Prolog和祖先关系

3

我需要编写一个小的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).

现在我需要编写一个名为ancestor(X,Y,Z)的方法,它还应该打印出两个人之间的关系。它应该像这样:

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

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

3个回答

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在他的编辑中所示,这里不需要显式累加器,因为我们可以在每次迭代时轻松地将术语的内部部分保持未绑定状态。因此,他的解决方案更好!


“Adapt”:这是一个委婉的说法,意思是“修复”。 - Scott Hunter

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).

很遗憾,不太对:ancestor(tim, ephraim, X)返回mother(father(anna))。我试图修复它,但是我不理解。 - user1164180

0
一种术语操作替代累加器技术的方法,由@Mog提出:
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].

为了测试,我让Tim成为Ugo的父亲:father(ugo, tim).

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接