Понимание правил - ложь как ответ
-
14-11-2019 - |
Вопрос
Я новичок в Prolog, и я просто подумал, почему это правило дает мне ложный результат после одного истинного.
likes(1,banana).
likes(1,mango).
test :- likes(1,banana),likes(1,mango).
?- test.
true;
false.
Я хочу знать причину, стоящую за этой ложью.
Решение
Способ работы prolog заключается в оценке запросов до тех пор, пока не произойдет сбой из-за отрицания.
Здесь вы установили два факта:
likes(1, banana).
где написано "1 любит бананы".
likes(1, mango).
где написано "1 любит манго".
Затем вы установили правило, которое в основном оценивается как:
left_hand_side :- right_hand_side.
left_hand_side
если right_hand_side
Оценка правила при выполнении запроса пытается сопоставить факты и возвращает true
если это возможно, и false, если это не может совпадать.Важно отметить, что, если указано, prolog будет продолжать сопоставлять факты до тех пор, пока правила оцениваются как true
.
Так что давайте пройдем через это test :- likes(1,banana),likes(1,mango).
Если test
запускается как запрос, prolog сначала пытается likes(1,banana)
что является ранее установленным фактом и является правдой.Затем он переходит к likes(1,mango)
что, опять же, является фактом и является правдой.Затем Prolog достигает конца правила и выводит true
.
На этом этапе, если вы не ищете больше совпадений, вы можете сократить запрос и просто указать true .Однако, если вы ищете больше (всех) совпадений, пролог обратные пути и пытается снова оценить правило, ища дополнительные совпадения.
Однако, поскольку ваше правило соответствует только "любит банан и любит манго", а мы уже сопоставили likes(1,banana)
, когда prolog возвращается назад и пытается оценить likes(1,banana)
опять же, поскольку мы уже сопоставляли его раньше, на этот раз нет другого факта (другими словами, 1 не может "лайкать" banana более одного раза, если это не было определено), которому нужно соответствовать.Так вот где находится false
происходит от.
В вашем интерпретаторе prolog вы можете отследить выполнение вашей программы, набрав 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
.
Я рад, что вы задали этот вопрос, потому что это позволило мне немного обновить prolog, который мне действительно нравится, но которым я давно не пользовался.