How do SICStus Prolog style attributed variables and the catch/throw Prolog exception handling mechanism interact?
Deep within the source code of library(clpz)
, there's a piece of code I don't quite comprehend:
with_local_attributes(Vars, Goal, Result) :- catch((Goal, maplist(del_all_attrs, Vars), % reset all attributes, only the result matters throw(local_attributes(Result,Vars))), local_attributes(Result,Vars), true).
The auxiliary code of del_all_attrs/1
is this:
del_all_attrs(Var) :- ( var(V) -> put_atts(V, -clpz(_)), put_atts(V, -clpz_aux(_)), put_atts(V, -clpz_relation(_)), % ... a lot more put_atts/2 goals follow ... put_atts(V, -clpz_gcc_vs(_)), put_atts(V, -clpz_gcc_num(_)), put_atts(V, -clpz_gcc_occurred(_)) ; true ).
Now, following the steps of these two predicates is not that hard, but what effect does it all have for the involved variables and constraints?
The way I see it now the following happens:
Goal
is executed; this may (and usually does) include the propagation of constraints.- All attributes are removed from variables in
Vars
; this effectively leaves all non-aliased variables as free variables, but preserves variable aliasing and ground values. throw/3
creates a copy ofVars
and then undoes the effects of steps (1) and (2).catch/3
unifies the copy ofVars
with the originalVars
.- As a result all aliases and ground values that were present in
Vars
after the execution ofGoal
are "preserved", but all constraints are effectively reset. Execution resumes with waking some constraints by unifyingVars
with the "returned" copy.
Am I on the right way?
And can I express this without catch/3
, maybe by using copy_term/3
?