Swi-Prolog: 后代谓词怎么写?

Swi-Prolog: How to write a descendant predicate?

我有如下提供的后代定义:

直系祖先的人。例如:child, 盛大child、great-grandchild 和永远"

以及其他规则,例如:

...
childof(X, Y).
parent(X, Y).
grandchild(X, Y).
ancestor(X, Y).
...

那么我可以简单地写一个规则如下,

descendant(X, Y):- ancestorof(Y, X).

或者有更好的方法吗?

这是树遍历或者图遍历的问题

我会概括一个 ancestor_of/3 谓词:

ancestor(Ancestor,Generations,Descendant)

假设你有一组事实,比如

parents( mother, father, child ).

On 可以说 parent 是 child 的母亲或父亲:

% P is a parent of C if P is either the mother or father of C.
parent(P,C) :- parents(P,_,C).
parent(P,C) :- parents(_,P,C).

鉴于上述情况,解决方案可能如下所示:

ancestor(Ancestor, Generations, Descendant) :-
  ancestor( Ancestor, 0, Generations, Descendant )
  .

ancestor( A, N, G, D ) :- % A is an ancestor of D...
  parent(A,D),            % * if A is the immediate parent of D
  G is N+1                % * in which case, tick the generation count
  .                       % Easy!
ancestor( A, N, G, D ) :- % otherwise, A is an ancestor of D...
  parent(A,X),            % * if A is the immediate parent of somebody
  X \= D,                 % * other than D
  N1 is N+1,              % * [ tick the generation count]
  ancestor( X, N1, G, D ) % and that somebody is the ancestor of D
  .                       % Also easy!

这让我们可以这样说:

grandparent(A,C) :- ancestor(A,2,C).

great-grandparent(A,C) :- ancestor(A,3,C).

等等

这适用于生物 parent年龄,但如果您允许 non-biologicalparent年龄(如step-parents等,则 “我是我自己的爷爷”是一种可能性,你需要携带 周围已访问节点的列表,因此您可以检测 图。

想办法从这里判断不同的亲属关系 (三次删除的第二个堂兄长什么样?)。您需要确定初学者的兄弟姐妹身份。