Prolog POST处理程序

时间:2017-01-06 10:50:01

标签: prolog swi-prolog

我对Prolog很新,我在POST方面遇到了一些麻烦。 这是我的Prolog表格:

form([action='/game', method='POST'], [
              p([], [
                label([for=fromX],'From X'),
                input([name=fromX, type=textarea])
              ]),
              p([], [
                label([for=fromY],'From Y'),
                input([name=fromY, type=textarea])
              ]),
              p([], [
                label([for=toX],'To X'),
                input([name=toX, type=textarea])
              ]),
              p([], [
                label([for=toY],'To Y'),
                input([name=toY, type=textarea])
              ]),
              p([], input([name=submit, type=submit, value='Submit'], []))
            ])

这是我的经纪人:

answer('/game', Request) :-
 memberchk(search(Search), Request),
 memberchk(toX=ToX, Search),
 memberchk(toY=ToY, Search),
 memberchk(fromX=FromX, Search),
 memberchk(fromYy=FromY, Search),
 whiteTurn(ToX/ToY, FromX/FromY, White_N),
 game_page(White_N).

当我按下提交按钮时,我

  

内部服务器错误目标意外失败

有人可以帮我解决一下如何让这个处理程序正常工作吗?现在我只需要从表单到whiteTurn函数继续处理数据,稍后我会处理其他异常。

以下是可执行示例,错误相同:

:- use_module(library('http/thread_httpd')).
:- use_module(library('http/html_write')).
:- use_module(library('http/http_session')).
:- use_module(library('http/http_error')).

server :-
  server(3000).

server(Port) :-
  http_server(answer,
        [ port(Port),
          timeout(20)
        | []
        ]).

 answer(Request) :-
  memberchk(path(Path), Request),
  answer(Path, Request).

 answer(/, _Request) :-
   title_page.

 answer('/game', Request) :-
  memberchk(search(Search), Request),
  memberchk(toX=ToX, Search),
  memberchk(toY=ToY, Search),
  memberchk(fromX=FromX, Search),
  memberchk(fromYy=FromY, Search),
  whiteTurn(ToX/ToY, FromX/FromY, White_N),
  game_page(White_N).

  title_page:-
   reply_html_page(
        title('Draughts'),
        [
         h1('Draughts'),
   form([action='/game', method='POST'], [
          p([], [
            label([for=fromX],'From X'),
            input([name=fromX, type=textarea])
          ]),
          p([], [
            label([for=fromY],'From Y'),
            input([name=fromY, type=textarea])
          ]),
          p([], [
            label([for=toX],'To X'),
            input([name=toX, type=textarea])
          ]),
          p([], [
            label([for=toY],'To Y'),
            input([name=toY, type=textarea])
          ]),
          p([], input([name=submit, type=submit, value='Submit'], []))
        ])
    ]).

 whiteTurn(X/Y, A/B, WHITE_N):-
  WHITE = [ 2/1,4/1,6/1,8/1,
    1/2,3/2,5/2,7/2,
    2/3,4/3,6/3,8/3],
  M = [ 1/1,2/1,3/1,4/1,5/1,6/1,7/1,8/1,
    1/2,2/2,3/2,4/2,5/2,6/2,7/2,8/2,
    1/3,2/3,3/3,4/3,5/3,6/3,7/3,8/3,
    1/2,2/2,3/2,4/2,5/2,6/2,7/2,8/2,
    1/4,2/4,3/4,4/4,5/4,6/4,7/4,8/4,
    1/5,2/5,3/5,4/5,5/5,6/5,7/5,8/5,
    1/6,2/6,3/6,4/6,5/6,6/6,7/6,8/6,
    1/7,2/7,3/7,4/7,5/7,6/7,7/7,8/7,
    1/8,2/8,3/8,4/8,5/8,6/8,7/8,8/8 ],
    (   member(X/Y, M), (X =:= A + 1; X =:= A - 1), Y =:= B - 1, 
    member(A/B, WHITE) ->  
    delete(WHITE, X/Y, WHITE_M), WHITE_N is [A/B|WHITE_M]; 
    WHITE_N = WHITE ).

    game_page(White_N):-
     reply_html_page(
        title('Draughts'),
        [
         h1('Draughts'),
     form([action='/game', method='POST'], [
          p([], [
            label([for=fromX],'From X'),
            input([name=fromX, type=textarea])
          ]),
          p([], [
            label([for=fromY],'From Y'),
            input([name=fromY, type=textarea])
          ]),
          p([], [
            label([for=toX],'To X'),
            input([name=toX, type=textarea])
          ]),
          p([], [
            label([for=toY],'To Y'),
            input([name=toY, type=textarea])
          ]),
          p([], input([name=submit, type=submit, value='Submit'], []))
        ])
      ]).

1 个答案:

答案 0 :(得分:1)

要在Prolog程序中找到失败的确切原因,请使用声明性调试的强大技术。

为此,请将以下定义添加到您的程序中:

:- op(920,fy, *).

*_.

现在,使用(*)/1可让您以非常方便的方式概括目标,只需在前面使用*即可。这相当于对目标进行评论,但更方便,因为它也适用于子句的最后一个目标,而无需在前一个目标中将,更改为.

因此,在您的情况下,快速查看确认失败发生在answer/2。从逻辑上讲,失败意味着您的程序太具体。因此,您可以概括,例如:


answer('/game', Request) :-
  * memberchk(search(Search), Request),
  * memberchk(toX=ToX, Search),
  * memberchk(toY=ToY, Search),
  * memberchk(fromX=FromX, Search),
  * memberchk(fromYy=FromY, Search),
  * whiteTurn(ToX/ToY, FromX/FromY, White_N),
  game_page(White_N).

我正在使用删除线字体来表示在阅读此片段时,目标可以简单地丢弃

如果你现在尝试使用这样修改过的程序,成功

显然,该计划现在非常过于笼统

所以,你可以通过系统地重新介绍你已经推广的目标,再次使它更具体。

这是第一次拍摄:

answer('/game', Request) :-
  memberchk(search(Search), Request),
  * memberchk(toX=ToX, Search),
  * memberchk(toY=ToY, Search),
  * memberchk(fromX=FromX, Search),
  * memberchk(fromYy=FromY, Search),
  * whiteTurn(ToX/ToY, FromX/FromY, White_N),
  game_page(White_N).

在这里,我(任意)重新引入了第一个目标。

现在,整个查询再次失败

因此,我们发现了这个失败的明确原因:要使整个查询成功,我们必须引入其他子句,或者概括这个特定目标。 / p>

换句话说,这一切都意味着:在这种情况下,search(S)中的Request 形式的术语不会出现

我将此作为练习进行纠正。

如果您不确定实际的Request包含什么,则可以使用此定义来发出请求:

answer('/game', Request) :-
        format("Content-type: text/plain~n~n"),
        maplist(portray_clause, Request).