像这样的全解谓词findall/3
可能会解决这个问题:
list_parents(P, L) :-
findall(Parent, parent(Parent, P), L).
简单的说,findall/3
查找所有绑定Parent
在“可回溯”目标中parent(Parent, P)
,并将所有绑定Parent
进入列表L
。请注意,这不会删除重复项,但您可以执行以下操作sort/2
to 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].