我正在学习prolog,我正在读一本名为Programming Prolog for Artificial Intelligence的书。作为练习,我想学习如何扩展本书中的一个例子。有人可以帮忙吗?
说你有这些事实:
parent(pam, bob). %pam is a parent of bob
parent(george, bob). %george is a parent of bob
我怎么写一个prolog谓词会给我一个bobs父母列表?例如:
list_parents(bob, L).
L = [pam, george] ;
L = [george, pam] ;
true.
答案 0 :(得分:17)
像findall/3
这样的全解决方案谓词可能会起到作用:
list_parents(P, L) :-
findall(Parent, parent(Parent, P), L).
简单地说,findall/3
在“可追溯”目标Parent
中找到parent(Parent, P)
的所有绑定,并将Parent
的所有绑定放入列表{{1} }}。请注意,这不会删除重复项,但您可以在返回创建集合之前执行L
到sort/2
。执行此:
L
如果你的PROLOG实现中没有?- list_parents(bob, L).
L = [pam, george].
,你可以像这样手动完成:
findall/3
此版本将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
答案 1 :(得分:2)
试试这个:
parent(pam, bob). %pam is a parent of bob
parent(george, bob). %george is a parent of bob
list_parents(A, Es, [X|Xs]) :- parent(X, A), \+ member(X, Es), list_parents(A, [X|Es], Xs).
list_parents(A, Es, []).
这是一种效率低下的方法,更好的方法需要“解决方案”高阶谓词。
list_parents(X,Ys): - 解决方案(父,[X,W],1,Ys)