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).
|
||||
|
||||
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) -->
|
||||
|
||||
Reference in New Issue
Block a user