i'm pretty new to Prolog and i have some troubles with POST. This is my Prolog form:
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'], []))
])
and this is my handler:
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).
When I hit submit button, I get
Internal server error goal unexpectedly failed
Can someone please help me with how to make this handler work properly? Now I only need to proceed data from form to whiteTurn
function, I will deal with other exceptions later.
Here is executable example, with same error:
:- 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'], []))
])
]).
To locate the precise cause of failure in Prolog programs, use the powerful technique of declarative debugging.
To do this, add the following definition to your program:
Now, using
(*)/1
lets you generalize away goals in a very convenient way, by simply using*
in front. This amounts to commenting the goal out, but is more convenient because it also works for the last goal of a clause, without having to change,
to.
in the preceding goal.So, in your case, a quick look confirms that the failure occurs in
answer/2
. Logically, failure means that your program is too specific. Thus, you can generalize it for example like this:I am using
strikethroughfont to indicate that the goal can be simply discarded when reading this snippet.If you try it now with the thus modified program, it succeeds!
Obviously, though, the program is now much too general.
So, you can again make it more specific by systematically re-introducing the goals you have generalized away.
Here is a first shot:
Here, I have (arbitrarily) re-introduced the first goal.
Now, the whole query again fails!
Thus, we have found a definite cause of this failure: To make the whole query succeed, we must either introduce additional clauses, or generalize this particular goal.
In other words, this all means: A term of the form
search(S)
does not occur inRequest
in this case!I leave correcting this as an exercise.
If you are ever unsure what the actual
Request
contains, you can use this definition instead to emit the request: