bagof只提供一件商品,但多件商品适合

时间:2016-07-17 12:51:06

标签: prolog

此代码按预期工作:

posedge of clock

但类似的电话,我真正想要的电话,却不会:

 ?- bagof(R,member(r(R),[r(a),r(b),r(c),r(d)]),Rs).
Rs = [a, b, c, d].

?- bagof(R,member(r(_,R),[r(_,a), r(_,b), r(_,c), r(_,d)]),Rs). Rs = [a] 给了我更多答案 - 但我想要;。我的修复是什么?

3 个答案:

答案 0 :(得分:3)

bagof/3_不直接聚集在一起。 setof/3也是如此。

所以要么给所有这些匿名变量一个名称,并将它们声明为局部变量,使用辅助谓词,或者使用library(lambda)

?- bagof(R,R+\member(r(_,R),[r(_,a), r(_,b), r(_,c), r(_,d)]),Rs).
Rs = [a,b,c,d].

答案 1 :(得分:2)

您需要存在性地限定您不感兴趣的参数而不是使用匿名变量:

?- bagof(R,A^A1^A2^A3^A4^member(r(A,R),[r(A1,a), r(A2,b), r(A3,c), r(A4,d)]),Rs).
Rs = [a, b, c, d].

这是必要的,因为bagof/3(和setof/3)将为自由变量的每个实例化返回一个解决方案包(集)(即目标中不在模板中的变量) 。或者,您可以使用findall/3谓词(忽略自由变量):

?- findall(R,member(r(A,R),[r(A1,a), r(A2,b), r(A3,c), r(A4,d)]),Rs).
Rs = [a, b, c, d].

但请注意,当没有解决方案时,findall/3会返回空列表,而bagof/3(和setof/3)在没有解决方案时会失败。

在调用bagof/3setof/3时避免一长串存在限定变量的另一种方法是引入一个带有单个子句的辅助谓词,其头部只列出您感兴趣的参数。例如:

r(R) :-
    member(r(_,R),[r(_,a), r(_,b), r(_,c), r(_,d)]).

?- bagof(R, r(R), Rs).
Rs = [a, b, c, d].

答案 2 :(得分:1)

Paulo贡献了一个库(yall),在SWI-Prolog中自动加载。 Yall(Yet Another Lambda Library)可以轻松解决您的问题:

?- bagof(R, {R}/member(r(_,R),[r(_,a), r(_,b), r(_,c), r(_,d)]),Rs).
Rs = [a, b, c, d].