An all-solutions predicate such as findall/3 can do the trick:
list_parents(P, L) :- findall(Parent, parent(Parent, P), L).
Simply put, findall/3 finds all the bindings for Parent in the target with the return traffic parent(Parent, P) and puts all the bindings of Parent on the L list. Note that this will not remove duplicates, but you can do sort/2 to L before returning it to create a set. Doing this:
?- list_parents(bob, L). L = [pam, george].
If you do not have findall/3 in your PROLOG implementation, you can do it manually as follows:
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).
This version sends calls to list_parents/2 to the battery version, list_parents/3 . The latter also tries to collect Parent bindings, if we have not seen them before (therefore, checking \+ member ), and returns a list in which new Parent bindings copied to the Acc list can be found. Doing this gives us the same result as the first option:
?- list_parents(bob, L). L = [pam, george].