我有谓词P1,它会一个接一个地返回值:
-? P1(ARGUMENTS, RETURN).
-? RETURN = 1;
-? RETURN = 2;
-? RETURN = 3;
-? fail.
我还有另一个名为P2的谓词:
P2(ARGUMENTS, LIST) :- P1(ARGUMENTS, RETURN),... % SOMEHOW HERE I NEED TO INSERT ALL VALUES OF RETURN TO LIST.
如何查找RETURN
的所有值并将其分配给LIST
?
答案 0 :(得分:17)
使用findall
来完成此任务:
P2(ARGUMENTS, LIST) :- findall(X, P1(ARGUMENTS, X), LIST).
这与Anders Lindahl关联的bagof
function mentioned in the question有关。关于两个函数之间的关系有很好的解释(第三个函数setof
)here:
说明差异考虑 一个小例子:
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)
要求 “Z
的袋子就是存在的 一个X
,并且存在Y
p(X,Y,Z)
“。findall
就像bagof
一样 自动包含所有自由变量 存在量化的。此外findall
会在那里返回一个空列表[]
没有目标满意度,而bagof
失败。