0

使用递归我需要找到家谱中任何人的所有血缘关系。到目前为止,我的尝试失败了。这是我的代码,我的尝试在底部

female(helen).
female(debbie).
female(louise).
female(yvonne).
female(belinda).
female(heather).
male(john).
male(andrew).
male(barry).
male(daniel).
male(charles).
parent(helen, debbie).
parent(helen, barry).
parent(helen, louise).
parent(john, debbie).
parent(john, barry).
parent(andrew, louise).
parent(debbie, yvonne).
parent(debbie, daniel).
parent(barry, charles).
parent(barry, belinda).
parent(louise, heather).

mother(X, Y) :-
        female(X),
        parent(X, Y).
father(X, Y) :-
        male(X),
        parent(X,Y).
child(X, Y) :-
        parent(Y, X).
daughter(X, Y) :-
        parent(Y, X),
        female(X).
son(X, Y) :-
        parent(Y,X),
        male(X).
sister(X, Y) :-
        female(X),
        parent(Q,X),
        parent(Q,Y).
brother(X, Y) :-
        male(X),
        parent(Q,X),
        parent(Q,Y).
sibling(X, Y) :-
        parent(Q,X),
        parent(Q,Y),
        X\=Y.
uncle(X, Y) :-
        parent(P,Y),
        brother(X,P).
aunt(X, Y) :-
        parent(P,Y),
        sister(X,P).

cousin(C, Cousin):-
        parent(Parent,C),
        sibling(Parent,AU),
        child(Cousin,AU).

        %Here is Relative

relative(An, Re):-
        An\=Re,
        parent(An, Re);
        sibling(An, Re).

relative(An, Rela):-
        parent(An, Child);
        sibling(An, Rela),      
        relative(Child, Rela),
        An\=Rela, C\=Rela.

有点作品,但最后陷入了无限循环。谢谢。

4

2 回答 2

2

不确定“亲戚”(在父/子关系中可以触及的任何人?),但您的定义似乎比需要的更复杂(您知道什么;吗?)。

我试过了

relative(An, Re):-
        parent(An, Re).
relative(An, Rela):-
        parent(An, C),
        relative(C, Rela).

产生

16 ?- forall(relative(X,Y),writeln(X:Y)).
helen:debbie
helen:barry
helen:louise
john:debbie
john:barry
andrew:louise
debbie:yvonne
debbie:daniel
barry:charles
barry:belinda
louise:heather
helen:yvonne
helen:daniel
helen:charles
helen:belinda
helen:heather
john:yvonne
john:daniel
john:charles
john:belinda
andrew:heather
true.

编辑我尝试了另一个关系,使用广义的 parent/2,但仍然过于宽容。

relative(Pers, Re):-
        ancestor(Re, Pers) ; sibling(Pers, Re) ; cousin(Pers, Re) ; uncle(Re, Pers) ; aunt(Re, Pers).

ancestor(Anc, Pers) :- parent(Anc, Pers).
ancestor(Anc, Pers) :- parent(Anc, P), ancestor(P, Pers).

也许堂兄/ 2也太宽容了。这是图表

在此处输入图像描述

我猜希瑟应该只有路易斯、海伦和安德鲁作为亲戚。这是真的吗?

编辑给出最新评论,似乎定义可能是正确的。我明白了

24 ?- setln(X,relative(heather,X)).
andrew
barry
belinda
charles
daniel
debbie
helen
louise
yvonne
true.

那就是每个人都与希瑟·约翰有关。

于 2013-11-08T12:16:17.403 回答
0

Here's one way that works, but it will sometimes produce duplicates. Using setof will give the unique collection. I avoided the miscellaneous relations and stuck with descendent or parent.

descendent(A, B) :-
    parent(B, A).
descendent(A, B) :-
    parent(C, A),
    descendent(C, B).

relative(A, B) :-
    descendent(B, A).
relative(A, B) :-
    descendent(A, B).
relative(A, B) :-
    descendent(A, C),
    descendent(B, C),
    A \= B.

setof(A, relative(heather, A), Relatives).

Relatives = [andrew,barry,belinda,charles,daniel,debbie,helen,louise,yvonne]

If you don't have setof, you can use the findall/3 and sort/2 ISO predicates:

findall(A, relative(heather, A), R), sort(R, Relatives).

Note that the solutions presented so far assume that all of the relatives have unique names. A general case of dealing with relatives with the same first name (and possibly the same last name) you would need to track and compare lineages for differences.

于 2013-11-08T17:29:06.157 回答