Prolog 序言与祖先关系

Prolog 序言与祖先关系,prolog,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,

我必须写一个小的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)).

这就是问题所在:我不知道该怎么做。

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


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

由@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].
为了测试,我让蒂姆做了父亲:
父亲(乌戈,蒂姆)。


不幸的是不完全正确:祖先(提姆,以法莲,X)。返回母亲(父亲(安娜))。我试图修复它,但我不明白。“适应”:这是说“修复”的礼貌方式。
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].
?- ancestor(tim, ephraim, X).
X = father(mother(tim)) .

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