如何在prolog中返回单个答案列表(而不是多个单独的答案)?

时间:2012-04-27 08:20:40

标签: list prolog combinations

我有一个prolog定义,返回多个答案。我想要而不是这个,返回一个包含所有可能答案的列表。

E.g。

alpha;
beta;
gamma;
delta;

[alpha, beta, gamma, delta];

如何在prolog中完成?

2 个答案:

答案 0 :(得分:1)

请注意,根据您的具体需要,findall/3可能不合适:

考虑将test/2 : test(+L, -E)E成员统一为自由变量的谓词L

test(L, E) :-
    member(E, L),
    var(E).

现在,假设你想通过使用这个谓词找到列表的所有自由变量(注意:如果你真的想这样做,那不是正确的方法,只是指出一个findall/3行为):

?- findall(X, test([A, 3, C], X), Xs).
Xs = [_G32, _G29].

findall/3给你一个很好的答案,但模数变量重命名!

?- bagof(X, test([A, 3, C], X), Xs).
Xs = [A, C].

?- setof(X, test([A, 3, C], X), Xs).
Xs = [A, C].

尽管如此。

我不确定我在这里说的是否适用于其他Prolog系统而不是SWI-Prolog。

以下是相应的doc page

答案 1 :(得分:0)

使用findall。您有somepred(X),它可以为您提供指定的答案。现在尝试运行findall(X,somepred(X),List)以查看List与所有答案的列表统一。

编辑 正如问题所述,在问题的上下文中使用setofbagof代替findall是错误的。

setof显然是错误的,因为它会跳过碰巧重复的有效解决方案。当没有解决方案时bagof 失败,而findall正确“返回”空列表[](根据OP的要求) )。哦,bagofsetof 回溯关于自由变量的替代绑定,而OP明确要求一个解决方案列表 < em>“返回”,即 无回溯 。即:

?- [user].
|: test(L,E):- member(E,L),var(E).
|: 
% user://2 compiled 0.00 sec, 124 bytes

Yes
?- findall(X, (test([A,3,A],X) , member(A,[1,2]) )   , Xs).

X = _G546
A = _G536
Xs = [1, 2, 1, 2] ;

No
?- bagof(X, (test([A,3,A],X) , member(A,[1,2]) )     , Xs).

X = _G534
A = 1
Xs = [1, 1] ;

X = _G534
A = 2
Xs = [2, 2] ;

No
?- 

但是OP要求返回“包含所有可能答案的单一列表”

编辑 没有答案时所有答案的列表是一个空列表。