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