Найти предка в списке семьи в Пролг - PullRequest
0 голосов
/ 08 декабря 2018
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? -Ancestor (16, L).L = [12,13,1,3,4,5].

1 Ответ

0 голосов
/ 08 декабря 2018

Как правило, нельзя заключать элементы в списки в предикат, если имеет смысл выводить их по отдельности, поскольку тогда становится сложнее создать «цепочку» предикатов для фильтрации или генерировать другие значения.Поэтому, как правило, лучше «излучать» отдельные элементы в промежуточных предикатах.

Родитель ребенка можно получить с помощью:

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

Приятно то, что это работает разнонаправленный : мы можем запросить отдельных потомков 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 является родителем Y, а Y является предкомиз Z.

Итак, теперь для данного ребенка мы можем запросить всех предков:

?- ancestor(X, 16).
X = 11 ;
X = 13 ;
X = 1 ;
X = 4 ;
X = 3 ;
X = 5 ;
false.

Так что теперь единственное, что нам нужно сделать, - это обернуть их в список.Мы можем сделать это с помощью findall/3 [swi-doc] :

ancestor_list(Decendant, Ancestors) :-
    findall(Ancestor, ancestor(Ancestor, Decendant), Ancestors).

Это даст нам:

?- ancestor_list(16, L).
L = [11, 13, 1, 4, 3, 5].
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...