Generated on Tue Apr 18 10:21:41 2017 for Gecode by doxygen 1.6.3

eq.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2004
00008  *
00009  *  Last modified:
00010  *     $Date: 2016-11-08 17:23:24 +0100 (Tue, 08 Nov 2016) $ by $Author: schulte $
00011  *     $Revision: 15253 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 namespace Gecode { namespace Int { namespace Rel {
00039 
00040   /*
00041    * Binary value propagation equality
00042    *
00043    */
00044 
00045   template<class View0, class View1>
00046   forceinline
00047   EqVal<View0,View1>::EqVal(Home home, View0 x0, View1 x1)
00048     : MixBinaryPropagator<View0,PC_INT_VAL,View1,PC_INT_VAL>(home,x0,x1) {}
00049 
00050   template<class View0, class View1>
00051   ExecStatus
00052   EqVal<View0,View1>::post(Home home, View0 x0, View1 x1){
00053     if (x0.assigned()) {
00054       GECODE_ME_CHECK(x1.eq(home,x0.val()));
00055     } else if (x1.assigned()) {
00056       GECODE_ME_CHECK(x0.eq(home,x1.val()));
00057     } else if (!same(x0,x1)) {
00058       (void) new (home) EqVal<View0,View1>(home,x0,x1);
00059     }
00060     return ES_OK;
00061   }
00062 
00063   template<class View0, class View1>
00064   forceinline
00065   EqVal<View0,View1>::EqVal(Space& home, bool share, EqVal<View0,View1>& p)
00066     : MixBinaryPropagator<View0,PC_INT_VAL,View1,PC_INT_VAL>(home,share,p) {}
00067 
00068   template<class View0, class View1>
00069   forceinline
00070   EqVal<View0,View1>::EqVal(Space& home, bool share, Propagator& p,
00071                             View0 x0, View1 x1)
00072     : MixBinaryPropagator<View0,PC_INT_VAL,View1,PC_INT_VAL>(home,share,p,
00073                                                              x0,x1) {}
00074 
00075   template<class View0, class View1>
00076   Actor*
00077   EqVal<View0,View1>::copy(Space& home, bool share) {
00078     return new (home) EqVal<View0,View1>(home,share,*this);
00079   }
00080 
00081   template<class View0, class View1>
00082   PropCost
00083   EqVal<View0,View1>::cost(const Space&, const ModEventDelta&) const {
00084     return PropCost::unary(PropCost::LO);
00085   }
00086 
00087   template<class View0, class View1>
00088   ExecStatus
00089   EqVal<View0,View1>::propagate(Space& home, const ModEventDelta&) {
00090     if (x0.assigned()) {
00091       GECODE_ME_CHECK(x1.eq(home,x0.val()));
00092     } else {
00093       assert(x1.assigned());
00094       GECODE_ME_CHECK(x0.eq(home,x1.val()));
00095     }
00096     return home.ES_SUBSUMED(*this);
00097   }
00098 
00099 
00100   /*
00101    * Binary bounds consistent equality
00102    *
00103    */
00104 
00105   template<class View0, class View1>
00106   forceinline
00107   EqBnd<View0,View1>::EqBnd(Home home, View0 x0, View1 x1)
00108     : MixBinaryPropagator<View0,PC_INT_BND,View1,PC_INT_BND>(home,x0,x1) {}
00109 
00110   template<class View0, class View1>
00111   ExecStatus
00112   EqBnd<View0,View1>::post(Home home, View0 x0, View1 x1){
00113     if (x0.assigned()) {
00114       GECODE_ME_CHECK(x1.eq(home,x0.val()));
00115     } else if (x1.assigned()) {
00116       GECODE_ME_CHECK(x0.eq(home,x1.val()));
00117     } else if (!same(x0,x1)) {
00118       GECODE_ME_CHECK(x0.lq(home,x1.max()));
00119       GECODE_ME_CHECK(x1.lq(home,x0.max()));
00120       GECODE_ME_CHECK(x0.gq(home,x1.min()));
00121       GECODE_ME_CHECK(x1.gq(home,x0.min()));
00122       (void) new (home) EqBnd<View0,View1>(home,x0,x1);
00123     }
00124     return ES_OK;
00125   }
00126 
00127   template<class View0, class View1>
00128   forceinline
00129   EqBnd<View0,View1>::EqBnd(Space& home, bool share, EqBnd<View0,View1>& p)
00130     : MixBinaryPropagator<View0,PC_INT_BND,View1,PC_INT_BND>(home,share,p) {}
00131 
00132   template<class View0, class View1>
00133   forceinline
00134   EqBnd<View0,View1>::EqBnd(Space& home, bool share, Propagator& p,
00135                             View0 x0, View1 x1)
00136     : MixBinaryPropagator<View0,PC_INT_BND,View1,PC_INT_BND>(home,share,p,
00137                                                              x0,x1) {}
00138 
00139   template<class View0, class View1>
00140   Actor*
00141   EqBnd<View0,View1>::copy(Space& home, bool share) {
00142     return new (home) EqBnd<View0,View1>(home,share,*this);
00143   }
00144 
00145   template<class View0, class View1>
00146   ExecStatus
00147   EqBnd<View0,View1>::propagate(Space& home, const ModEventDelta&) {
00148     if (x0.assigned()) {
00149       GECODE_ME_CHECK(x1.eq(home,x0.val()));
00150     } else if (x1.assigned()) {
00151       GECODE_ME_CHECK(x0.eq(home,x1.val()));
00152     } else {
00153       do {
00154         GECODE_ME_CHECK(x0.gq(home,x1.min()));
00155         GECODE_ME_CHECK(x1.gq(home,x0.min()));
00156       } while (x0.min() != x1.min());
00157       do {
00158         GECODE_ME_CHECK(x0.lq(home,x1.max()));
00159         GECODE_ME_CHECK(x1.lq(home,x0.max()));
00160       } while (x0.max() != x1.max());
00161       if (!x0.assigned())
00162         return ES_FIX;
00163     }
00164     assert(x0.assigned() && x1.assigned());
00165     return home.ES_SUBSUMED(*this);
00166   }
00167 
00168   /*
00169    * Binary domain consistent equality
00170    *
00171    */
00172 
00173   template<class View0, class View1>
00174   forceinline
00175   EqDom<View0,View1>::EqDom(Home home, View0 x0, View1 x1)
00176     : MixBinaryPropagator<View0,PC_INT_DOM,View1,PC_INT_DOM>(home,x0,x1) {}
00177 
00178   template<class View0, class View1>
00179   ExecStatus
00180   EqDom<View0,View1>::post(Home home, View0 x0, View1 x1){
00181     if (x0.assigned()) {
00182       GECODE_ME_CHECK(x1.eq(home,x0.val()));
00183     } else if (x1.assigned()) {
00184       GECODE_ME_CHECK(x0.eq(home,x1.val()));
00185     } else if (!same(x0,x1)) {
00186       GECODE_ME_CHECK(x0.lq(home,x1.max()));
00187       GECODE_ME_CHECK(x1.lq(home,x0.max()));
00188       GECODE_ME_CHECK(x0.gq(home,x1.min()));
00189       GECODE_ME_CHECK(x1.gq(home,x0.min()));
00190       (void) new (home) EqDom<View0,View1>(home,x0,x1);
00191     }
00192     return ES_OK;
00193   }
00194 
00195 
00196   template<class View0, class View1>
00197   forceinline
00198   EqDom<View0,View1>::EqDom(Space& home, bool share, EqDom<View0,View1>& p)
00199     : MixBinaryPropagator<View0,PC_INT_DOM,View1,PC_INT_DOM>(home,share,p) {}
00200 
00201   template<class View0, class View1>
00202   forceinline
00203   EqDom<View0,View1>::EqDom(Space& home, bool share, Propagator& p,
00204                             View0 x0, View1 x1)
00205     : MixBinaryPropagator<View0,PC_INT_DOM,View1,PC_INT_DOM>(home,share,p,
00206                                                              x0,x1) {}
00207 
00208   template<class View0, class View1>
00209   Actor*
00210   EqDom<View0,View1>::copy(Space& home, bool share) {
00211     return new (home) EqDom<View0,View1>(home,share,*this);
00212   }
00213 
00214   template<class View0, class View1>
00215   PropCost
00216   EqDom<View0,View1>::cost(const Space&, const ModEventDelta& med) const {
00217     if ((View0::me(med) == ME_INT_VAL) || (View1::me(med) == ME_INT_VAL))
00218       return PropCost::unary(PropCost::LO);
00219     else if ((View0::me(med) == ME_INT_DOM) || (View1::me(med) == ME_INT_DOM))
00220       return PropCost::binary(PropCost::LO);
00221     else
00222       return PropCost::binary(PropCost::HI);
00223   }
00224 
00225   template<class View0, class View1>
00226   ExecStatus
00227   EqDom<View0,View1>::propagate(Space& home, const ModEventDelta& med) {
00228     if (x0.assigned()) {
00229       GECODE_ME_CHECK(x1.eq(home,x0.val()));
00230       return home.ES_SUBSUMED(*this);
00231     }
00232     if (x1.assigned()) {
00233       GECODE_ME_CHECK(x0.eq(home,x1.val()));
00234       return home.ES_SUBSUMED(*this);
00235     }
00236     if ((View0::me(med) != ME_INT_DOM) && (View1::me(med) != ME_INT_DOM)) {
00237       do {
00238         GECODE_ME_CHECK(x0.gq(home,x1.min()));
00239         GECODE_ME_CHECK(x1.gq(home,x0.min()));
00240       } while (x0.min() != x1.min());
00241       do {
00242         GECODE_ME_CHECK(x0.lq(home,x1.max()));
00243         GECODE_ME_CHECK(x1.lq(home,x0.max()));
00244       } while (x0.max() != x1.max());
00245       if (x0.assigned())
00246         return home.ES_SUBSUMED(*this);
00247       if (x0.range() && x1.range())
00248         return ES_FIX;
00249       return home.ES_FIX_PARTIAL(*this,View0::med(ME_INT_DOM));
00250     }
00251     ViewRanges<View0> r0(x0);
00252     GECODE_ME_CHECK(x1.inter_r(home,r0,shared(x0,x1)));
00253     ViewRanges<View1> r1(x1);
00254     GECODE_ME_CHECK(x0.narrow_r(home,r1,shared(x0,x1)));
00255     if (x0.assigned())
00256       return home.ES_SUBSUMED(*this);
00257     return ES_FIX;
00258   }
00259 
00260 
00261 
00262   /*
00263    * Nary domain consistent equality
00264    *
00265    */
00266 
00267   template<class View>
00268   forceinline
00269   NaryEqDom<View>::NaryEqDom(Home home, ViewArray<View>& x)
00270     : NaryPropagator<View,PC_INT_DOM>(home,x) {}
00271 
00272   template<class View>
00273   ExecStatus
00274   NaryEqDom<View>::post(Home home, ViewArray<View>& x) {
00275     x.unique(home);
00276     if (x.size() == 2) {
00277       return EqDom<View,View>::post(home,x[0],x[1]);
00278     } else if (x.size() > 2) {
00279       int l = x[0].min();
00280       int u = x[0].max();
00281       for (int i=x.size(); i-- > 1; ) {
00282         l = std::max(l,x[i].min());
00283         u = std::min(u,x[i].max());
00284       }
00285       for (int i=x.size(); i--; ) {
00286         GECODE_ME_CHECK(x[i].gq(home,l));
00287         GECODE_ME_CHECK(x[i].lq(home,u));
00288       }
00289       (void) new (home) NaryEqDom<View>(home,x);
00290     }
00291     return ES_OK;
00292   }
00293 
00294   template<class View>
00295   forceinline
00296   NaryEqDom<View>::NaryEqDom(Space& home, bool share, NaryEqDom<View>& p)
00297     : NaryPropagator<View,PC_INT_DOM>(home,share,p) {}
00298 
00299   template<class View>
00300   Actor*
00301   NaryEqDom<View>::copy(Space& home, bool share) {
00302     return new (home) NaryEqDom<View>(home,share,*this);
00303   }
00304 
00305   template<class View>
00306   PropCost
00307   NaryEqDom<View>::cost(const Space&, const ModEventDelta& med) const {
00308     if (View::me(med) == ME_INT_VAL)
00309       return PropCost::unary(PropCost::LO);
00310     else
00311       return PropCost::linear((View::me(med) == ME_INT_DOM) ?
00312                               PropCost::LO : PropCost::HI, x.size());
00313   }
00314 
00315   template<class View>
00316   ExecStatus
00317   NaryEqDom<View>::propagate(Space& home, const ModEventDelta& med) {
00318     assert(x.size() > 2);
00319 
00320     ModEvent me = View::me(med);
00321     if (me == ME_INT_VAL) {
00322       // One of the variables is assigned
00323       for (int i = 0; ; i++)
00324         if (x[i].assigned()) {
00325           int n = x[i].val();
00326           x.move_lst(i);
00327           for (int j = x.size(); j--; )
00328             GECODE_ME_CHECK(x[j].eq(home,n));
00329           return home.ES_SUBSUMED(*this);
00330         }
00331       GECODE_NEVER;
00332     }
00333 
00334     if (me == ME_INT_BND) {
00335       {
00336         // One of the mins has changed
00337         int mn = x[0].min();
00338       restart_min:
00339         for (int i = x.size(); i--; ) {
00340           GECODE_ME_CHECK(x[i].gq(home,mn));
00341           if (mn < x[i].min()) {
00342             mn = x[i].min();
00343             goto restart_min;
00344           }
00345         }
00346       }
00347       {
00348         // One of the maxs has changed
00349         int mx = x[0].max();
00350       restart_max:
00351         for (int i = x.size(); i--; ) {
00352           GECODE_ME_CHECK(x[i].lq(home,mx));
00353           if (mx > x[i].max()) {
00354             mx = x[i].max();
00355             goto restart_max;
00356           }
00357         }
00358       }
00359       if (x[0].assigned())
00360         return home.ES_SUBSUMED(*this);
00361       return home.ES_FIX_PARTIAL(*this,View::med(ME_INT_DOM));
00362     }
00363 
00364     int n = x.size();
00365 
00366     Region re(home);
00367     ViewRanges<View>* i_x = re.alloc<ViewRanges<View> >(n);
00368     for (int i = n; i--; ) {
00369       ViewRanges<View> i_xi(x[i]);
00370       i_x[i] = i_xi;
00371     }
00372     Iter::Ranges::NaryInter r(re,i_x,n);
00373 
00374     if (!r())
00375       return ES_FAILED;
00376     ++r;
00377     if (!r()) {
00378       r.reset();
00379       for (int i = n; i--; ) {
00380         GECODE_ME_CHECK(x[i].gq(home,r.min()));
00381         GECODE_ME_CHECK(x[i].lq(home,r.max()));
00382       }
00383     } else {
00384       for (int i = n; i--; ) {
00385         r.reset();
00386         GECODE_ME_CHECK(x[i].narrow_r(home,r,false));
00387       }
00388     }
00389     return ES_FIX;
00390   }
00391 
00392 
00393 
00394   /*
00395    * Nary bound consistent equality
00396    *
00397    */
00398 
00399   template<class View>
00400   forceinline
00401   NaryEqBnd<View>::NaryEqBnd(Home home, ViewArray<View>& x)
00402     : NaryPropagator<View,PC_INT_BND>(home,x) {}
00403 
00404   template<class View>
00405   ExecStatus
00406   NaryEqBnd<View>::post(Home home, ViewArray<View>& x) {
00407     x.unique(home);
00408     if (x.size() == 2) {
00409       return EqBnd<View,View>::post(home,x[0],x[1]);
00410     } else if (x.size() > 2) {
00411       int l = x[0].min();
00412       int u = x[0].max();
00413       for (int i=x.size(); i-- > 1; ) {
00414         l = std::max(l,x[i].min());
00415         u = std::min(u,x[i].max());
00416       }
00417       for (int i=x.size(); i--; ) {
00418         GECODE_ME_CHECK(x[i].gq(home,l));
00419         GECODE_ME_CHECK(x[i].lq(home,u));
00420       }
00421       (void) new (home) NaryEqBnd<View>(home,x);
00422     }
00423     return ES_OK;
00424   }
00425 
00426   template<class View>
00427   forceinline
00428   NaryEqBnd<View>::NaryEqBnd(Space& home, bool share, NaryEqBnd<View>& p)
00429     : NaryPropagator<View,PC_INT_BND>(home,share,p) {}
00430 
00431   template<class View>
00432   Actor*
00433   NaryEqBnd<View>::copy(Space& home, bool share) {
00434     return new (home) NaryEqBnd<View>(home,share,*this);
00435   }
00436 
00437   template<class View>
00438   PropCost
00439   NaryEqBnd<View>::cost(const Space&, const ModEventDelta& med) const {
00440     if (View::me(med) == ME_INT_VAL)
00441       return PropCost::unary(PropCost::LO);
00442     else
00443       return PropCost::linear(PropCost::LO, x.size());
00444   }
00445 
00446   template<class View>
00447   ExecStatus
00448   NaryEqBnd<View>::propagate(Space& home, const ModEventDelta& med) {
00449     assert(x.size() > 2);
00450     if (View::me(med) == ME_INT_VAL) {
00451       // One of the variables is assigned
00452       for (int i = 0; ; i++)
00453         if (x[i].assigned()) {
00454           int n = x[i].val();
00455           x.move_lst(i);
00456           for (int j = x.size(); j--; )
00457             GECODE_ME_CHECK(x[j].eq(home,n));
00458           return home.ES_SUBSUMED(*this);
00459         }
00460       GECODE_NEVER;
00461     }
00462 
00463     int mn = x[0].min();
00464   restart_min:
00465     for (int i = x.size(); i--; ) {
00466       GECODE_ME_CHECK(x[i].gq(home,mn));
00467       if (mn < x[i].min()) {
00468         mn = x[i].min();
00469         goto restart_min;
00470       }
00471     }
00472     int mx = x[0].max();
00473   restart_max:
00474     for (int i = x.size(); i--; ) {
00475       GECODE_ME_CHECK(x[i].lq(home,mx));
00476       if (mx > x[i].max()) {
00477         mx = x[i].max();
00478         goto restart_max;
00479       }
00480     }
00481     return x[0].assigned() ? home.ES_SUBSUMED(*this) : ES_FIX;
00482   }
00483 
00484 
00485 
00486   /*
00487    * Reified domain consistent equality
00488    *
00489    */
00490 
00491   template<class View, class CtrlView, ReifyMode rm>
00492   forceinline
00493   ReEqDom<View,CtrlView,rm>::ReEqDom(Home home, View x0, View x1, CtrlView b)
00494     : ReBinaryPropagator<View,PC_INT_DOM,CtrlView>(home,x0,x1,b) {}
00495 
00496   template<class View, class CtrlView, ReifyMode rm>
00497   ExecStatus
00498   ReEqDom<View,CtrlView,rm>::post(Home home, View x0, View x1, CtrlView b) {
00499     if (b.one()) {
00500       if (rm == RM_PMI)
00501         return ES_OK;
00502       return EqDom<View,View>::post(home,x0,x1);
00503     }
00504     if (b.zero()) {
00505       if (rm == RM_IMP)
00506         return ES_OK;
00507       return Nq<View,View>::post(home,x0,x1);
00508     }
00509     if (!same(x0,x1)) {
00510       (void) new (home) ReEqDom(home,x0,x1,b);
00511     } else if (rm != RM_IMP) {
00512       GECODE_ME_CHECK(b.one(home));
00513     }
00514     return ES_OK;
00515   }
00516 
00517 
00518   template<class View, class CtrlView, ReifyMode rm>
00519   forceinline
00520   ReEqDom<View,CtrlView,rm>::ReEqDom(Space& home, bool share, ReEqDom& p)
00521     : ReBinaryPropagator<View,PC_INT_DOM,CtrlView>(home,share,p) {}
00522 
00523   template<class View, class CtrlView, ReifyMode rm>
00524   Actor*
00525   ReEqDom<View,CtrlView,rm>::copy(Space& home, bool share) {
00526     return new (home) ReEqDom<View,CtrlView,rm>(home,share,*this);
00527   }
00528 
00529   template<class View, class CtrlView, ReifyMode rm>
00530   ExecStatus
00531   ReEqDom<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) {
00532     if (b.one()) {
00533       if (rm == RM_PMI)
00534         return home.ES_SUBSUMED(*this);
00535       GECODE_REWRITE(*this,(EqDom<View,View>::post(home(*this),x0,x1)));
00536     }
00537     if (b.zero()) {
00538       if (rm == RM_IMP)
00539         return home.ES_SUBSUMED(*this);
00540       GECODE_REWRITE(*this,(Nq<View,View>::post(home(*this),x0,x1)));
00541     }
00542     switch (rtest_eq_dom(x0,x1)) {
00543     case RT_TRUE:
00544       if (rm != RM_IMP)
00545         GECODE_ME_CHECK(b.one_none(home));
00546       break;
00547     case RT_FALSE:
00548       if (rm != RM_PMI)
00549         GECODE_ME_CHECK(b.zero_none(home));
00550       break;
00551     case RT_MAYBE:
00552       return ES_FIX;
00553     default: GECODE_NEVER;
00554     }
00555     return home.ES_SUBSUMED(*this);
00556   }
00557 
00558 
00559 
00560   /*
00561    * Reified bounds consistent equality
00562    *
00563    */
00564 
00565   template<class View, class CtrlView, ReifyMode rm>
00566   forceinline
00567   ReEqBnd<View,CtrlView,rm>::ReEqBnd(Home home, View x0, View x1, CtrlView b)
00568     : ReBinaryPropagator<View,PC_INT_BND,CtrlView>(home,x0,x1,b) {}
00569 
00570   template<class View, class CtrlView, ReifyMode rm>
00571   ExecStatus
00572   ReEqBnd<View,CtrlView,rm>::post(Home home, View x0, View x1, CtrlView b){
00573     if (b.one()) {
00574       if (rm == RM_PMI)
00575         return ES_OK;
00576       return EqBnd<View,View>::post(home,x0,x1);
00577     }
00578     if (b.zero()) {
00579       if (rm == RM_IMP)
00580         return ES_OK;
00581       return Nq<View,View>::post(home,x0,x1);
00582     }
00583     if (!same(x0,x1)) {
00584       (void) new (home) ReEqBnd(home,x0,x1,b);
00585     } else if (rm != RM_IMP) {
00586       GECODE_ME_CHECK(b.one(home));
00587     }
00588     return ES_OK;
00589   }
00590 
00591 
00592   template<class View, class CtrlView, ReifyMode rm>
00593   forceinline
00594   ReEqBnd<View,CtrlView,rm>::ReEqBnd(Space& home, bool share, ReEqBnd& p)
00595     : ReBinaryPropagator<View,PC_INT_BND,CtrlView>(home,share,p) {}
00596 
00597   template<class View, class CtrlView, ReifyMode rm>
00598   Actor*
00599   ReEqBnd<View,CtrlView,rm>::copy(Space& home, bool share) {
00600     return new (home) ReEqBnd<View,CtrlView,rm>(home,share,*this);
00601   }
00602 
00603   template<class View, class CtrlView, ReifyMode rm>
00604   ExecStatus
00605   ReEqBnd<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) {
00606     if (b.one()) {
00607       if (rm == RM_PMI)
00608         return home.ES_SUBSUMED(*this);
00609       GECODE_REWRITE(*this,(EqBnd<View,View>::post(home(*this),x0,x1)));
00610     }
00611     if (b.zero()) {
00612       if (rm == RM_IMP)
00613         return home.ES_SUBSUMED(*this);
00614       GECODE_REWRITE(*this,(Nq<View,View>::post(home(*this),x0,x1)));
00615     }
00616     switch (rtest_eq_bnd(x0,x1)) {
00617     case RT_TRUE:
00618       if (rm != RM_IMP)
00619         GECODE_ME_CHECK(b.one_none(home));
00620       break;
00621     case RT_FALSE:
00622       if (rm != RM_PMI)
00623         GECODE_ME_CHECK(b.zero_none(home));
00624       break;
00625     case RT_MAYBE:
00626       return ES_FIX;
00627     default: GECODE_NEVER;
00628     }
00629     return home.ES_SUBSUMED(*this);
00630   }
00631 
00632 
00633 
00634 
00635   /*
00636    * Reified domain consistent equality (one variable)
00637    *
00638    */
00639 
00640   template<class View, class CtrlView, ReifyMode rm>
00641   forceinline
00642   ReEqDomInt<View,CtrlView,rm>::ReEqDomInt
00643   (Home home, View x, int c0, CtrlView b)
00644     : ReUnaryPropagator<View,PC_INT_DOM,CtrlView>(home,x,b), c(c0) {}
00645 
00646   template<class View, class CtrlView, ReifyMode rm>
00647   ExecStatus
00648   ReEqDomInt<View,CtrlView,rm>::post(Home home, View x, int c, CtrlView b) {
00649     if (b.one()) {
00650       if (rm != RM_PMI)
00651         GECODE_ME_CHECK(x.eq(home,c));
00652     } else if (b.zero()) {
00653       if (rm != RM_IMP)
00654         GECODE_ME_CHECK(x.nq(home,c));
00655     } else if (x.assigned()) {
00656       assert(b.none());
00657       if (x.val() == c) {
00658         if (rm != RM_IMP)
00659           GECODE_ME_CHECK(b.one_none(home));
00660       } else {
00661         if (rm != RM_PMI)
00662           GECODE_ME_CHECK(b.zero_none(home));
00663       }
00664     } else {
00665       (void) new (home) ReEqDomInt(home,x,c,b);
00666     }
00667     return ES_OK;
00668   }
00669 
00670 
00671   template<class View, class CtrlView, ReifyMode rm>
00672   forceinline
00673   ReEqDomInt<View,CtrlView,rm>::ReEqDomInt(Space& home, bool share,
00674                                            ReEqDomInt& p)
00675     : ReUnaryPropagator<View,PC_INT_DOM,CtrlView>(home,share,p), c(p.c) {}
00676 
00677   template<class View, class CtrlView, ReifyMode rm>
00678   Actor*
00679   ReEqDomInt<View,CtrlView,rm>::copy(Space& home, bool share) {
00680     return new (home) ReEqDomInt<View,CtrlView,rm>(home,share,*this);
00681   }
00682 
00683   template<class View, class CtrlView, ReifyMode rm>
00684   ExecStatus
00685   ReEqDomInt<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) {
00686     if (b.one()) {
00687       if (rm != RM_PMI)
00688         GECODE_ME_CHECK(x0.eq(home,c));
00689     } else if (b.zero()) {
00690       if (rm != RM_IMP)
00691         GECODE_ME_CHECK(x0.nq(home,c));
00692     } else {
00693       switch (rtest_eq_dom(x0,c)) {
00694       case RT_TRUE:
00695         if (rm != RM_IMP)
00696           GECODE_ME_CHECK(b.one_none(home));
00697         break;
00698       case RT_FALSE:
00699         if (rm != RM_PMI)
00700           GECODE_ME_CHECK(b.zero_none(home));
00701         break;
00702       case RT_MAYBE:
00703         return ES_FIX;
00704       default: GECODE_NEVER;
00705       }
00706     }
00707     return home.ES_SUBSUMED(*this);
00708   }
00709 
00710 
00711 
00712 
00713   /*
00714    * Reified bounds consistent equality (one variable)
00715    *
00716    */
00717 
00718   template<class View, class CtrlView, ReifyMode rm>
00719   forceinline
00720   ReEqBndInt<View,CtrlView,rm>::ReEqBndInt
00721   (Home home, View x, int c0, CtrlView b)
00722     : ReUnaryPropagator<View,PC_INT_BND,CtrlView>(home,x,b), c(c0) {}
00723 
00724   template<class View, class CtrlView, ReifyMode rm>
00725   ExecStatus
00726   ReEqBndInt<View,CtrlView,rm>::post(Home home, View x, int c, CtrlView b) {
00727     if (b.one()) {
00728       if (rm != RM_PMI)
00729         GECODE_ME_CHECK(x.eq(home,c));
00730     } else if (b.zero()) {
00731       if (rm != RM_IMP)
00732         GECODE_ME_CHECK(x.nq(home,c));
00733     } else if (x.assigned()) {
00734       assert(b.none());
00735       if (x.val() == c) {
00736         if (rm != RM_IMP)
00737           GECODE_ME_CHECK(b.one_none(home));
00738       } else {
00739         if (rm != RM_PMI)
00740           GECODE_ME_CHECK(b.zero_none(home));
00741       }
00742     } else {
00743       (void) new (home) ReEqBndInt(home,x,c,b);
00744     }
00745     return ES_OK;
00746   }
00747 
00748 
00749   template<class View, class CtrlView, ReifyMode rm>
00750   forceinline
00751   ReEqBndInt<View,CtrlView,rm>::ReEqBndInt(Space& home, bool share, ReEqBndInt& p)
00752     : ReUnaryPropagator<View,PC_INT_BND,CtrlView>(home,share,p), c(p.c) {}
00753 
00754   template<class View, class CtrlView, ReifyMode rm>
00755   Actor*
00756   ReEqBndInt<View,CtrlView,rm>::copy(Space& home, bool share) {
00757     return new (home) ReEqBndInt<View,CtrlView,rm>(home,share,*this);
00758   }
00759 
00760   template<class View, class CtrlView, ReifyMode rm>
00761   ExecStatus
00762   ReEqBndInt<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) {
00763     if (b.one()) {
00764       if (rm != RM_PMI)
00765         GECODE_ME_CHECK(x0.eq(home,c));
00766     } else if (b.zero()) {
00767       if (rm != RM_IMP)
00768         GECODE_ME_CHECK(x0.nq(home,c));
00769     } else {
00770       switch (rtest_eq_bnd(x0,c)) {
00771       case RT_TRUE:
00772         if (rm != RM_IMP)
00773           GECODE_ME_CHECK(b.one_none(home));
00774         break;
00775       case RT_FALSE:
00776         if (rm != RM_PMI)
00777           GECODE_ME_CHECK(b.zero_none(home));
00778         break;
00779       case RT_MAYBE:
00780         return ES_FIX;
00781       default: GECODE_NEVER;
00782       }
00783     }
00784     return home.ES_SUBSUMED(*this);
00785   }
00786 
00787 }}}
00788 
00789 // STATISTICS: int-prop