frozen/2 的意外行为

Unexpected behavior of frozen/2

我在玩 谓词 freeze/2frozen/2:

?- freeze(X,a=a), frozen(X,Goal).
?- freeze(X,a=a), freeze(Y,b=b), X=Y, frozen(X,Goal).

(x86_64 的 4.5.1 版)给出了这些答案:

| ?- freeze(X,a=a), frozen(X,Goal).
Goal = prolog:freeze(X,user:(a=a)),
prolog:freeze(X,user:(a=a)) ? ;
no
| ?- freeze(X,a=a), freeze(Y,b=b), X=Y, frozen(X,Goal).
Y = X,
Goal = (user:(a=a),prolog:freeze(X,user:(b=b))),
prolog:freeze(X,user:(a=a)),
prolog:freeze(X,user:(b=b)) ? ;
no

现在 目标 = <b>prolog:freeze(X,</b>user:(a=a)<b>)</b>没想到!

所做的所期望的是 8.0.3 版给出的答案:

?- freeze(X,a=a), frozen(X,Goal).
Goal = user:(a=a),
freeze(X, a=a).
?- freeze(X,a=a), freeze(Y,b=b), X=Y, frozen(X,Goal).
X = Y,
Goal = (user:(a=a), user:(b=b)),
freeze(Y, a=a),
freeze(Y, b=b).

可以说,SICStus 的答案 SWI 的答案都是正确的...

但是 SICStus 给出的有些奇怪的答案是否有更深层次的原因?

不知道是不是有什么"deep"原因造成的差异。由于 frozen/2 是属性变量的通用接口,因此不特例 freeze/2 目标是有意义的。

事实上,在 4.5.1 之前,SICStus 尝试过,但有时会失败,以实现特殊情况 freeze/2 目标。这就是为什么您看到第一个子目标 user:(a=a) 的原因。在下一个版本中,我们对此进行了更改,因此结果将变为 Goal = (prolog:freeze(X,user:(a=a)),prolog:freeze(X,user:(b=b)))(我们还对 frozen/2 进行了一些其他改进)。