我有一个prolog定义,返回多个答案。我想要而不是这个,返回一个包含所有可能答案的列表。
E.g。
alpha;
beta;
gamma;
delta;
到
[alpha, beta, gamma, delta];
如何在prolog中完成?
答案 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
与所有答案的列表统一。
编辑 正如问题所述,在问题的上下文中使用setof
或bagof
代替findall
是错误的。
setof
显然是错误的,因为它会跳过碰巧重复的有效解决方案。当没有解决方案时bagof
失败,而findall
正确“返回”空列表[]
(根据OP的要求) )。哦,bagof
和setof
回溯关于自由变量的替代绑定,而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要求返回“包含所有可能答案的单一列表”。
编辑 没有答案时所有答案的列表是一个空列表。