为什么此祖先代码不起作用-Prolog

时间:2019-02-26 01:25:09

标签: prolog

parent(jill, john).  
parent(john, pam).  
parent(pam, bob).  
parent(tom, bob).  
parent(tom, liz).  
parent(bob, ann).  
parent(bob, pat).  
parent(pat, jim).  

female(jill).      
female(pam).  
female(liz).  
female(ann).  
female(pat).  
male(jim).  
male(john).  
male(tom).  
male(bob).  

mother(X,Y) :- female(X) , parent(X,Y).  
father(X,Y) :- male(X), parent(X,Y).  
offspring(X,Y) :-  parent(Y,X).  
sister(X,Y) :- female(X), female(Y), parent(Z,X), parent(Z,Y), not(X=Y).  
ancestor(X, Y) :- parent(X,Z), ancestor(Z,Y).   

这是整个代码以及与祖先部分无关的其他内容。当我尝试在swipl中对其进行测试时,祖先代码给我错误的提示。我正在尝试祖先(pat,jim)。和ancestor(X,jim)。如果我在祖先代码中使用;而不是,,则可以工作,但是当一个人的父母双方都在列表中时,名字会重复。

1 个答案:

答案 0 :(得分:0)

在这种情况下,trace是您的朋友:

?- trace.
true.

[trace]  ?- ancestor(pat, jim).
   Call: (8) ancestor(pat, jim) ? creep
   Call: (9) parent(pat, _3162) ? creep
   Exit: (9) parent(pat, jim) ? creep
   Call: (9) ancestor(jim, jim) ? creep
   Call: (10) parent(jim, _3162) ? creep
   Fail: (10) parent(jim, _3162) ? creep
   Fail: (9) ancestor(jim, jim) ? creep
   Fail: (8) ancestor(pat, jim) ? creep
false.

看看会发生什么?您将ancestor(X,Y)定义为有两个要求:首先,X必须是某个中间人Z的父级,然后Z也必须是{{1}的祖先}。由于Ypat的父母,因此要求jim是他自己的祖先,而他不是。

一种可能的解决方案是将祖先定义为 的直接父系另一个祖先的父系:

jim

让我们测试一下

ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).

因此,我们对[trace] ?- ancestor(pat, jim). Call: (8) ancestor(pat, jim) ? creep Call: (9) parent(pat, jim) ? creep Exit: (9) parent(pat, jim) ? creep Exit: (8) ancestor(pat, jim) ? creep pat很满意,因为它们是直接的jim关系。递归情况如何?

parent