为什么 SWI-prolog 中的 findall/3 忽略了变量绑定



以下代码给出这些结果:

?- X = a, findall(Element, ( member(Z, [a,b,c]), Element = Z:X  ), Set).
X = a,
Set = [a:a, b:a, c:a].

但是当我希望所有元素共享相同的未绑定变量(而不是 a)时,事情就不像假设的那样工作:

?- X = Y, findall(Element, ( member(Z, [a,b,c]), Element = Z:X  ), Set).
X = Y,
Set = [a:_G1918, b:_G1912, c:_G1906]. 

为什么_G1918、_G1912和_G1906不相互约束?这是SWI-Prolog中的错误吗?

您可以使用bagof/3

?- X = Y, bagof(Element, Z^( member(Z, [a,b,c]), Element = Z:X  ), Set).
X = Y,
Set = [a:Y, b:Y, c:Y].

来自SWI-Prolog的文档:

findall/3 等价于 bagof/3,所有自由变量都绑定了 存在运算符 (^),除了 bagof/3 在 Goal 有 没有解决方案。

在您的查询中,X是一个自由变量,因此您得到的结果与具有X^bagof/3的结果相同:

?- X = Y, bagof(Element, X^Z^( member(Z, [a,b,c]), Element = Z:X  ), Set).
X = Y,
Set = [a:_G2115, b:_G2109, c:_G2103].
这不是

一个错误,内置的"所有解决方案"在可变量化处理方面有所不同。

Findall/3 这是更简单的模型。对于您的情况,bagof/3 将起作用,但您需要指示聚合变量:

?- X = Y, bagof(Element, Z^( member(Z, [a,b,c]), Element = Z:X  ), Set).
X = Y,
Set = [a:Y, b:Y, c:Y].

最新更新