Пролог работает, оценивая запросы до тех пор, пока не произойдет сбой по отрицанию.
Здесь вы установили два факта:
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
.
Я рад, что вы задали этот вопрос, потому что он позволил мне немного освежиться в прологе, который мне действительно нравится, но долгое время не использовал.