获取Prolog中的解决方案列表

时间:2010-11-16 03:44:57

标签: prolog

我正在学习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.

2 个答案:

答案 0 :(得分:17)

findall/3这样的全解决方案谓词可能会起到作用:

list_parents(P, L) :-
    findall(Parent, parent(Parent, P), L).

简单地说,findall/3在“可追溯”目标Parent中找到parent(Parent, P)的所有绑定,并将Parent的所有绑定放入列表{{1} }}。请注意,这不会删除重复项,但您可以在返回创建集合之前执行Lsort/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)