1

我有一个返回多个答案的序言定义。我想代替这个,返回一个包含所有可能答案的列表。

例如

alpha;
beta;
gamma;
delta;

[alpha, beta, gamma, delta];

这怎么能在序言中完成?

4

2 回答 2

1

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

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

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 系统。

这是相应的文档页面

于 2012-04-27T09:35:10.093 回答
0

通过使用findall. 你有somepred(X)它给你指定的答案。现在尝试运行findall(X,somepred(X),List)以查看List统一的所有答案列表。

编辑:如所问,在问题的上下文中使用setoforbagof代替findall

setof显然是错误的,因为它跳过了恰好是重复的有效解决方案。当没有解决方案时bagof 失败findall,同时正确地“返回”一个空列表[](按照 OP 的要求)。哦,还有自由变量的替代绑定bagofsetof 回溯,而 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 要求返回“包含所有可能答案的单一列表”

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

于 2012-04-27T08:24:55.837 回答