Generated on Wed Nov 1 15:04:46 2006 for Gecode by doxygen 1.4.5

re-eq.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Guido Tack <tack@gecode.org>
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Bugfixes provided by:
00007  *     Grégoire Dooms <dooms@info.ucl.ac.be>
00008  *
00009  *  Copyright:
00010  *     Guido Tack, 2004
00011  *     Christian Schulte, 2004
00012  *
00013  *  Last modified:
00014  *     $Date: 2006-05-29 09:42:21 +0200 (Mon, 29 May 2006) $ by $Author: schulte $
00015  *     $Revision: 3246 $
00016  *
00017  *  This file is part of Gecode, the generic constraint
00018  *  development environment:
00019  *     http://www.gecode.org
00020  *
00021  *  See the file "LICENSE" for information on usage and
00022  *  redistribution of this file, and for a
00023  *     DISCLAIMER OF ALL WARRANTIES.
00024  *
00025  */
00026 
00027 namespace Gecode { namespace Set { namespace Rel {
00028 
00029   template <class View0, class View1>
00030   forceinline
00031   ReEq<View0,View1>::ReEq(Space* home, View0 y0, View1 y1,
00032                           Gecode::Int::BoolView y2)
00033     : Propagator(home), x0(y0), x1(y1), b(y2) {
00034     b.subscribe(home,this, Gecode::Int::PC_INT_VAL);
00035     x0.subscribe(home,this, PC_SET_ANY);
00036     x1.subscribe(home,this, PC_SET_ANY);
00037   }
00038 
00039   template <class View0, class View1>
00040   forceinline
00041   ReEq<View0,View1>::ReEq(Space* home, bool share, ReEq& p)
00042     : Propagator(home,share,p) {
00043     x0.update(home,share,p.x0);
00044     x1.update(home,share,p.x1);
00045     b.update(home,share,p.b);
00046   }
00047 
00048   template <class View0, class View1>
00049   PropCost
00050   ReEq<View0,View1>::cost(void) const {
00051     return PC_TERNARY_LO;
00052   }
00053 
00054   template <class View0, class View1>
00055   size_t
00056   ReEq<View0,View1>::dispose(Space* home) {
00057     assert(!home->failed());
00058     b.cancel(home,this, Gecode::Int::PC_INT_VAL);
00059     x0.cancel(home,this, PC_SET_ANY);
00060     x1.cancel(home,this, PC_SET_ANY);
00061     (void) Propagator::dispose(home);
00062     return sizeof(*this);
00063   }
00064 
00065   template <class View0, class View1>
00066   ExecStatus
00067   ReEq<View0,View1>::post(Space* home, View0 x0, View1 x1,
00068                             Gecode::Int::BoolView b) {
00069     (void) new (home) ReEq<View0,View1>(home,x0,x1,b);
00070     return ES_OK;
00071   }
00072 
00073   template <class View0, class View1>
00074   Actor*
00075   ReEq<View0,View1>::copy(Space* home, bool share) {
00076     return new (home) ReEq<View0,View1>(home,share,*this);
00077   }
00078 
00079   template <class View0, class View1>
00080   ExecStatus
00081   ReEq<View0,View1>::propagate(Space* home) {
00082 
00083     if (b.one()) {
00084       GECODE_ES_CHECK((Eq<View0,View1>::post(home,x0,x1)));
00085       return ES_SUBSUMED;
00086     }
00087     if (b.zero()) {
00088       GECODE_ES_CHECK((Distinct<View0,View1>::post(home,x0,x1)));
00089       return ES_SUBSUMED;
00090     }
00091 
00092     if (x0.assigned() && x1.assigned()) {
00093       // directly test x0==x1
00094       GlbRanges<View0> x0lb(x0);
00095       GlbRanges<View1> x1lb(x1);
00096       for (; x0lb() && x1lb(); ++x0lb, ++x1lb) {
00097         if (x0lb.min() != x1lb.min() ||
00098             x0lb.max() != x1lb.max()) {
00099           b.t_zero_none(home);
00100           return ES_SUBSUMED;
00101         }
00102       }
00103       if (!x0lb() && !x1lb()) {
00104         b.t_one_none(home);
00105         return ES_SUBSUMED;
00106       } else {
00107         b.t_zero_none(home);
00108         return ES_SUBSUMED;
00109       }
00110     }
00111 
00112     // check whether cardinalities still allow equality
00113     if (x0.cardMin() > x1.cardMax() ||
00114         x1.cardMin() > x0.cardMax()) {
00115       b.t_zero_none(home);
00116       return ES_SUBSUMED;
00117     }
00118 
00119     // check glb(x0) subset lub(x1)
00120     GlbRanges<View0> x0lb(x0);
00121     LubRanges<View1> x1ub(x1);
00122     Iter::Ranges::Diff<GlbRanges<View0>, LubRanges<View1> > diff1(x0lb, x1ub);
00123     if ( diff1() ) {
00124       b.t_zero_none(home);
00125       return ES_SUBSUMED;
00126     }
00127 
00128     // check glb(x1) subset lub(x0)
00129     GlbRanges<View1> x1lb(x1);
00130     LubRanges<View0> x0ub(x0);
00131     Iter::Ranges::Diff<GlbRanges<View1>, LubRanges<View0> > diff2(x1lb, x0ub);
00132     if ( diff2() ) {
00133       b.t_zero_none(home);
00134       return ES_SUBSUMED;
00135     }
00136 
00137     return ES_FIX;
00138   }
00139 
00140 }}}
00141 
00142 // STATISTICS: set-prop