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.
This commit is contained in:
@@ -6112,55 +6112,22 @@ put_free(F) :- put_attr(F, free, true).
|
|||||||
|
|
||||||
free_node(F) :- get_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, ?).
|
:- meta_predicate with_local_attributes(?, 0, ?).
|
||||||
|
|
||||||
|
:- dynamic(nat_copy/1).
|
||||||
|
|
||||||
with_local_attributes(Vars, Goal, Result) :-
|
with_local_attributes(Vars, Goal, Result) :-
|
||||||
catch((Goal,
|
catch((Goal,
|
||||||
maplist(del_all_attrs, Vars),
|
% Create a copy where all attributes are removed. Only
|
||||||
% reset all attributes, only the result matters
|
% the result and its relation to Vars matters. We throw
|
||||||
throw(local_attributes(Result,Vars))),
|
% an exception to undo all modifications to attributes
|
||||||
local_attributes(Result,Vars),
|
% 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).
|
true).
|
||||||
|
|
||||||
distinct(Vars) -->
|
distinct(Vars) -->
|
||||||
|
|||||||
Reference in New Issue
Block a user