无法在Prolog中显示第二个答案

时间:2017-10-11 17:51:09

标签: prolog prolog-dif

sisters(mary,catherine).
sisters(catherine,mary).
brothers(john,simone).
brothers(simone,john).
marriage(john,mary,2010).
marriage(mary,john,2010).
marriage(kate,simone,2009).
marriage(simone,kate,2009).
marriage(catherine,josh,2011).
marriage(josh,catherine,2011).
birth(mary,johnny).
birth(mary,peter).
birth(catherine,william).
birth(kate,betty).
givebirthyear(mary,peter,2015).
givebirthyear(mary,johnny,2012).
givebirthyear(catherine,william,2012).
givebirthyear(kate,betty,2011).
siblings(X,Y) :-
    birth(Parent,X),
    birth(Parent,Y).
cousins(X,Y) :-
    birth(Xparent,X),
    birth(Yparent,Y),
    sisters(Xparent,Yparent).
cousins(X,Y) :-
    X \= Y,
    birth(Xmom,X),
    birth(Ymom,Y),
    marriage(Xmom,Xdad,_),
    marriage(Ymom,Ydad,_),
    brothers(Xdad,Ydad).

我不知道我的代码中发生了什么。当我输入

cousins(betty,johnny).

cousins(william,johnny).

序言说的是真的。但是当我进入

cousins(S,johnny).

序言说S = william但没有告诉我S = betty。我真的不知道发生了什么。需要帮助。

这是我得到的序言结果。

?- cousins(S,johnny).
S = william ;
false.

?- cousins(betty,johnny).
true.

?- cousins(william,johnny).
true .

1 个答案:

答案 0 :(得分:1)

问题

发生这种情况的原因是因为

X \= Y,

实际上意味着:

\+(X = Y).

现在,Prolog中的\+not与逻辑not相比有一些奇怪的行为。 \+表示否定为有限失败。这意味着,如果Prolog查询\+(G)true被认为是G,并且找不到满足G的方法,G是有限的(最终要求满足G结束)。

现在,如果我们查询\+(X = Y),Prolog将旨在统一XY。如果XY是(未接地)变量,则X可以等于Y。因此,如果X \= YX是自由变量,则Y会失败。

所以基本上我们可以使用另一个谓词,例如对变量接地时触发的两个变量设置约束,或者我们可以重新排序子句的主体,例如X和{{在我们致电Y之前,1}}已经停飞。

如果我们可以假设X \= YX在调用Y后接地,我们可以将该条款重新排序为:

birth/2
然而,Prolog有一个谓词cousins(X,Y) :- birth(Xmom,X), birth(Ymom,Y), X \= Y, marriage(Xmom,Xdad,_), marriage(Ymom,Ydad,_), brothers(Xdad,Ydad).,它对这两个变量施加约束,从两者接地的那一刻开始,如果两者相等就会失败。所以我们可以像:

一样使用它
dif/2

简化事情

话虽如此,我认为你使程序过于复杂。我们可以从一些定义开始:

  

两个人cousins(X,Y) :- dif(X,Y), birth(Xmom,X), birth(Ymom,Y), marriage(Xmom,Xdad,_), marriage(Ymom,Ydad,_), brothers(Xdad,Ydad). slibings/2brothers/2。{/ p>

sisters/2

slibings(X,Y) :- brothers(X,Y). slibings(X,Y) :- sisters(X,Y). brothers/2可能无法提供所有信息。如果他们有同一个母亲,我们也会有两个人(我们会假设人们不在这里离婚,或者至少在他们再婚后不生孩子)。

sisters/2
  

一个人的slibings(X,Y) :- dif(X,Y), birth(Mother,X), birth(Mother,Y). 是该人或父亲的母亲(与母亲结婚的人)。

所以我们可以写:

parent/2

根据您的示例,parent(Mother,X) :- birth(Mother,X). parent(Father,X) :- birth(Mother,X), marriage(Father,Mother,_). 谓词是双向的:如果marriage/3,则还有一个事实marriage(X,Y,Z).

现在我们可以定义:

  如果有父母的话,两个人就是表兄弟:

marriage(Y,X,Z).

那就是它。