2

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:

  1. Goal is executed; this may (and usually does) include the propagation of constraints.
  2. 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.
  3. throw/3 creates a copy of Vars and then undoes the effects of steps (1) and (2).
  4. catch/3 unifies the copy of Vars with the original Vars.
  5. As a result all aliases and ground values that were present in Vars after the execution of Goal are "preserved", but all constraints are effectively reset. Execution resumes with waking some constraints by unifying Vars with the "returned" copy.

Am I on the right way? And can I express this without catch/3, maybe by using copy_term/3?

false
  • 10,264
  • 13
  • 101
  • 209
repeat
  • 18,496
  • 4
  • 54
  • 166
  • 2
    So this is about Scryer too, right? – false Feb 09 '23 at 19:46
  • 1
    @false. I'm working with the sources that work on SICStus and I don't know about the details of the modified version of clp(Z) for Scryer Prolog. A quick glance tells me the two variants are not identical in this respect. Ideally, yes, all improvements of clp(Z) that I care about (including this one) should benefit all SICStus style systems. – repeat Feb 09 '23 at 21:02
  • @false. I am tuning a variant of clp(Z) on SICStus. I run exactly the same code on MI-Prolog (with varying, but growing success). I'm not interested in any kind of divergence in this matter. – repeat Feb 09 '23 at 21:05
  • 1
    Minor: This `Result` variable is a bit problematic (regardless of atvs) because there are implementations like SWI and IF that produce an error for `?- catch((X=a,throw(-b)),-X,true).` when they should answer `X = b`. – false Feb 11 '23 at 08:08
  • 1
    @false. Luckily, MI answers `X = b`:) – repeat Feb 12 '23 at 18:05

0 Answers0