]> Repositorios git - scryer-prolog.git/commitdiff
FIXED: CLP(ℤ): Correctly remove all attributes during propagation of all_distinct...
authorMarkus Triska <[email protected]>
Mon, 24 Oct 2022 17:18:49 +0000 (19:18 +0200)
committerMark Thom <[email protected]>
Thu, 27 Oct 2022 05:36:07 +0000 (23:36 -0600)
The constraints from library(clpz) were already correctly removed, but
others such as pending freeze/2 goals were not, potentially leading to
an accumulation of redundant constraints during propagation.

Test case:

   ?- freeze(A,(X=1;X=2)), all_distinct([A]), A = 1.
      A = 1, X = 1
   ;  A = 1, X = 2.

The combination of freeze/2 and CLP(ℤ) is useful for example when
creating animations of search processes.

This addresses #1624.

src/lib/clpz.pl

index 466180323b1991f0cd6ba7b493688d32be33cfa8..2734a683981974eea99c572c618873f4ccaf3061 100644 (file)
@@ -6112,55 +6112,22 @@ put_free(F) :- put_attr(F, free, true).
 
 free_node(F) :- get_attr(F, free, true).
 
-del_vars_attr(Vars, Attr) :- maplist(del_attr(Attr), Vars).
-
-%del_attr_(Attr, Var) :- del_attr(Var, Attr).
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-  This needs to be spelt out.
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-% del_attr_(edges, Var)    :- del_attr(Var, edges).
-% del_attr_(parent, Var)   :- del_attr(Var, parent).
-% del_attr_(g0_edges, Var) :- del_attr(Var, g0_edges).
-% del_attr_(index, Var)    :- del_attr(Var, index).
-% del_attr_(visited, Var)  :- del_attr(Var, visited).
-
-del_all_attrs(Var) :-
-        (   var(Var) ->
-            Atts = [clpz,
-                    clpz_aux,
-                    clpz_relation,
-                    edges,
-                    flow,
-                    parent,
-                    free,
-                    g0_edges,
-                    used,
-                    lowlink,
-                    value,
-                    visited,
-                    index,
-                    in_stack,
-                    clpz_gcc_vs,
-                    clpz_gcc_num,
-                    clpz_gcc_occurred],
-            maplist(remove_attr(Var), Atts)
-        ;   true
-        ).
-
-remove_attr(Var, Attr) :-
-        functor(Term, Attr, 1),
-        put_atts(Var, -Term).
-
 :- meta_predicate with_local_attributes(?, 0, ?).
 
+:- dynamic(nat_copy/1).
+
 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),
+               % Create a copy where all attributes are removed. Only
+               % the result and its relation to Vars matters. We throw
+               % an exception to undo all modifications to attributes
+               % we made during propagation, and unify the variables
+               % in the thrown copy with Vars in order to get the
+               % intended variables in Result.
+               asserta(nat_copy(Vars-Result)),
+               retract(nat_copy(Copy)),
+               throw(local_attributes(Copy))),
+              local_attributes(Vars-Result),
               true).
 
 distinct(Vars) -->