我在prolog中编程一个家庭,我在使用nephew实现时遇到了麻烦.当我问埃里克是否是阿尔贝托的侄子时,它返回真实,因为它应该返回假,因为阿尔贝托是埃里克的父亲,然而,它确实适用于所有其他应该是真实的情况.如果有人能帮助我,我将非常感激.我的代码:
man(beto).
man(fransisco).
man(alberto).
man(jaime).
man(manolo).
man(nolo).
man(lito).
man(manuel).
man(erick).
man(jesu).
man(jesus).
woman(emi).
woman(harumi).
woman(haru).
woman(yuneisi).
woman(yasmeli).
woman(mioara).
woman(elia).
woman(iza).
woman(alice).
woman(ofelia).
woman(arlet).
parent(manuel, alberto).
parent(ofelia, alberto).
parent(manuel, jaime).
parent(ofelia, jaime).
parent(manuel, manolo).
parent(ofelia, manolo).
parent(alberto, erick).
parent(alberto, beto).
parent(alberto, fransisco).
parent(emi, erick).
parent(emi, beto).
parent(manolo, nolo).
parent(manolo, arlet).
parent(nolo, lito).
parent(iza, lito).
parent(mioara, yuneisi).
parent(mioara, yasmeli).
parent(jaime, yuneisi).
parent(jaime, yasmeli).
parent(jesus_padre, jesu)
parent(jesus_padre, alice).
parent(jesus_padre, haru).
parent(harumi, haru).
parent(harumi, jesu).
parent(harumi, alice).
father(X,Y) :- parent(X,Y), man(X).
mother(X,Y) :- parent(X,Y), woman(X).
brother(X,Y) :- man(X), parent(F, X), parent(F, Y).
sister(X,Y) :- woman(X), parent(P, X), parent(P, Y).
grandpa(X,Y) :- father(F,Y), father(X,F), man(X).
grandma(X,Y) :- father(F,Y), mother(X,F), woman(X).
son(X,Y) :- father(Y,X), man(X).
nephew(X,Y) :- father(F,X), brother(F,Y).
Run Code Online (Sandbox Code Playgroud)
除了parent(jesus_padre, jesu)@LuaiGhunim所指出的缺失点之外,你的谓词还有一些其他问题.你对兄弟/ 2的定义过于笼统.没有人是他自己的兄弟,但如果你查询你的谓词,你会发现几个这样的例子:
?- brother(X,X).
X = beto ;
X = beto ;
X = fransisco ;
X = alberto ;
X = alberto ;
X = jaime ;
X = jaime ;
X = manolo ;
X = manolo ;
X = nolo ;
X = lito ;
X = lito ;
X = erick ;
X = erick ;
X = jesu ;
X = jesu ;
false.
Run Code Online (Sandbox Code Playgroud)
您可以通过添加目标dif/2来轻松解决此问题:
brother(X,Y) :-
dif(X,Y),
man(X),
parent(F, X),
parent(F, Y).
Run Code Online (Sandbox Code Playgroud)
现在上面的查询失败了,因为它应该:
?- brother(X,X).
false.
Run Code Online (Sandbox Code Playgroud)
你还会得到很多对两次:
?- brother(X,Y).
X = beto, % <- 1st occurrence
Y = erick ; % <- 1st occurrence
X = beto,
Y = fransisco ;
X = beto, % <- 2nd occurrence
Y = erick ; % <- 2nd occurrence
.
.
.
Run Code Online (Sandbox Code Playgroud)
原因是你可以通过母亲或父亲来获得它.在上面的示例(beto和erick)中,您将通过emi或来到那里alberto.这些解决方案可能是多余的,但它们是正确的 您的谓词妹妹/ 2也是如此:
?- sister(X,X).
X = haru ;
X = haru ;
X = yuneisi ;
X = yuneisi ;
X = yasmeli ;
X = yasmeli ;
X = alice ;
X = alice ;
X = arlet.
Run Code Online (Sandbox Code Playgroud)
补救措施与上述相同:
sister(X,Y) :-
dif(X,Y),
woman(X),
parent(P, X),
parent(P, Y).
?- sister(X,X).
false.
?- sister(X,Y).
X = haru,
Y = jesu ;
X = haru,
Y = alice ;
X = haru,
Y = jesu ;
.
.
.
Run Code Online (Sandbox Code Playgroud)
另一方面,您对grandma/2和grandpa/2的定义过于具体.要查看此内容,请在代码中添加以下事实:
man(m1).
man(m2).
woman(w1).
woman(w2).
woman(w3).
parent(m1,w1).
parent(w1,w2).
parent(w2,w3).
Run Code Online (Sandbox Code Playgroud)
然后,以下查询应该成功,但它们会失败:
?- grandpa(m1,w2).
false.
?- grandma(w1,w3).
false.
Run Code Online (Sandbox Code Playgroud)
原因是爷爷/ 2和祖母/ 2的定义中的中间父亲是父/ 2,它应该是父/ 2.此外,最后的目标(man(X)和woman(X))是多余的,因为它们已分别由父/ 2和母/ 2覆盖.相反,您可以像这样定义两个谓词:
grandpa(X,Y) :-
parent(F,Y),
father(X,F).
grandma(X,Y) :-
parent(F,Y),
mother(X,F).
Run Code Online (Sandbox Code Playgroud)
现在上面的查询产生了所需的结果:
?- grandpa(m1,w2).
true.
?- grandma(w1,w3).
true.
Run Code Online (Sandbox Code Playgroud)
最后,根据剑桥词典的侄子是你的姐妹或兄弟的儿子,或你的丈夫或妻子的姐妹或兄弟的儿子.既然你没有丈夫和妻子的谓词,我会坚持你的姐姐或兄弟的一个儿子.如果您为丈夫和妻子添加事实,您可以添加其他规则以涵盖定义的其他部分.您可以在Prolog中编写定义的第一部分,如下所示:
nephew(X,Y) :-
man(X),
dif(F,Y),
parent(P,F),
parent(P,Y),
parent(F,X).
Run Code Online (Sandbox Code Playgroud)
如果您查询此谓词,则不再有erick/alberto解决方案:
?- nephew(erick,X).
X = jaime ;
X = manolo ;
X = jaime ;
X = manolo ;
false.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
460 次 |
| 最近记录: |