/* * Main authors: * Guido Tack * Christian Schulte * * Bugfixes provided by: * Grégoire Dooms * * Copyright: * Guido Tack, 2004 * Christian Schulte, 2004 * * Last modified: * $Date: 2006-05-29 09:42:21 +0200 (Mon, 29 May 2006) $ by $Author: schulte $ * $Revision: 3246 $ * * This file is part of Gecode, the generic constraint * development environment: * http://www.gecode.org * * See the file "LICENSE" for information on usage and * redistribution of this file, and for a * DISCLAIMER OF ALL WARRANTIES. * */ namespace Gecode { namespace Set { namespace Rel { template forceinline ReEq::ReEq(Space* home, View0 y0, View1 y1, Gecode::Int::BoolView y2) : Propagator(home), x0(y0), x1(y1), b(y2) { b.subscribe(home,this, Gecode::Int::PC_INT_VAL); x0.subscribe(home,this, PC_SET_ANY); x1.subscribe(home,this, PC_SET_ANY); } template forceinline ReEq::ReEq(Space* home, bool share, ReEq& p) : Propagator(home,share,p) { x0.update(home,share,p.x0); x1.update(home,share,p.x1); b.update(home,share,p.b); } template PropCost ReEq::cost(void) const { return PC_TERNARY_LO; } template size_t ReEq::dispose(Space* home) { assert(!home->failed()); b.cancel(home,this, Gecode::Int::PC_INT_VAL); x0.cancel(home,this, PC_SET_ANY); x1.cancel(home,this, PC_SET_ANY); (void) Propagator::dispose(home); return sizeof(*this); } template ExecStatus ReEq::post(Space* home, View0 x0, View1 x1, Gecode::Int::BoolView b) { (void) new (home) ReEq(home,x0,x1,b); return ES_OK; } template Actor* ReEq::copy(Space* home, bool share) { return new (home) ReEq(home,share,*this); } template ExecStatus ReEq::propagate(Space* home) { if (b.one()) { GECODE_ES_CHECK((Eq::post(home,x0,x1))); return ES_SUBSUMED; } if (b.zero()) { GECODE_ES_CHECK((Distinct::post(home,x0,x1))); return ES_SUBSUMED; } if (x0.assigned() && x1.assigned()) { // directly test x0==x1 GlbRanges x0lb(x0); GlbRanges x1lb(x1); for (; x0lb() && x1lb(); ++x0lb, ++x1lb) { if (x0lb.min() != x1lb.min() || x0lb.max() != x1lb.max()) { b.t_zero_none(home); return ES_SUBSUMED; } } if (!x0lb() && !x1lb()) { b.t_one_none(home); return ES_SUBSUMED; } else { b.t_zero_none(home); return ES_SUBSUMED; } } // check whether cardinalities still allow equality if (x0.cardMin() > x1.cardMax() || x1.cardMin() > x0.cardMax()) { b.t_zero_none(home); return ES_SUBSUMED; } // check glb(x0) subset lub(x1) GlbRanges x0lb(x0); LubRanges x1ub(x1); Iter::Ranges::Diff, LubRanges > diff1(x0lb, x1ub); if ( diff1() ) { b.t_zero_none(home); return ES_SUBSUMED; } // check glb(x1) subset lub(x0) GlbRanges x1lb(x1); LubRanges x0ub(x0); Iter::Ranges::Diff, LubRanges > diff2(x1lb, x0ub); if ( diff2() ) { b.t_zero_none(home); return ES_SUBSUMED; } return ES_FIX; } }}} // STATISTICS: set-prop