Вопрос

Я новичок в 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, который мне действительно нравится, но которым я давно не пользовался.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top