用于findall
完成此操作:
P2(ARGUMENTS, LIST) :- findall(X, P1(ARGUMENTS, X), LIST).
这与Anders Lindahl 链接bagof
的问题中提到的功能有关。这里setof
对这两个函数(和第三个函数)之间的关系有一个很好的解释:
为了说明差异,请考虑一个小例子:
listing(p).
p(1,3,5).
p(2,4,1).
p(3,5,2).
p(4,3,1).
p(5,2,4).
尝试以下目标。(答案显示已修改以节省空间。)
?- bagof(Z,p(X,Y,Z),Bag).
Z = _G182 X = 1 Y = 3 Bag = [5] ;
Z = _G182 X = 2 Y = 4 Bag = [1] ;
Z = _G182 X = 3 Y = 5 Bag = [2] ;
Z = _G182 X = 4 Y = 3 Bag = [1] ;
Z = _G182 X = 5 Y = 2 Bag = [4] ;
No
?- findall(Z,p(X,Y,Z),Bag).
Z = _G182 X = _G180 Y = _G181 Bag = [5, 1, 2, 1, 4] ;
No
?- bagof(Z,X^Y^p(X,Y,Z),Bag).
Z = _G182 X = _G180 Y = _G181 Bag = [5, 1, 2, 1, 4] ;
No
?- setof(Z,X^Y^p(X,Y,Z),Bag).
Z = _G182 X = _G180 Y = _G181 Bag = [1, 2, 4, 5] ;
No
目标中自由变量的单个绑定的谓词bagof
和setof
产生集合。setof
生成没有重复的集合的排序版本。为避免绑定变量,请使用存在量词表达式。例如,目标
bagof(Z,X^Y^p(X,Y,Z),Bag)
要求“的 Bag ofZ
存在一个X
并且存在一个Y
这样的
p(X,Y,Z)
”。findall
就像bagof
所有自由变量自动存在量化一样。此外
findall
返回一个空列表[]
,没有目标满足,而bagof
失败。