Prolog和祖先的关系

时间:2012-01-23 01:58:27

标签: prolog

我必须写一个小的prolog程序,检查给定的人是否是第二个的祖先。 这些是事实和规则:

mother(tim, anna).
mother(anna, fanny).
mother(daniel, fanny).
mother(celine, gertrude).
father(tim, bernd).
father(anna, ephraim).
father(daniel, ephraim).
father(celine, daniel).

parent(X,Y) :- mother(X,Y).
parent(X,Y) :- father(X,Y).

如果一个人是另一个人的祖先的测试很容易:

ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).

但是现在我必须写一个方法祖先(X,Y,Z),它也打印出两个人之间的关系。看起来应该是这样的

?- ancestor(ephraim, tim, X).
false.
?- ancestor(tim, ephraim, X).
X = father(mother(tim)).

这就是问题所在:我不知道如何做到这一点。

3 个答案:

答案 0 :(得分:1)

您可以使用累加器来调整@Scott Hunter的解决方案:

mother(anna, fanny).
mother(daniel, fanny).
mother(celine, gertrude).
father(tim, bernd).
father(anna, ephraim).
father(daniel, ephraim).
father(celine, daniel).

ancestor(X, Y, Z) :- ancestor(X, Y, X, Z).
ancestor(X, Y, Acc, father(Acc)) :- father(X, Y).
ancestor(X, Y, Acc, mother(Acc)) :- mother(X, Y).
ancestor(X, Y, Acc, Result) :-
    father(X, Z),
    ancestor(Z, Y, father(Acc), Result).
ancestor(X, Y, Acc, Result) :-
    mother(X, Z),
    ancestor(Z, Y, mother(Acc), Result).

编辑:正如Scott Hunter在他的编辑中所示,这里不需要显式累加器,因为我们可以在每次迭代时轻松地保留术语的内部部分。因此,他的解决方案更好!

答案 1 :(得分:0)

只需添加一个术语,该术语表示在每个步骤中使用了哪种父级(编辑以获得正确顺序的结果):

ancestor(X,Y,father(X)) :- father(X,Y).
ancestor(X,Y,mother(X)) :- mother(X,Y).
ancestor(X,Y,father(Z2)) :- father(Z,Y), ancestor(X,Z,Z2).
ancestor(X,Y,mother(Z2)) :- mother(Z,Y), ancestor(X,Z,Z2).

答案 2 :(得分:0)

@Mog的累加器tecnique的术语操作替代:

parent(X, Y, mother(X)) :- mother(X, Y).
parent(X, Y, father(X)) :- father(X, Y).

ancestor(X, Y, R) :-
    parent(X, Y, R).
ancestor(X, Y, R) :-
    parent(X, Z, P),
    ancestor(Z, Y, A),
    eldest(A, P, R).

eldest(A, P, R) :-
    A =.. [Af, Aa],
    (   atom(Aa)
    ->  T = P
    ;   eldest(Aa, P, T)
    ),
    R =.. [Af, T].

为了测试,我让蒂姆变成了父亲:father(ugo, tim).

?- ancestor(tim, ephraim, X).
X = father(mother(tim)) .

?- ancestor(ugo, ephraim, X).
X = father(mother(father(ugo))) .