如何从家庭谓词中提取所有祖先?

How to extract all ancestors from family predicate?

我有这些给定的事实,格式为 family(parent1, parent2, listOfChildren):

family (1,2,[9,10]).
family (1,3,[11]).
family (4,5,[12,13,14]).
family (6,7,[8]).
family (8,9,[15]).
family (11,13,[16]).

我需要提取给定 child 的所有祖先。 例如

 ancestors(16,L)

应该'return':[11,13,1,3,4,5]

这几天我一直在努力解决这个问题。您的帮助将是 'a savior'.

我认为您应该首先专注于编写一个谓词,该谓词在第一个参数是第二个参数的祖先时成功。所以,ancestor(X,Z) 像这样:

ancestor(X,Z) :- family(X,_,Zs), member(Z,Zs).
ancestor(Y,Z) :- family(_,Y,Zs), member(Z,Zs).

ancestor(X,Z) :- family(W,_,Zs), member(Z,Zs), ancestor(X,W).
ancestor(Y,Z) :- family(_,W,Zs), member(Z,Zs), ancestor(Y,W).

现在,findall 很有用。

?- findall(X,ancestor(X,_),Xs), list_to_set(Xs,Ys), write(Ys)

我使用 list_to_set/1 删除重复项。

产生:

[1,4,6,8,11,2,3,5,7,9,13]

现在,我可以执行此查询:

?- ancestor(L,16).
L = 11 .

请注意,我交换了您提供的参数的顺序,因为 Prolog 通常以这种方式读取:“L 是一个 祖先 of 16