un todo-soluciones predicado LIKE findall/3
puede hacer el truco:
list_parents(P, L) :-
findall(Parent, parent(Parent, P), L).
Simplemente put, findall/3
encuentra todas las vinculaciones para Parent
en el objetivo 'backtrack-able' parent(Parent, P)
, y pone todas las vinculaciones de Parent
en la lista L
. Tenga en cuenta que esto no eliminará los duplicados, pero puede hacer un sort/2
a L
antes de devolverlo para crear un conjunto. La ejecución de esta:
?- list_parents(bob, L).
L = [pam, george].
Si usted no tiene findall/3
en su aplicación PROLOG, se puede hacer de forma manual como esto:
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).
Esta versión envía las llamadas a list_parents/2
fuera a un acumulador-versión, list_parents/3
. Este último intenta recopilar Parent
enlaces también, siempre que no los hayamos visto antes (de ahí el \+ member
cheque), y devuelve la lista donde no se pueden encontrar enlaces nuevos Parent
acumulados en la lista Acc
. La ejecución de esta nos da el mismo resultado que la primera opción:
?- list_parents(bob, L).
L = [pam, george].
He publicado una pregunta de seguimiento a la respuesta que se refiere el predicado "soluciones": https://stackoverflow.com/questions/47233986/higher-order- solutions-predicate – mrsteve