如何在 swi-prolog 中编写后代谓词?

时间:2021-06-24 03:44:34

标签: prolog swi-prolog

我提供的后代定义如下:

"直系祖先的人。例如:孩子, 孙子、曾孙和永远"

以及其他规则,例如:

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

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

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

或者有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

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

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

ancestor(Ancestor,Generations,Descendant)

假设您有一组事实,例如

parents( mother, father, child ).

On 可以说父母是孩子的母亲或父亲:

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

这适用于亲生父母,但如果您允许 非生物出身(例如,继父母等,然后 “我是我自己的爷爷”是一种可能,你需要随身携带 周围访问过的节点列表,以便您可以检测到任何循环 图表。

试着从中找出不同程度的亲缘关系 (三次移除的二表亲是什么样子的?)。您需要确定初学者的兄弟姐妹状态。

相关问题