2016-07-17 57 views
4

此代码按预期工作:bagof只给一个项目,虽然多个项目适合

?- 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] 

;给我更多的答案 - 但我想[a,b,c,d]。我的修复程序是什么?

回答

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]. 
+1

真的很不错的“伎俩”驯服bagof/3涉及语法! – CapelliC

+0

我也这么认为!有关findall/3 v。bagof/3的更多信息,请访问:http://www.swi-prolog.org/pldoc/man?predicate=findall/3。谢谢! –

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]. 
+0

该代码片段在我的解释器中不起作用 - 这是SWI-PROLOG,如果这有所作为。 ? –

+3

您需要安装[相应的包](http://www.swi-prolog.org/pack/list?p=lambda)。 – false

1

保罗贡献库(yall),自动加载在SWI-Prolog的。 Yall(又一个Lambda图书馆)轻松解决您的问题:

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