Prolog 家庭序言练习
我不熟悉prolog,不知道如何解决这个问题。我必须写一条规则。一直以来,在代码的底部,我都有我的兄弟姐妹的规则。该规则的问题在于它会返回兄弟姐妹两次。例如,如果我想得到朱莉娅的兄弟姐妹,我会得到“罗莎”两次。我想现在发生的是程序为每个家长(alex和lina)进行评估。那么,我怎样才能修正我的规则,让我只得到朱莉娅(或任何人)的兄弟姐妹一次呢Prolog 家庭序言练习,prolog,Prolog,我不熟悉prolog,不知道如何解决这个问题。我必须写一条规则。一直以来,在代码的底部,我都有我的兄弟姐妹的规则。该规则的问题在于它会返回兄弟姐妹两次。例如,如果我想得到朱莉娅的兄弟姐妹,我会得到“罗莎”两次。我想现在发生的是程序为每个家长(alex和lina)进行评估。那么,我怎样才能修正我的规则,让我只得到朱莉娅(或任何人)的兄弟姐妹一次呢 parent(alex,julia). parent(alex,rosa). parent(lina,julia). parent(lina,rosa)
parent(alex,julia).
parent(alex,rosa).
parent(lina,julia).
parent(lina,rosa).
parent(romeo,peter).
parent(julia,peter).
parent(rosa,silvia).
parent(oscar,ida).
parent(eva,ida).
parent(eva,bruno).
parent(peter,bruno).
parent(peter,georg).
parent(peter,irma).
parent(ruth,georg).
parent(ruth,irma).
parent(silvia,otto).
parent(silvia,pascal).
parent(irma,olga).
parent(irma,jean).
parent(otto,olga).
parent(otto,jean).
parent(jean,tina).
parent(marie,tina).
male(alex).
male(romeo).
male(oscar).
male(peter).
male(bruno).
male(georg).
male(otto).
male(pascal).
male(jean).
husband(alex,lina).
husband(romeo,julia).
husband(oscar,eva).
husband(peter,ruth).
husband(otto,irma).
husband(jean,marie).
% father(X,Y) :- X is the father of Y.
father(X,Y) :- parent(X,Y), male(X).
% grandfather(X,Y) :- X is the grandfather of Y.
grandfather(X,Y) :- father(X,P), parent(P,Y).
% brother(X,Y) :- X is the brother of Y.
brother(X,Y) :- parent(P,X), parent(P,Y), male(X), X \= Y.
% uncle(X,Y) :- X is the uncle of Y.
uncle(X,Y) :- brother(X,P), parent(P,Y).
% female(X) :- X is a female person.
female(X) :- \+ male(X).
% sister(X,Y) :- X is the sister of Y.
sister(X,Y) :- parent(P,X), parent(P,Y), female(X), X \= Y.
% has_son(X) :- the person X has a son.
has_son(X) :- parent(X,Y), male(Y).
% married(X,Y) :- X and Y are married to each other.
married(X,Y) :- husband(X,Y).
married(X,Y) :- husband(Y,X).
% brother_in_law(X,Y) :- X is the brother-in-law of Y.
brother_in_law(X,Y) :- brother(X,P), married(P,Y).
brother_in_law(X,Y) :- husband(X,W), sister(W,Y).
% ancestor(X,Y) :- X is an ancestor of Y.
ancestor(X,Y) :- parent(X,Y).
ancestor(X,Y) :- parent(X,P), ancestor(P,Y).
% relatives(X,Y) :- X and Y are relatives (related by blood to each other).
relatives(X,X).
relatives(X,Y) :- ancestor(X,Y).
relatives(X,Y) :- ancestor(Y,X).
relatives(X,Y) :- ancestor(A,X), ancestor(A,Y).
% ancestors(As,X) :- As is the set of all (known) ancestors of X.
ancestors(As,X) :- setof(A,ancestor(A,X),As).
% descendants(Ds,X) :- Ds is the set of all (known) descendants of X.
descendants(Ds,X) :-setof(D,ancestor(X,D),Ds).
% ancestor(X,Y,L) :- X is an ancestor of Y, and L is the list of names
% leading from X to Y.
ancestor(X,Y,[X,Y]) :- parent(X,Y).
ancestor(X,Y,[X|L]) :- parent(X,P), ancestor(P,Y,L).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Exercise 1
% Write a rule that determines if mother (M) is mother of (C) child.
% mother(M, C) :-
mother(M,C) :- female(M), parent(M,C).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Exercise 2
% Write a rule that infers the siblings of certain (X) person
% siblings. Ss is the siblings list.
% siblings(Ss, X) :-
sibling(X,Y) :- dif(X,Y),parent(Z,X),parent(Z,Y).
你的怀疑是正确的。谓词的问题是一个人(通常)有两个父母:一个母亲/2和一个父亲/2 这意味着如果
rosa
和julia
是(真实的)兄弟姐妹(那么他们共享相同的母亲/2
和父亲/2
)
如果我们跟踪。
我们可以看到,这一点源于复制:
?- trace.
true.
[trace] ?- sibling(rosa, julia).
Call: (8) sibling(rosa, julia) ? creep
Call: (9) dif:dif(rosa, julia) ? creep
Exit: (9) dif:dif(rosa, julia) ? creep
Call: (9) parent(_5278, rosa) ? creep
Exit: (9) parent(alex, rosa) ? creep
Call: (9) parent(alex, julia) ? creep
Exit: (9) parent(alex, julia) ? creep
Exit: (8) sibling(rosa, julia) ? creep
true ;
Redo: (9) parent(alex, julia) ? creep
Fail: (9) parent(alex, julia) ? creep
Redo: (9) parent(_5278, rosa) ? creep
Exit: (9) parent(lina, rosa) ? creep
Call: (9) parent(lina, julia) ? creep
Exit: (9) parent(lina, julia) ? creep
Exit: (8) sibling(rosa, julia) ? creep
true.
因此,首先我们通过alex(两人的父亲)找到兄弟姐妹关系,然后通过lina(两人的母亲)找到兄弟姐妹关系
如果这里没有同父异母的兄弟姐妹(两个人共享相同的父亲/2
或母亲/2
,但不是相同的母亲/2
或父亲/2
),那么我们可以通过只选择两个父母中的一个来“消除重复”,例如母亲/2
:
sibling(A, B) :-
dif(A, B),
mother(M, A),
mother(M, B).
sibling(A, B) :-
dif(A, B),
father(F, A),
father(F, B).
根据注释,您的female/1
谓词似乎工作不正常。所以我建议你试着解决这个问题
或者通过父亲/2:
sibling(A, B) :-
dif(A, B),
mother(M, A),
mother(M, B).
sibling(A, B) :-
dif(A, B),
father(F, A),
father(F, B).
当我们考虑一个有一半兄弟姐妹的家庭时,我们可以通过检查<代码>母亲/ 2 < /代码>和<代码>父亲/ 2 < /代码>来实现一个谓词,其中“<代码>母亲> / 2 < /代码> .< /p>使用<代码>母亲/2 < /代码>和/或<代码>父/ 2 < /代码>使谓词“不对称”(当然,不允许同性婚姻)。.现在我不考虑同父异母的兄弟姐妹,所以你说的很有道理,但当我试图通过兄弟姐妹(A,julia)得到julia的兄弟姐妹时。它返回false,知道为什么吗?@JorgePadilla:是的,如果
X
是一个自由变量,你的female(X)
谓词将失败。你也可以通过首先指定parent(M,C)
然后指定female(M)
来修复mother/2
谓词,因为M
是“统一的”在检查female/1
之前使用一个常量。好的,谢谢,我重新排列了父母/母亲的顺序,并得出以下结论:兄弟姐妹(Ss,X):-dif(Ss,X),父亲(F,Ss),父亲(F,X),母亲(M,Ss),母亲(M,X)。这有意义吗?或者你注意到什么车了吗?