2017-01-06 5 views
0

Я довольно новичок в прологе, и у меня есть проблемы с POST. Это мой пролог форма:Prolog POST handler

  `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

Чтобы найти точную причину отказа в программах на Прологе, использовать мощную технику декларативного   отладки.

Чтобы сделать это, добавьте следующее определение к вашей программе:

 
:- 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

Я понял, мне пришлось использовать метод GET вместо POST, после чего я мог передавать свои данные на другую страницу. Спасибо за помощь, ваш код был полезен для обнаружения моей ошибки :-) –

+0

Вполне нормально использовать метод «POST», а в некоторых случаях это даже необходимо или лучше. Однако вам нужно обрабатывать запрос по-разному, см. [Документация] (http://eu.swi-prolog.org/pldoc/man?section=http-read-post). Чтобы обработать запрос 'POST', вам нужно только добавить': - use_module (library (http/http_client)). 'И использовать 'http_read_data (Request, Data, [])' для получения списка 'Var = Value' пары в «Данные». См. Также ['http_handler/3'] (http://eu.swi-prolog.org/pldoc/doc_for?object=http_handler/3), чтобы упростить отправку. Кроме того, '[a, b | []]' совпадает с '[a, b]'. – mat