I was playing around with the prolog-coroutining predicates freeze/2
and frozen/2
:
?- freeze(X,a=a), frozen(X,Goal).
?- freeze(X,a=a), freeze(Y,b=b), X=Y, frozen(X,Goal).
sicstus-prolog (version 4.5.1 for x86_64) gave these answers:
| ?- 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
Now Goal = prolog:freeze(X,user:(a=a))
I did not expect!
What I did expect were answers like the ones given by swi-prolog version 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).
Arguably, both the SICStus answers and the SWI answers are correct...
But is there a deeper reason for the somewhat peculiar answer(s) given by SICStus?
I don't know if there is any "deep" reason for the difference. Since frozen/2
is a general interface to attributed variables, it kind of makes sense to not special-case freeze/2
goals.
In fact, up to 4.5.1, SICStus tried, but sometimes failed, to special-case freeze/2
goals. This is why you see user:(a=a)
for the first sub-goal. In the next release we have changed this so the result instead will become Goal = (prolog:freeze(X,user:(a=a)),prolog:freeze(X,user:(b=b)))
(and we have also made some other improvements to frozen/2
).