Предикат "все решения", такой как findall/3
, может помочь:
list_parents(P, L) :-
findall(Parent, parent(Parent, P), L).
Проще говоря, findall/3
находит все привязки для Parent
в цели "backtrack-способны" parent(Parent, P)
и помещает все привязки Parent
в список L
.Обратите внимание, что это не удалит дубликаты, но вы можете сделать от sort/2
до L
перед возвратом, чтобы создать набор.Выполнение этого:
?- list_parents(bob, L).
L = [pam, george].
Если у вас нет findall/3
в вашей реализации PROLOG, вы можете сделать это вручную следующим образом:
list_parents(P, L) :-
list_parents(P, [], L).
list_parents(P, Acc, L) :-
parent(Parent, P),
\+ member(Parent, Acc), !,
list_parents(P, [Parent|Acc], L).
list_parents(_, L, L).
Эта версия отправляет вызовы на list_parents/2
до аккумуляторной версии, list_parents/3
.Последний также пытается собрать привязки Parent
, пока мы их не видели (следовательно, проверка \+ member
), и возвращает список, в котором не может быть никаких новых привязок Parent
, накопленных в списке Acc
.найденный.Выполнение этого дает нам тот же результат, что и первый вариант:
?- list_parents(bob, L).
L = [pam, george].