Một all-giải pháp predicate như findall/3
thể làm như lừa:
list_parents(P, L) :-
findall(Parent, parent(Parent, P), L).
Simply đặt, findall/3
tìm tất cả các ràng buộc cho Parent
trong mục tiêu 'backtrack-possible' parent(Parent, P)
và đặt tất cả các liên kết của Parent
vào danh sách L
. Lưu ý rằng thao tác này sẽ không xóa các mục trùng lặp, nhưng bạn có thể thực hiện sort/2
đến L
trước khi trả lại để tạo một bộ. Thực hiện điều này:
?- list_parents(bob, L).
L = [pam, george].
Nếu bạn không có findall/3
trong việc thực hiện PROLOG của bạn, bạn có thể làm nó bằng tay như thế này:
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).
Phiên bản này sẽ gửi các cuộc gọi đến list_parents/2
tắt để một ắc-phiên bản, list_parents/3
. Sau đó, cố gắng thu thập các ràng buộc Parent
, miễn là chúng tôi chưa thấy chúng trước đây (do đó kiểm tra \+ member
) và trả về danh sách không có các liên kết Parent
mới tích lũy vào danh sách Acc
. Thực hiện điều này sẽ cho chúng ta những kết quả tương tự như tùy chọn đầu tiên:
?- list_parents(bob, L).
L = [pam, george].
tôi đăng một câu hỏi theo dõi câu trả lời của bạn liên quan đến việc "giải pháp" vị ngữ: https://stackoverflow.com/questions/47233986/higher-order- giải pháp-predicate – mrsteve