prolog中的意外结果

prolog中的意外结果,prolog,Prolog,为什么我得到了这么多真实的结果而不是一个?以下是我如何定义我的规则: parent(X,Y):- or(father(X,Y), mother(X,Y)). sister(X,Y):- female(X), parent(P, X), parent(P,Y). aunt(X,Y):- female(X), sister(X,P), parent(P,Y). ?- aunt(molly, johnny). true ; true ; true ; true ; true ;

为什么我得到了这么多真实的结果而不是一个?以下是我如何定义我的规则:

parent(X,Y):- or(father(X,Y), mother(X,Y)).   
sister(X,Y):- female(X), parent(P, X), parent(P,Y).      
aunt(X,Y):- female(X), sister(X,P), parent(P,Y).


?- aunt(molly, johnny).
true ;
true ;
true ;
true ;
true ;
true ;
true ;
true ;
true ;
true.

正如@Steven在他的评论中提到的,结果取决于你拥有的谓词,尤其是原子谓词。例如,以下代码将产生两个“true”结果,因为
父(X,Y):-father(X,Y);母亲(X,Y)。
将匹配molly和alex的父谓词和母谓词

father(dan,molly).
father(dan,alex).
father(alex,johnny).

mother(jess,molly).
mother(jess,alex).

female(molly).

parent(X,Y):- father(X,Y) ; mother(X,Y).

sister(X,Y):- female(X), parent(P, X), parent(P,Y), X \= Y.

aunt(X,Y):- sister(X,P), parent(P,Y).

?- aunt(molly, johnny).
true ;
true .
如果需要获得单个匹配(例如单个
true
结果),可以使用cut
阿姨谓词末尾的谓词,例如
阿姨(X,Y):-女性(X),姐妹(X,P),父母(P,Y)

在这种情况下,代码如下所示:

father(dan,molly).
father(dan,alex).
father(alex,johnny).

mother(jess,molly).
mother(jess,alex).

female(molly).

parent(X,Y):- father(X,Y) ; mother(X,Y).

sister(X,Y):- female(X), parent(P, X), parent(P,Y), X \= Y.

aunt(X,Y):- sister(X,P), parent(P,Y),!.

?- aunt(molly, johnny).
true .

如果看不到所涉及的谓词的定义,我们是无法判断的。我猜,
sister
和/或
parent
对给定的输入多次成功。@Steven我添加了parent()和sister()的规则,您可以在找到第一个解决方案时使用剪切,它不会再回溯了。你应该在你的代码中加一个切口,而不是在查询中,但试着写一个类似这样的查询,看看它会一次性返回
阿姨(molly,johnny)@LuaiGhunim一个切口并不是解决这个问题的正确方法。CUTE经常被用作一个创可贴,许多Prolog初学者用来修复定义不好的规则。@ H有没有解决办法?你需要添加一些条件来避免它,或者你可以使用<代码> SET/3 或类似的东西。不要像其他人时不时建议的那样在代码上撒下削减。围绕目标包装
setof(t,Goal\u 0,)
<代码>姐姐(莫莉,莫莉)
成功<代码>莫莉
不是她的亲妹妹。而且
sister/2
已经检查了第一个参数是否为女性,因此
female(X)
调用
aunt(X,Y)
是多余的
阿姨(莫莉,约翰尼)
成功两次,因为
姐妹/2
可以成功两次,因为姐妹俩有双亲。@好斗的蒙大拿,如果你想要一个简单快速的解决方案,你可以使用切割谓词
,正如这里的人建议的那样。然而,这可能不是最佳做法。我已经更新了答案,向您展示了如何使用切割谓词,我还删除了多余的
female(X)
调用,并按照@louger的建议修复了
姐妹(molly,molly)