From: Markus Triska Date: Mon, 24 Oct 2022 17:18:49 +0000 (+0200) Subject: FIXED: CLP(ℤ): Correctly remove all attributes during propagation of all_distinct... X-Git-Tag: v0.9.1^2~4 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=d91ee5b77cf77d701f215a126bbd3f6433bd5da7;p=scryer-prolog.git FIXED: CLP(ℤ): Correctly remove all attributes during propagation of all_distinct/1 and other global constraints. 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. --- diff --git a/src/lib/clpz.pl b/src/lib/clpz.pl index 46618032..2734a683 100644 --- a/src/lib/clpz.pl +++ b/src/lib/clpz.pl @@ -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) -->