我对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'], []))
])
]).
答案 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).