familija(father,mother,list_of_child).
familija(1,2,[9,10]).
familija(1,3,[11]).
familija(4,5,[12,13,14]).
familija(6,7,[8]).
familija(8,9,[15]).
familija(11,13,[16]).
这是数据库,我需要找到给定X的祖先列表 α-祖先(16,L)。 L = [12,13,1,3,4,5]。
答案 0 :(得分:0)
如果有意义的话,通常不将它们包装在谓词列表中,因为这样可以使谓词“链”变得难以过滤或生成其他值,因此变得更加困难。因此,通常最好将中间谓词“散出”。
可以通过以下方式获得孩子的父母:
parent(Parent, Child) :-
(familija(Parent, _, Children); familija(_, Parent, Children)),
member(Child, Children).
有趣的是,它可以实现 multidirectional :我们可以查询Parent
的各个子代,但也可以查询给定Child
的父代是什么(或检查Parent
是Child
的父对象,还是遍历所有父子关系)。
例如:
?- parent(P, 16).
P = 11 ;
P = 13.
现在,我们可以对parent/2
谓词进行传递闭包,以定义ancestor/2
:
ancestor(X, Z) :-
parent(X, Z).
ancestor(X, Z) :-
parent(X, Y),
ancestor(Y, Z).
因此,X
是Z
的祖先,假设X
是Z
的父母,或者假设X
是{{1}的父母},而Y
是Y
的祖先。
现在,对于给定的孩子,我们可以查询所有祖先:
Z
因此,现在我们唯一需要做的就是将它们包装在列表中。我们可以使用findall/3
[swi-doc]来做到这一点:
?- ancestor(X, 16).
X = 11 ;
X = 13 ;
X = 1 ;
X = 4 ;
X = 3 ;
X = 5 ;
false.
这将给我们:
ancestor_list(Decendant, Ancestors) :-
findall(Ancestor, ancestor(Ancestor, Decendant), Ancestors).