Понимание правил - ложь как ответ

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

likes(1,banana).
likes(1,mango).

test :- likes(1,banana),likes(1,mango).

?- test.  
true;  
false.

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


person anilonwebs    schedule 16.02.2011    source источник


Ответы (1)


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

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

likes(1, banana)., в котором написано: "1 нравится банан"

likes(1, mango)., в котором написано: "Мне нравится манго"

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

left_hand_side :- right_hand_side. left_hand_side если right_hand_side

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

Итак, давайте перейдем к test :- likes(1,banana),likes(1,mango).

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

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

Однако, поскольку ваше правило соответствует только «любит банан и любит манго», и мы уже сопоставили likes(1,banana), когда пролог откатывается и снова пытается оценить likes(1,banana), поскольку мы уже сопоставили его раньше, на этот раз другого факта нет (другими словами, 1 не может "лайкнуть" банан более одного раза, если это не было определено) для соответствия. Вот откуда взялся 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.

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

person aqua    schedule 16.02.2011
comment
спасибо за такое подробное описание. На самом деле раньше я не понимал концепцию обратного отслеживания, и я думал, что обратное отслеживание будет выполняться только тогда, когда мы пытаемся создать экземпляр переменной, такой как like(1,X)., но теперь я немного более ясно понимаю эту концепцию. Еще раз спасибо. - person anilonwebs; 16.02.2011
comment
@Anil Mundra: Отлично! Рад помочь. - person aqua; 17.02.2011