Un all-solutions prédicat comme findall/3
pourrait faire l'affaire:
list_parents(P, L) :-
findall(Parent, parent(Parent, P), L).
simplement put, findall/3
trouve toutes les liaisons pour Parent
dans l'objectif 'backtrack-able' parent(Parent, P)
, et met toutes les liaisons de Parent
dans la liste L
. Notez que cela ne supprime pas les doublons, mais vous pouvez faire un sort/2
à L
avant de le retourner pour créer un ensemble. L'exécution de cette:
?- list_parents(bob, L).
L = [pam, george].
Si vous n'avez pas findall/3
dans votre implémentation Prolog, on pourrait le faire manuellement comme ceci:
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).
Cette version envoie des appels à list_parents/2
off à une version de l'accumulateur, list_parents/3
. Ce dernier essaie également de collecter des liaisons Parent
, tant que nous ne les avons pas vues auparavant (d'où le contrôle \+ member
), et renvoie la liste dans laquelle aucune nouvelle liaison Parent
accumulée dans la liste Acc
ne peut être trouvée. L'exécution cela nous donne le même résultat que la première option:
?- list_parents(bob, L).
L = [pam, george].
Je posté une question de suivi à votre réponse concernant le prédicat « solutions »: https://stackoverflow.com/questions/47233986/higher-order- solutions-prédicat – mrsteve