我有一个返回多个答案的序言定义。我想代替这个,返回一个包含所有可能答案的列表。
例如
alpha;
beta;
gamma;
delta;
到
[alpha, beta, gamma, delta];
这怎么能在序言中完成?
我有一个返回多个答案的序言定义。我想代替这个,返回一个包含所有可能答案的列表。
例如
alpha;
beta;
gamma;
delta;
到
[alpha, beta, gamma, delta];
这怎么能在序言中完成?
请注意,根据您的具体需要,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].
做的伎俩虽然。
我不确定我在这里所说的是否适用于 SWI-Prolog 以外的其他 Prolog 系统。
这是相应的文档页面。
通过使用findall
. 你有somepred(X)
它给你指定的答案。现在尝试运行findall(X,somepred(X),List)
以查看List
统一的所有答案列表。
编辑:如所问,在问题的上下文中使用setof
orbagof
代替findall
setof
显然是错误的,因为它跳过了恰好是重复的有效解决方案。当没有解决方案时bagof
失败findall
,同时正确地“返回”一个空列表[]
(按照 OP 的要求)。哦,还有自由变量的替代绑定bagof
和setof
回溯,而 OP 明确要求“返回”一个解决方案列表,即没有回溯。以机智:
?- [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 要求返回“包含所有可能答案的单一列表”。
编辑:没有答案时的所有答案列表是一个空列表。