Понимание правил - ложь как ответ - PullRequest
4 голосов
/ 16 февраля 2011

Я новичок в Прологе, и я просто подумала, почему это правило дает мне ложный результат после одной истины.1009 *

?- test.  
true;  
false.

Я хочу знать причину этого ложного.

1 Ответ

7 голосов
/ 16 февраля 2011

Пролог работает, оценивая запросы до тех пор, пока не произойдет сбой по отрицанию.

Здесь вы установили два факта:

likes(1, banana)., который говорит: «1 любит банан»

likes(1, mango)., который говорит "1 любит манго"

Затем вы установили правило, которое в основном оценивается как:

left_hand_side :- right_hand_side. left_hand_side если right_hand_side

Оценка правила в виде запроса пытается сопоставить факты и возвращает true, если может, и false, если не может сопоставиться.Важно отметить, что, если указано, пролог будет продолжать соответствовать фактам до тех пор, пока правила оценят true.

Так что давайте пройдемся по test :- likes(1,banana),likes(1,mango).

Если testзапускается как запрос, пролог сначала пытается likes(1,banana), что является ранее установленным фактом, и это правда.Затем он переходит к likes(1,mango), что, опять же, является фактом, и это правда.Затем Prolog достиг конца правила и выдает true.

. На этом этапе, если вы не ищете больше совпадений, вы можете сократить запрос и просто получить значение true.Однако, если вы ищете больше (все) совпадений, пролог возвращает назад и пытается снова оценить правило, ища больше совпадений.

Однако, поскольку ваше правило соответствует только "любит банан и любит манго ", и мы уже сопоставили likes(1,banana), когда пролог возвращается и пытается оценить likes(1,banana) снова, поскольку мы уже сопоставили его раньше, на этот раз нет другого факта (другими словами, я не могу" любить "бананболее одного раза, если это не было определено) для соответствия.Так вот откуда взято false.

В вашем интерпретаторе пролога вы можете отследить выполнение вашей программы, набрав trace. и выполнив запрос.Мой след приведен ниже:

| ?- trace
.
The debugger will first creep -- showing everything (trace)

(1 ms) yes
{trace}
| ?- test.
      1    1  Call: test ? 
      2    2  Call: likes(1,banana) ? 
      2    2  Exit: likes(1,banana) ? 
      3    2  Call: likes(1,mango) ? 
      3    2  Exit: likes(1,mango) ? 
      1    1  Exit: test ? 

true ? ;
      1    1  Redo: test ? 
      2    2  Redo: likes(1,banana) ? 
      2    2  Fail: likes(1,banana) ? 
      1    1  Fail: test ? 

(1 ms) no
{trace}
| ?-

Еще одна вещь, на которую следует обратить внимание: если бы вместо нажатия ; в приглашении true ?, если бы я нажал <ENTER>, сценарий завершился бы толькоtrue.

Я рад, что вы задали этот вопрос, потому что он позволил мне немного освежиться в прологе, который мне действительно нравится, но долгое время не использовал.

...