Search code examples
prologsicstus-prologprolog-coroutining

Unexpected behavior of frozen/2


I was playing around with the 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).

(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 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?


Solution

  • 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).