Что означает, когда gprolog говорит правду? вместо да в этом случае?

Я пытаюсь написать программу gprolog, которая подтверждает это, учитывая некоторый "разумный" фон из эту песню (слушайте здесь :-) ), ответит утвердительно, когда я запрошу grandpa(me, me) (т. е. действительно ли я сам себе дедушка?). Это было задание для моего класса ИИ, и нам оставалось решать, какие факты и предикаты включать. Хотя он полон избыточности и некоторых пунктов, которые я не использую (некоторые просто ради песни), вот то, что я собрал вместе, с необходимым предположением, что пасынки считаются полными / обычными детьми:

  3 male(me).
  4 male(mydad).
  5 male(mybaby).
  6 female(widow).
  7 female(redhead).
  8 grandma(Z, X) :- female(Z), child(Z, Y), child(Y, X).           
  9 grandpa(Z, X) :- male(Z), child(Z, Y), child(Y, X).         
 10 child(me, mydad). 
 11 child(redhead, widow). 
 12 child(mybaby, me).
 13 child(A, B) :- married(B, C), married(A, D), child(D, C).  
 14 child(C, A) :- married(A, B), child(C, B). %step children as children
 15 married(me, widow). 
 16 married(widow, me). 
 17 married(mydad, redhead).

Это небрежно, но я бы сказал, что наиболее важными являются пункты 13 и 14. В частности, 14 попыток сделать так, чтобы, например, мой отец был моим ребенком, поскольку он женился на моем пасынке и, таким образом, является моим зятем.

В любом случае, трассировка показывает, что выполнение запроса, похоже, работает - вроде:

{trace}
| ?- grandpa(me, me).
      1    1  Call: grandpa(me,me) ? 
      2    2  Call: male(me) ? 
      2    2  Exit: male(me) ? 
      3    2  Call: child(me,_366) ? 
      3    2  Exit: child(me,mydad) ? 
      4    2  Call: child(mydad,me) ? 
      5    3  Call: married(me,_415) ? 
      5    3  Exit: married(me,widow) ? 
      6    3  Call: married(mydad,_440) ? 
      6    3  Exit: married(mydad,redhead) ? 
      7    3  Call: child(redhead,widow) ? 
      7    3  Exit: child(redhead,widow) ? 
      4    2  Exit: child(mydad,me) ? 
      1    1  Exit: grandpa(me,me) ? 

true ? 

(2 ms) yes

Меня беспокоит заявление true?. Если я просто нажму Enter, появится yes, но если произнести что-то вроде a, это приведет к бесконечному циклу, при котором стек вызовов будет становиться все больше и больше с каждым раундом, прежде чем снова появится «true». Что здесь происходит? Я думал, что успешное «подтверждение» запроса будет означать конец всему. Я больше не вижу переменных для проверки!


person norman    schedule 01.07.2013    source источник


Ответы (1)


true vs yes используются, чтобы отличить, где может быть больше решений. Prolog может проверять стек доказательств в поисках точек выбора, то есть там, где ожидаются альтернативные вычисления, которые еще предстоит опровергнуть.

Нажимая a, вы подчеркиваете основной цикл, который приводит к парадоксу:

...
   Redo: (31) child(redhead, me)
   Call: (32) married(me, _G2289)
   Exit: (32) married(me, widow)
   Call: (32) child(redhead, widow)
   Exit: (32) child(redhead, widow)
   Exit: (31) child(redhead, me)
   Exit: (30) child(redhead, widow)
   Exit: (29) child(redhead, me)
   Exit: (28) child(redhead, widow)
...

(примечание: трассировка получена с помощью SWI-Prolog, не обращайте внимания на небольшие отличия)

person CapelliC    schedule 02.07.2013
comment
Я не уверен, что понимаю, что вы говорите. - person norman; 02.07.2013