2017-10-11 64 views
2
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). 

我不知道我的代碼中發生了什麼。當我輸入在Prolog中無法顯示第二個答案

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 . 
+0

這是這裏的問題。當我按「;」我得到一個答案「假」。我嘗試另一個簡單的陳述來測試我是否可以使用「;」得到另一個答案,我成功了。但在這種情況下,我不能... –

+2

嘗試用'dif(X,Y)'代替'X \ = Y'。 'dif(X,Y)'是說'X'和'Y'是不同的關係方式。 – lurker

回答

1

問題

之所以出現這種情況是因爲

X \= Y, 

實際上意味着:

\+(X = Y). 

現在\+或在序言not有一些怪異的行爲相比,邏輯不。 \+意味着否定爲有限失敗。這意味着在Prolog查詢G的情況下,\+(G)被認爲是true,並且無法找到滿足G的方式,並且G是有限的(最終尋求滿足G兩端)。

現在,如果我們查詢\+(X = Y),Prolog將因此旨在統一XY。如果XY是(未接地)變量,則X可以等於Y。結果X \= YXY是自由變量的情況下失敗。因此,基本上我們可以使用另一個謂詞,例如對變量接地時觸發的兩個變量施加約束,或者我們可以對子句的主體進行重新排序,使得XY已經在我們呼籲X \= Y

如果我們能讓例如假設XY將調用birth/2後接地,我們可以重新排序子句:

cousins(X,Y) :- 
    birth(Xmom,X), 
    birth(Ymom,Y), 
    X \= Y, 
    marriage(Xmom,Xdad,_), 
    marriage(Ymom,Ydad,_), 
    brothers(Xdad,Ydad).

Prolog有但是謂詞dif/2是把一個約束的兩個變量,並且從兩者接地的那一刻開始,如果兩者相等,它將失敗。因此,我們可以這樣使用它:

cousins(X,Y) :- 
    dif(X,Y), 
    birth(Xmom,X), 
    birth(Ymom,Y), 
    marriage(Xmom,Xdad,_), 
    marriage(Ymom,Ydad,_), 
    brothers(Xdad,Ydad).

使事情變得更簡單

話雖這麼說,我覺得你做的程序太複雜。我們可以用一些定義開始:

兩個人都slibings/2如果他們brothers/2sisters/2

slibings(X,Y) :- 
    brothers(X,Y). 
slibings(X,Y) :- 
    sisters(X,Y). 

然而可能brothers/2sisters/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).

而現在我們可以這樣定義:

兩個人是堂兄弟,如果有父母slibings:

cousins(X,Y) :- 
    parent(MF1,X), 
    parent(MF2,Y), 
    slibings(MF1,MF2). 

,就是這樣。

+1

......太神奇了。我從來沒有想過添加幫手定義來解決表弟問題。你的回答讓我想起! –

相關問題