Prolog 家庭序言练习

Prolog 家庭序言练习,prolog,Prolog,我不熟悉prolog,不知道如何解决这个问题。我必须写一条规则。一直以来,在代码的底部,我都有我的兄弟姐妹的规则。该规则的问题在于它会返回兄弟姐妹两次。例如,如果我想得到朱莉娅的兄弟姐妹,我会得到“罗莎”两次。我想现在发生的是程序为每个家长(alex和lina)进行评估。那么,我怎样才能修正我的规则,让我只得到朱莉娅(或任何人)的兄弟姐妹一次呢 parent(alex,julia). parent(alex,rosa). parent(lina,julia). parent(lina,rosa)

我不熟悉prolog,不知道如何解决这个问题。我必须写一条规则。一直以来,在代码的底部,我都有我的兄弟姐妹的规则。该规则的问题在于它会返回兄弟姐妹两次。例如,如果我想得到朱莉娅的兄弟姐妹,我会得到“罗莎”两次。我想现在发生的是程序为每个家长(alex和lina)进行评估。那么,我怎样才能修正我的规则,让我只得到朱莉娅(或任何人)的兄弟姐妹一次呢

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)。这有意义吗?或者你注意到什么车了吗?