2017-01-06 10 views
0

私はかなりプロローグに新しいです。私はPOSTにいくつかの問題があります。 は、これは私のプロローグ形式です:Prolog POSTハンドラー

  `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'], [])) 
     ]) 
     ]). 
+4

は**私たちが試みることができるという例でる! – mat

+0

これは何が起こっているかをより良く理解するのに役立ちます。http://www.swi-prolog.org/howto/http/Developing.html –

+0

@mat私のコードの実行可能なエラーを同じエラーで追加しました –

答えて

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). 

、私は(任意)再導入最初の目標があります。

今すぐクエリ全体がになります。

したがって、我々は、この障害の明確な原因を発見した:全体のクエリが成功させるために、我々は、追加条項を導入しなければならないのいずれか、またはこの特定の目標一般化します。言い換えれば

、このすべての手段:フォームsearch(S)の用語は 、この場合にはRequestを発生しません!

私はこれを練習問題として修正します。

あなたは、実際のRequestに何が含まれているか不明な場合は、あなたが 要求放出する代わりに、この定義を使用することができます最小限と**完全にこれを変更してください

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

アドバイスありがとうございますが、私の主な問題は私のポストフォームから変数を取ってwhiteTurnステートメントに入れる方法がわからないということです。今私は彼らが依頼でさえないことを知っているが、理由を知らない。私はインターネット上で解決策を探していたが、見つからなかった。それを行う方法を単純な解決策はどこにもありません。 –

+0

POSTの代わりにGETメソッドを使用しなければならなかったので、データを他のページに渡すことができました。おかげで、あなたのコードは私の間違いを見つけるのに役立ちました:-) –

+0

'POST'メソッドを使うのは大丈夫です。ただし、リクエストを別々に処理する必要があります。[documentation](http://eu.swi-prolog.org/pldoc/man?section=http-read-post)を参照してください。 'POST'リクエストを処理するには、' Var = Value'のリストを取得するためにhttp_read_data(Request、Data、[]) 'を使用するだけで': - use_module(library(http/http_client) 「データ」のペアになります。ディスパッチを簡単にするために['http_handler/3'](http://eu.swi-prolog.org/pldoc/doc_for?object=http_handler/3)も参照してください。また、 '[a、b | []]'は '[a、b]'と同じです。 – mat

関連する問題