在普罗格(Prolg)的家庭列表中查找祖先

时间:2018-12-08 18:14:53

标签: prolog

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]。

1 个答案:

答案 0 :(得分:0)

如果有意义的话,通常不将它们包装在谓词列表中,因为这样可以使谓词“链”变得难以过滤或生成其他值,因此变得更加困难。因此,通常最好将中间谓词“散出”。

可以通过以下方式获得孩子的父母:

parent(Parent, Child) :-
    (familija(Parent, _, Children); familija(_, Parent, Children)),
    member(Child, Children).

有趣的是,它可以实现 multidirectional :我们可以查询Parent的各个子代,但也可以查询给定Child的父代是什么(或检查ParentChild的父对象,还是遍历所有父子关系)。

例如:

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

因此,XZ的祖先,假设XZ的父母,或者假设X是{{1}的父母},而YY的祖先。

现在,对于给定的孩子,我们可以查询所有祖先:

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