Generated on Thu Apr 11 13:59:05 2019 for Gecode by doxygen 1.6.3

or.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 Bool {
00035 
00037   template<class BV>
00038   class OrTrueSubsumed : public BoolBinary<BV,BV> {
00039   protected:
00040     using BoolBinary<BV,BV>::x0;
00041     using BoolBinary<BV,BV>::x1;
00043     OrTrueSubsumed(Space& home, OrTrueSubsumed& p);
00045     static ExecStatus post(Home home, BV b0, BV b1);
00046   public:
00048     OrTrueSubsumed(Home home, BV b0, BV b1);
00050     OrTrueSubsumed(Space& home, Propagator& p,
00051                    BV b0, BV b1);
00053     virtual Actor* copy(Space& home);
00055     virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00056   };
00057 
00058   template<class BV>
00059   forceinline
00060   OrTrueSubsumed<BV>::OrTrueSubsumed
00061   (Home home, BV b0, BV b1)
00062     : BoolBinary<BV,BV>(home,b0,b1) {}
00063 
00064   template<class BV>
00065   forceinline ExecStatus
00066   OrTrueSubsumed<BV>::post(Home home, BV b0, BV b1) {
00067     (void) new (home) OrTrueSubsumed(home,b0,b1);
00068     return ES_OK;
00069   }
00070 
00071   template<class BV>
00072   forceinline
00073   OrTrueSubsumed<BV>::OrTrueSubsumed
00074   (Space& home, OrTrueSubsumed<BV>& p)
00075     : BoolBinary<BV,BV>(home,p) {}
00076 
00077   template<class BV>
00078   forceinline
00079   OrTrueSubsumed<BV>::OrTrueSubsumed(Space& home, Propagator& p,
00080                                      BV b0, BV b1)
00081     : BoolBinary<BV,BV>(home,p,b0,b1) {}
00082 
00083   template<class BV>
00084   Actor*
00085   OrTrueSubsumed<BV>::copy(Space& home) {
00086     return new (home) OrTrueSubsumed<BV>(home,*this);
00087   }
00088 
00089   template<class BV>
00090   ExecStatus
00091   OrTrueSubsumed<BV>::propagate(Space& home, const ModEventDelta&) {
00092     return home.ES_SUBSUMED(*this);
00093   }
00094 
00095 
00096   /*
00097    * Binary Boolean disjunction propagator (true)
00098    *
00099    */
00100 
00101   template<class BVA, class BVB>
00102   forceinline
00103   BinOrTrue<BVA,BVB>::BinOrTrue(Home home, BVA b0, BVB b1)
00104     : BoolBinary<BVA,BVB>(home,b0,b1) {}
00105 
00106   template<class BVA, class BVB>
00107   forceinline
00108   BinOrTrue<BVA,BVB>::BinOrTrue(Space& home, BinOrTrue<BVA,BVB>& p)
00109     : BoolBinary<BVA,BVB>(home,p) {}
00110 
00111   template<class BVA, class BVB>
00112   forceinline
00113   BinOrTrue<BVA,BVB>::BinOrTrue(Space& home, Propagator& p,
00114                               BVA b0, BVB b1)
00115     : BoolBinary<BVA,BVB>(home,p,b0,b1) {}
00116 
00117   template<class BVA, class BVB>
00118   Actor*
00119   BinOrTrue<BVA,BVB>::copy(Space& home) {
00120     return new (home) BinOrTrue<BVA,BVB>(home,*this);
00121   }
00122 
00123   template<class BVA, class BVB>
00124   inline ExecStatus
00125   BinOrTrue<BVA,BVB>::post(Home home, BVA b0, BVB b1) {
00126     switch (bool_test(b0,b1)) {
00127     case BT_SAME:
00128       GECODE_ME_CHECK(b0.one(home));
00129       break;
00130     case BT_COMP:
00131       break;
00132     case BT_NONE:
00133       if (b0.zero()) {
00134         GECODE_ME_CHECK(b1.one(home));
00135       } else if (b1.zero()) {
00136         GECODE_ME_CHECK(b0.one(home));
00137       } else if (!b0.one() && !b1.one()) {
00138         (void) new (home) BinOrTrue<BVA,BVB>(home,b0,b1);
00139       }
00140       break;
00141     default: GECODE_NEVER;
00142     }
00143     return ES_OK;
00144   }
00145 
00146   template<class BVA, class BVB>
00147   ExecStatus
00148   BinOrTrue<BVA,BVB>::propagate(Space& home, const ModEventDelta&) {
00149 #define GECODE_INT_STATUS(S0,S1) \
00150   ((BVA::S0<<(1*BVA::BITS))|(BVB::S1<<(0*BVB::BITS)))
00151     switch ((x0.status() << (1*BVA::BITS)) | (x1.status() << (0*BVB::BITS))) {
00152     case GECODE_INT_STATUS(NONE,NONE):
00153       GECODE_NEVER;
00154     case GECODE_INT_STATUS(NONE,ZERO):
00155       GECODE_ME_CHECK(x0.one_none(home)); break;
00156     case GECODE_INT_STATUS(NONE,ONE):
00157       break;
00158     case GECODE_INT_STATUS(ZERO,NONE):
00159       GECODE_ME_CHECK(x1.one_none(home)); break;
00160     case GECODE_INT_STATUS(ZERO,ZERO):
00161       return ES_FAILED;
00162     case GECODE_INT_STATUS(ZERO,ONE):
00163     case GECODE_INT_STATUS(ONE,NONE):
00164     case GECODE_INT_STATUS(ONE,ZERO):
00165     case GECODE_INT_STATUS(ONE,ONE):
00166       break;
00167     default:
00168         GECODE_NEVER;
00169     }
00170     return home.ES_SUBSUMED(*this);
00171 #undef GECODE_INT_STATUS
00172   }
00173 
00174   /*
00175    * Boolean disjunction propagator (true)
00176    *
00177    */
00178 
00179   template<class BV>
00180   forceinline
00181   TerOrTrue<BV>::TerOrTrue(Home home, BV b0, BV b1, BV b2)
00182     : BoolBinary<BV,BV>(home,b0,b1), x2(b2) {}
00183 
00184   template<class BV>
00185   forceinline size_t
00186   TerOrTrue<BV>::dispose(Space& home) {
00187     (void) BoolBinary<BV,BV>::dispose(home);
00188     return sizeof(*this);
00189   }
00190 
00191   template<class BV>
00192   forceinline
00193   TerOrTrue<BV>::TerOrTrue(Space& home, TerOrTrue<BV>& p)
00194     : BoolBinary<BV,BV>(home,p) {
00195     x2.update(home,p.x2);
00196   }
00197 
00198   template<class BV>
00199   forceinline
00200   TerOrTrue<BV>::TerOrTrue(Space& home, Propagator& p,
00201                            BV b0, BV b1, BV b2)
00202     : BoolBinary<BV,BV>(home,p,b0,b1) {
00203     x2.update(home,b2);
00204   }
00205 
00206   template<class BV>
00207   Actor*
00208   TerOrTrue<BV>::copy(Space& home) {
00209     assert(x0.none() && x1.none());
00210     if (x2.one())
00211       return new (home) OrTrueSubsumed<BV>(home,*this,x0,x1);
00212     else if (x2.zero())
00213       return new (home) BinOrTrue<BV,BV>(home,*this,x0,x1);
00214     else
00215       return new (home) TerOrTrue<BV>(home,*this);
00216   }
00217 
00218   template<class BV>
00219   forceinline ExecStatus
00220   TerOrTrue<BV>::post(Home home, BV b0, BV b1, BV b2) {
00221     (void) new (home) TerOrTrue<BV>(home,b0,b1,b2);
00222     return ES_OK;
00223   }
00224 
00225   template<class BV>
00226   ExecStatus
00227   TerOrTrue<BV>::propagate(Space& home, const ModEventDelta&) {
00228 #define GECODE_INT_STATUS(S0,S1,S2) \
00229     ((BV::S0<<(2*BV::BITS))|(BV::S1<<(1*BV::BITS))|(BV::S2<<(0*BV::BITS)))
00230     switch ((x0.status() << (2*BV::BITS)) | (x1.status() << (1*BV::BITS)) |
00231             (x2.status() << (0*BV::BITS))) {
00232     case GECODE_INT_STATUS(NONE,NONE,NONE):
00233     case GECODE_INT_STATUS(NONE,NONE,ZERO):
00234     case GECODE_INT_STATUS(NONE,NONE,ONE):
00235       GECODE_NEVER;
00236     case GECODE_INT_STATUS(NONE,ZERO,NONE):
00237       std::swap(x1,x2); x1.subscribe(home,*this,PC_BOOL_VAL);
00238       return ES_FIX;
00239     case GECODE_INT_STATUS(NONE,ZERO,ZERO):
00240       GECODE_ME_CHECK(x0.one_none(home)); break;
00241     case GECODE_INT_STATUS(NONE,ZERO,ONE):
00242     case GECODE_INT_STATUS(NONE,ONE,NONE):
00243     case GECODE_INT_STATUS(NONE,ONE,ZERO):
00244     case GECODE_INT_STATUS(NONE,ONE,ONE):
00245       break;
00246     case GECODE_INT_STATUS(ZERO,NONE,NONE):
00247       std::swap(x0,x2); x0.subscribe(home,*this,PC_BOOL_VAL);
00248       return ES_FIX;
00249     case GECODE_INT_STATUS(ZERO,NONE,ZERO):
00250       GECODE_ME_CHECK(x1.one_none(home)); break;
00251     case GECODE_INT_STATUS(ZERO,NONE,ONE):
00252       break;
00253     case GECODE_INT_STATUS(ZERO,ZERO,NONE):
00254       GECODE_ME_CHECK(x2.one_none(home)); break;
00255     case GECODE_INT_STATUS(ZERO,ZERO,ZERO):
00256       return ES_FAILED;
00257     case GECODE_INT_STATUS(ZERO,ZERO,ONE):
00258     case GECODE_INT_STATUS(ZERO,ONE,NONE):
00259     case GECODE_INT_STATUS(ZERO,ONE,ZERO):
00260     case GECODE_INT_STATUS(ZERO,ONE,ONE):
00261     case GECODE_INT_STATUS(ONE,NONE,NONE):
00262     case GECODE_INT_STATUS(ONE,NONE,ZERO):
00263     case GECODE_INT_STATUS(ONE,NONE,ONE):
00264     case GECODE_INT_STATUS(ONE,ZERO,NONE):
00265     case GECODE_INT_STATUS(ONE,ZERO,ZERO):
00266     case GECODE_INT_STATUS(ONE,ZERO,ONE):
00267     case GECODE_INT_STATUS(ONE,ONE,NONE):
00268     case GECODE_INT_STATUS(ONE,ONE,ZERO):
00269     case GECODE_INT_STATUS(ONE,ONE,ONE):
00270       break;
00271     default:
00272       GECODE_NEVER;
00273     }
00274     return home.ES_SUBSUMED(*this);
00275 #undef GECODE_INT_STATUS
00276   }
00277 
00278   /*
00279    * Boolean disjunction propagator (true)
00280    *
00281    */
00282 
00283   template<class BV>
00284   forceinline
00285   QuadOrTrue<BV>::QuadOrTrue(Home home, BV b0, BV b1, BV b2, BV b3)
00286     : BoolBinary<BV,BV>(home,b0,b1), x2(b2), x3(b3) {}
00287 
00288   template<class BV>
00289   forceinline size_t
00290   QuadOrTrue<BV>::dispose(Space& home) {
00291     (void) BoolBinary<BV,BV>::dispose(home);
00292     return sizeof(*this);
00293   }
00294 
00295   template<class BV>
00296   forceinline
00297   QuadOrTrue<BV>::QuadOrTrue(Space& home, QuadOrTrue<BV>& p)
00298     : BoolBinary<BV,BV>(home,p) {
00299     x2.update(home,p.x2);
00300     x3.update(home,p.x3);
00301   }
00302 
00303   template<class BV>
00304   forceinline
00305   QuadOrTrue<BV>::QuadOrTrue(Space& home, Propagator& p,
00306                              BV b0, BV b1, BV b2, BV b3)
00307     : BoolBinary<BV,BV>(home,p,b0,b1) {
00308     x2.update(home,b2);
00309     x3.update(home,b3);
00310   }
00311 
00312   template<class BV>
00313   Actor*
00314   QuadOrTrue<BV>::copy(Space& home) {
00315     assert(x0.none() && x1.none());
00316     if (x2.one() || x3.one())
00317       return new (home) OrTrueSubsumed<BV>(home,*this,x0,x1);
00318     else if (x2.zero() && x3.zero())
00319       return new (home) BinOrTrue<BV,BV>(home,*this,x0,x1);
00320     else if (x2.zero())
00321       return new (home) TerOrTrue<BV>(home,*this,x0,x1,x3);
00322     else if (x3.zero())
00323       return new (home) TerOrTrue<BV>(home,*this,x0,x1,x2);
00324     else
00325       return new (home) QuadOrTrue<BV>(home,*this);
00326   }
00327 
00328   template<class BV>
00329   forceinline ExecStatus
00330   QuadOrTrue<BV>::post(Home home, BV b0, BV b1, BV b2, BV b3) {
00331     (void) new (home) QuadOrTrue<BV>(home,b0,b1,b2,b3);
00332     return ES_OK;
00333   }
00334 
00335   template<class BV>
00336   ExecStatus
00337   QuadOrTrue<BV>::propagate(Space& home, const ModEventDelta&) {
00338 #define GECODE_INT_STATUS(S0,S1,S2,S3)                        \
00339     ((BV::S0 << (3*BV::BITS)) | (BV::S1 << (2*BV::BITS)) |    \
00340      (BV::S2 << (1*BV::BITS)) | (BV::S3 << (0*BV::BITS)))
00341     switch ((x0.status() << (3*BV::BITS)) | (x1.status() << (2*BV::BITS)) |
00342             (x2.status() << (1*BV::BITS)) | (x3.status() << (0*BV::BITS))) {
00343     case GECODE_INT_STATUS(NONE,NONE,NONE,NONE):
00344     case GECODE_INT_STATUS(NONE,NONE,NONE,ZERO):
00345     case GECODE_INT_STATUS(NONE,NONE,NONE,ONE):
00346     case GECODE_INT_STATUS(NONE,NONE,ZERO,NONE):
00347     case GECODE_INT_STATUS(NONE,NONE,ZERO,ZERO):
00348     case GECODE_INT_STATUS(NONE,NONE,ZERO,ONE):
00349     case GECODE_INT_STATUS(NONE,NONE,ONE,NONE):
00350     case GECODE_INT_STATUS(NONE,NONE,ONE,ZERO):
00351     case GECODE_INT_STATUS(NONE,NONE,ONE,ONE):
00352       GECODE_NEVER;
00353     case GECODE_INT_STATUS(NONE,ZERO,NONE,NONE):
00354     case GECODE_INT_STATUS(NONE,ZERO,NONE,ZERO):
00355       std::swap(x1,x2); x1.subscribe(home,*this,PC_BOOL_VAL,false);
00356       return ES_FIX;
00357     case GECODE_INT_STATUS(NONE,ZERO,NONE,ONE):
00358       break;
00359     case GECODE_INT_STATUS(NONE,ZERO,ZERO,NONE):
00360       std::swap(x1,x3); x1.subscribe(home,*this,PC_BOOL_VAL,false);
00361       return ES_FIX;
00362     case GECODE_INT_STATUS(NONE,ZERO,ZERO,ZERO):
00363       GECODE_ME_CHECK(x0.one_none(home)); break;
00364     case GECODE_INT_STATUS(NONE,ZERO,ZERO,ONE):
00365     case GECODE_INT_STATUS(NONE,ZERO,ONE,NONE):
00366     case GECODE_INT_STATUS(NONE,ZERO,ONE,ZERO):
00367     case GECODE_INT_STATUS(NONE,ZERO,ONE,ONE):
00368     case GECODE_INT_STATUS(NONE,ONE,NONE,NONE):
00369     case GECODE_INT_STATUS(NONE,ONE,NONE,ZERO):
00370     case GECODE_INT_STATUS(NONE,ONE,NONE,ONE):
00371     case GECODE_INT_STATUS(NONE,ONE,ZERO,NONE):
00372     case GECODE_INT_STATUS(NONE,ONE,ZERO,ZERO):
00373     case GECODE_INT_STATUS(NONE,ONE,ZERO,ONE):
00374     case GECODE_INT_STATUS(NONE,ONE,ONE,NONE):
00375     case GECODE_INT_STATUS(NONE,ONE,ONE,ZERO):
00376     case GECODE_INT_STATUS(NONE,ONE,ONE,ONE):
00377       break;
00378     case GECODE_INT_STATUS(ZERO,NONE,NONE,NONE):
00379     case GECODE_INT_STATUS(ZERO,NONE,NONE,ZERO):
00380       std::swap(x0,x2); x0.subscribe(home,*this,PC_BOOL_VAL,false);
00381       return ES_FIX;
00382     case GECODE_INT_STATUS(ZERO,NONE,NONE,ONE):
00383       break;
00384     case GECODE_INT_STATUS(ZERO,NONE,ZERO,NONE):
00385       std::swap(x0,x3); x0.subscribe(home,*this,PC_BOOL_VAL,false);
00386       return ES_FIX;
00387     case GECODE_INT_STATUS(ZERO,NONE,ZERO,ZERO):
00388       GECODE_ME_CHECK(x1.one_none(home)); break;
00389     case GECODE_INT_STATUS(ZERO,NONE,ZERO,ONE):
00390     case GECODE_INT_STATUS(ZERO,NONE,ONE,NONE):
00391     case GECODE_INT_STATUS(ZERO,NONE,ONE,ZERO):
00392     case GECODE_INT_STATUS(ZERO,NONE,ONE,ONE):
00393       break;
00394     case GECODE_INT_STATUS(ZERO,ZERO,NONE,NONE):
00395       std::swap(x0,x2); x0.subscribe(home,*this,PC_BOOL_VAL,false);
00396       std::swap(x1,x3); x1.subscribe(home,*this,PC_BOOL_VAL,false);
00397       return ES_FIX;
00398     case GECODE_INT_STATUS(ZERO,ZERO,NONE,ZERO):
00399       GECODE_ME_CHECK(x2.one_none(home)); break;
00400     case GECODE_INT_STATUS(ZERO,ZERO,NONE,ONE):
00401       break;
00402     case GECODE_INT_STATUS(ZERO,ZERO,ZERO,NONE):
00403       GECODE_ME_CHECK(x3.one_none(home)); break;
00404     case GECODE_INT_STATUS(ZERO,ZERO,ZERO,ZERO):
00405       return ES_FAILED;
00406     case GECODE_INT_STATUS(ZERO,ZERO,ZERO,ONE):
00407     case GECODE_INT_STATUS(ZERO,ZERO,ONE,NONE):
00408     case GECODE_INT_STATUS(ZERO,ZERO,ONE,ZERO):
00409     case GECODE_INT_STATUS(ZERO,ZERO,ONE,ONE):
00410     case GECODE_INT_STATUS(ZERO,ONE,NONE,NONE):
00411     case GECODE_INT_STATUS(ZERO,ONE,NONE,ZERO):
00412     case GECODE_INT_STATUS(ZERO,ONE,NONE,ONE):
00413     case GECODE_INT_STATUS(ZERO,ONE,ZERO,NONE):
00414     case GECODE_INT_STATUS(ZERO,ONE,ZERO,ZERO):
00415     case GECODE_INT_STATUS(ZERO,ONE,ZERO,ONE):
00416     case GECODE_INT_STATUS(ZERO,ONE,ONE,NONE):
00417     case GECODE_INT_STATUS(ZERO,ONE,ONE,ZERO):
00418     case GECODE_INT_STATUS(ZERO,ONE,ONE,ONE):
00419     case GECODE_INT_STATUS(ONE,NONE,NONE,NONE):
00420     case GECODE_INT_STATUS(ONE,NONE,NONE,ZERO):
00421     case GECODE_INT_STATUS(ONE,NONE,NONE,ONE):
00422     case GECODE_INT_STATUS(ONE,NONE,ZERO,NONE):
00423     case GECODE_INT_STATUS(ONE,NONE,ZERO,ZERO):
00424     case GECODE_INT_STATUS(ONE,NONE,ZERO,ONE):
00425     case GECODE_INT_STATUS(ONE,NONE,ONE,NONE):
00426     case GECODE_INT_STATUS(ONE,NONE,ONE,ZERO):
00427     case GECODE_INT_STATUS(ONE,NONE,ONE,ONE):
00428     case GECODE_INT_STATUS(ONE,ZERO,NONE,NONE):
00429     case GECODE_INT_STATUS(ONE,ZERO,NONE,ZERO):
00430     case GECODE_INT_STATUS(ONE,ZERO,NONE,ONE):
00431     case GECODE_INT_STATUS(ONE,ZERO,ZERO,NONE):
00432     case GECODE_INT_STATUS(ONE,ZERO,ZERO,ZERO):
00433     case GECODE_INT_STATUS(ONE,ZERO,ZERO,ONE):
00434     case GECODE_INT_STATUS(ONE,ZERO,ONE,NONE):
00435     case GECODE_INT_STATUS(ONE,ZERO,ONE,ZERO):
00436     case GECODE_INT_STATUS(ONE,ZERO,ONE,ONE):
00437     case GECODE_INT_STATUS(ONE,ONE,NONE,NONE):
00438     case GECODE_INT_STATUS(ONE,ONE,NONE,ZERO):
00439     case GECODE_INT_STATUS(ONE,ONE,NONE,ONE):
00440     case GECODE_INT_STATUS(ONE,ONE,ZERO,NONE):
00441     case GECODE_INT_STATUS(ONE,ONE,ZERO,ZERO):
00442     case GECODE_INT_STATUS(ONE,ONE,ZERO,ONE):
00443     case GECODE_INT_STATUS(ONE,ONE,ONE,NONE):
00444     case GECODE_INT_STATUS(ONE,ONE,ONE,ZERO):
00445     case GECODE_INT_STATUS(ONE,ONE,ONE,ONE):
00446       break;
00447     default:
00448       GECODE_NEVER;
00449     }
00450     return home.ES_SUBSUMED(*this);
00451 #undef GECODE_INT_STATUS
00452   }
00453 
00454   /*
00455    * Boolean disjunction propagator
00456    *
00457    */
00458 
00459   template<class BVA, class BVB, class BVC>
00460   forceinline
00461   Or<BVA,BVB,BVC>::Or(Home home, BVA b0, BVB b1, BVC b2)
00462     : BoolTernary<BVA,BVB,BVC>(home,b0,b1,b2) {}
00463 
00464   template<class BVA, class BVB, class BVC>
00465   forceinline
00466   Or<BVA,BVB,BVC>::Or(Space& home, Or<BVA,BVB,BVC>& p)
00467     : BoolTernary<BVA,BVB,BVC>(home,p) {}
00468 
00469   template<class BVA, class BVB, class BVC>
00470   forceinline
00471   Or<BVA,BVB,BVC>::Or(Space& home, Propagator& p,
00472                         BVA b0, BVB b1, BVC b2)
00473     : BoolTernary<BVA,BVB,BVC>(home,p,b0,b1,b2) {}
00474 
00475   template<class BVA, class BVB, class BVC>
00476   Actor*
00477   Or<BVA,BVB,BVC>::copy(Space& home) {
00478     if (x2.one()) {
00479       assert(x0.none() && x1.none());
00480       return new (home) BinOrTrue<BVA,BVB>(home,*this,x0,x1);
00481     } else if (x0.zero()) {
00482       assert(x1.none() && x2.none());
00483       return new (home) Eq<BVB,BVC>(home,*this,x1,x2);
00484     } else if (x1.zero()) {
00485       assert(x0.none() && x2.none());
00486       return new (home) Eq<BVA,BVC>(home,*this,x0,x2);
00487     } else {
00488       return new (home) Or<BVA,BVB,BVC>(home,*this);
00489     }
00490   }
00491 
00492   template<class BVA, class BVB, class BVC>
00493   inline ExecStatus
00494   Or<BVA,BVB,BVC>::post(Home home, BVA b0, BVB b1, BVC b2) {
00495     if (b2.zero()) {
00496       GECODE_ME_CHECK(b0.zero(home));
00497       GECODE_ME_CHECK(b1.zero(home));
00498     } else if (b2.one()) {
00499       return BinOrTrue<BVA,BVB>::post(home,b0,b1);
00500     } else {
00501       switch (bool_test(b0,b1)) {
00502       case BT_SAME:
00503         return Eq<BVA,BVC>::post(home,b0,b2);
00504       case BT_COMP:
00505         GECODE_ME_CHECK(b2.one(home));
00506         break;
00507       case BT_NONE:
00508         if (b0.one() || b1.one()) {
00509           GECODE_ME_CHECK(b2.one(home));
00510         } else if (b0.zero()) {
00511           return Eq<BVB,BVC>::post(home,b1,b2);
00512         } else if (b1.zero()) {
00513           return Eq<BVA,BVC>::post(home,b0,b2);
00514         } else {
00515           (void) new (home) Or<BVA,BVB,BVC>(home,b0,b1,b2);
00516         }
00517         break;
00518       default: GECODE_NEVER;
00519       }
00520     }
00521     return ES_OK;
00522   }
00523 
00524   template<class BVA, class BVB, class BVC>
00525   ExecStatus
00526   Or<BVA,BVB,BVC>::propagate(Space& home, const ModEventDelta&) {
00527 #define GECODE_INT_STATUS(S0,S1,S2) \
00528   ((BVA::S0<<(2*BVA::BITS))|(BVB::S1<<(1*BVB::BITS))|(BVC::S2<<(0*BVC::BITS)))
00529     switch ((x0.status() << (2*BVA::BITS)) | (x1.status() << (1*BVB::BITS)) |
00530             (x2.status() << (0*BVC::BITS))) {
00531     case GECODE_INT_STATUS(NONE,NONE,NONE):
00532       GECODE_NEVER;
00533     case GECODE_INT_STATUS(NONE,NONE,ZERO):
00534       GECODE_ME_CHECK(x0.zero_none(home));
00535       GECODE_ME_CHECK(x1.zero_none(home));
00536       break;
00537     case GECODE_INT_STATUS(NONE,NONE,ONE):
00538       return ES_FIX;
00539     case GECODE_INT_STATUS(NONE,ZERO,NONE):
00540       switch (bool_test(x0,x2)) {
00541       case BT_SAME: return home.ES_SUBSUMED(*this);
00542       case BT_COMP: return ES_FAILED;
00543       case BT_NONE: return ES_FIX;
00544       default: GECODE_NEVER;
00545       }
00546       GECODE_NEVER;
00547     case GECODE_INT_STATUS(NONE,ZERO,ZERO):
00548       GECODE_ME_CHECK(x0.zero_none(home)); break;
00549     case GECODE_INT_STATUS(NONE,ZERO,ONE):
00550       GECODE_ME_CHECK(x0.one_none(home)); break;
00551     case GECODE_INT_STATUS(NONE,ONE,NONE):
00552       GECODE_ME_CHECK(x2.one_none(home)); break;
00553     case GECODE_INT_STATUS(NONE,ONE,ZERO):
00554       return ES_FAILED;
00555     case GECODE_INT_STATUS(NONE,ONE,ONE):
00556       break;
00557     case GECODE_INT_STATUS(ZERO,NONE,NONE):
00558       switch (bool_test(x1,x2)) {
00559       case BT_SAME: return home.ES_SUBSUMED(*this);
00560       case BT_COMP: return ES_FAILED;
00561       case BT_NONE: return ES_FIX;
00562       default: GECODE_NEVER;
00563       }
00564       GECODE_NEVER;
00565     case GECODE_INT_STATUS(ZERO,NONE,ZERO):
00566       GECODE_ME_CHECK(x1.zero_none(home)); break;
00567     case GECODE_INT_STATUS(ZERO,NONE,ONE):
00568       GECODE_ME_CHECK(x1.one_none(home)); break;
00569     case GECODE_INT_STATUS(ZERO,ZERO,NONE):
00570       GECODE_ME_CHECK(x2.zero_none(home)); break;
00571     case GECODE_INT_STATUS(ZERO,ZERO,ZERO):
00572       break;
00573     case GECODE_INT_STATUS(ZERO,ZERO,ONE):
00574       return ES_FAILED;
00575     case GECODE_INT_STATUS(ZERO,ONE,NONE):
00576       GECODE_ME_CHECK(x2.one_none(home)); break;
00577     case GECODE_INT_STATUS(ZERO,ONE,ZERO):
00578       return ES_FAILED;
00579     case GECODE_INT_STATUS(ZERO,ONE,ONE):
00580       break;
00581     case GECODE_INT_STATUS(ONE,NONE,NONE):
00582       GECODE_ME_CHECK(x2.one_none(home)); break;
00583     case GECODE_INT_STATUS(ONE,NONE,ZERO):
00584       return ES_FAILED;
00585     case GECODE_INT_STATUS(ONE,NONE,ONE):
00586       break;
00587     case GECODE_INT_STATUS(ONE,ZERO,NONE):
00588       GECODE_ME_CHECK(x2.one_none(home)); break;
00589     case GECODE_INT_STATUS(ONE,ZERO,ZERO):
00590       return ES_FAILED;
00591     case GECODE_INT_STATUS(ONE,ZERO,ONE):
00592       break;
00593     case GECODE_INT_STATUS(ONE,ONE,NONE):
00594       GECODE_ME_CHECK(x2.one_none(home)); break;
00595     case GECODE_INT_STATUS(ONE,ONE,ZERO):
00596       return ES_FAILED;
00597     case GECODE_INT_STATUS(ONE,ONE,ONE):
00598       break;
00599     default:
00600       GECODE_NEVER;
00601     }
00602     return home.ES_SUBSUMED(*this);
00603 #undef GECODE_INT_STATUS
00604   }
00605 
00606   /*
00607    * N-ary Boolean disjunction propagator (true)
00608    *
00609    */
00610 
00611   template<class BV>
00612   forceinline
00613   NaryOrTrue<BV>::NaryOrTrue(Home home, ViewArray<BV>& b)
00614     : BinaryPropagator<BV,PC_BOOL_VAL>(home,b[0],b[1]), x(b) {
00615     assert(x.size() > 2);
00616     x.drop_fst(2);
00617   }
00618 
00619   template<class BV>
00620   PropCost
00621   NaryOrTrue<BV>::cost(const Space&, const ModEventDelta&) const {
00622     return PropCost::binary(PropCost::LO);
00623   }
00624 
00625   template<class BV>
00626   forceinline
00627   NaryOrTrue<BV>::NaryOrTrue(Space& home, NaryOrTrue<BV>& p)
00628     : BinaryPropagator<BV,PC_BOOL_VAL>(home,p) {
00629     x.update(home,p.x);
00630   }
00631 
00632   template<class BV>
00633   Actor*
00634   NaryOrTrue<BV>::copy(Space& home) {
00635     int n = x.size();
00636     if (n > 0) {
00637       // Eliminate all zeros and find a one
00638       for (int i=n; i--; )
00639         if (x[i].one()) {
00640           // Only keep the one
00641           x[0]=x[i]; x.size(1);
00642           return new (home) OrTrueSubsumed<BV>(home,*this,x0,x1);
00643         } else if (x[i].zero()) {
00644           // Eliminate the zero
00645           x[i]=x[--n];
00646         }
00647       x.size(n);
00648     }
00649     switch (n) {
00650     case 0:
00651       return new (home) BinOrTrue<BV,BV>(home,*this,x0,x1);
00652     case 1:
00653       return new (home) TerOrTrue<BV>(home,*this,x0,x1,x[0]);
00654     case 2:
00655       return new (home) QuadOrTrue<BV>(home,*this,x0,x1,x[0],x[1]);
00656     default:
00657       return new (home) NaryOrTrue<BV>(home,*this);
00658     }
00659   }
00660 
00661   template<class BV>
00662   inline ExecStatus
00663   NaryOrTrue<BV>::post(Home home, ViewArray<BV>& b) {
00664     for (int i=b.size(); i--; )
00665       if (b[i].one())
00666         return ES_OK;
00667       else if (b[i].zero())
00668         b.move_lst(i);
00669     if (b.size() == 0)
00670       return ES_FAILED;
00671     if (b.size() == 1) {
00672       GECODE_ME_CHECK(b[0].one(home));
00673     } else if (b.size() == 2) {
00674        return BinOrTrue<BV,BV>::post(home,b[0],b[1]);
00675     } else if (b.size() == 3) {
00676        return TerOrTrue<BV>::post(home,b[0],b[1],b[2]);
00677     } else if (b.size() == 4) {
00678        return QuadOrTrue<BV>::post(home,b[0],b[1],b[2],b[3]);
00679     } else {
00680       (void) new (home) NaryOrTrue(home,b);
00681     }
00682     return ES_OK;
00683   }
00684 
00685   template<class BV>
00686   forceinline size_t
00687   NaryOrTrue<BV>::dispose(Space& home) {
00688     (void) BinaryPropagator<BV,PC_BOOL_VAL>::dispose(home);
00689     return sizeof(*this);
00690   }
00691 
00692   template<class BV>
00693   forceinline ExecStatus
00694   NaryOrTrue<BV>::resubscribe(Space& home, BV& x0, BV x1) {
00695     if (x0.zero()) {
00696       int n = x.size();
00697       for (int i=n; i--; )
00698         if (x[i].one()) {
00699           return home.ES_SUBSUMED(*this);
00700         } else if (x[i].zero()) {
00701           x[i] = x[--n];
00702         } else {
00703           // Move to x0 and subscribe
00704           x0=x[i]; x[i]=x[--n];
00705           x.size(n);
00706           x0.subscribe(home,*this,PC_BOOL_VAL,false);
00707           return ES_FIX;
00708         }
00709       // All views have been assigned!
00710       GECODE_ME_CHECK(x1.one(home));
00711       return home.ES_SUBSUMED(*this);
00712     }
00713     return ES_FIX;
00714   }
00715 
00716   template<class BV>
00717   ExecStatus
00718   NaryOrTrue<BV>::propagate(Space& home, const ModEventDelta&) {
00719     if (x0.one())
00720       return home.ES_SUBSUMED(*this);
00721     if (x1.one())
00722       return home.ES_SUBSUMED(*this);
00723     GECODE_ES_CHECK(resubscribe(home,x0,x1));
00724     GECODE_ES_CHECK(resubscribe(home,x1,x0));
00725     return ES_FIX;
00726   }
00727 
00728 
00729   /*
00730    * N-ary Boolean disjunction propagator
00731    *
00732    */
00733 
00734   template<class VX, class VY>
00735   forceinline
00736   NaryOr<VX,VY>::NaryOr(Home home, ViewArray<VX>& x, VY y)
00737     : MixNaryOnePropagator<VX,PC_BOOL_NONE,VY,PC_BOOL_VAL>(home,x,y),
00738       n_zero(0), c(home) {
00739     x.subscribe(home,*new (home) Advisor(home,*this,c));
00740   }
00741 
00742   template<class VX, class VY>
00743   forceinline
00744   NaryOr<VX,VY>::NaryOr(Space& home, NaryOr<VX,VY>& p)
00745     : MixNaryOnePropagator<VX,PC_BOOL_NONE,VY,PC_BOOL_VAL>(home,p),
00746       n_zero(p.n_zero) {
00747     c.update(home,p.c);
00748   }
00749 
00750   template<class VX, class VY>
00751   Actor*
00752   NaryOr<VX,VY>::copy(Space& home) {
00753     assert(n_zero < x.size());
00754     if (n_zero > 0) {
00755       int n=x.size();
00756       // Eliminate all zeros
00757       for (int i=n; i--; )
00758         if (x[i].zero())
00759           x[i]=x[--n];
00760       x.size(n);
00761       n_zero = 0;
00762     }
00763     assert(n_zero < x.size());
00764     return new (home) NaryOr<VX,VY>(home,*this);
00765   }
00766 
00767   template<class VX, class VY>
00768   inline ExecStatus
00769   NaryOr<VX,VY>::post(Home home, ViewArray<VX>& x, VY y) {
00770     assert(!shared(x));
00771     if (y.one())
00772       return NaryOrTrue<VX>::post(home,x);
00773     if (y.zero()) {
00774       for (int i=0; i<x.size(); i++)
00775         GECODE_ME_CHECK(x[i].zero(home));
00776       return ES_OK;
00777     }
00778     for (int i=x.size(); i--; )
00779       if (x[i].one()) {
00780         GECODE_ME_CHECK(y.one_none(home));
00781         return ES_OK;
00782       } else if (x[i].zero()) {
00783         x.move_lst(i);
00784       }
00785     if (x.size() == 0) {
00786       GECODE_ME_CHECK(y.zero_none(home));
00787     } else if (x.size() == 1) {
00788       return Eq<VX,VY>::post(home,x[0],y);
00789     } else if (x.size() == 2) {
00790       return Or<VX,VX,VY>::post(home,x[0],x[1],y);
00791     } else {
00792       (void) new (home) NaryOr(home,x,y);
00793     }
00794     return ES_OK;
00795   }
00796 
00797   template<class VX, class VY>
00798   PropCost
00799   NaryOr<VX,VY>::cost(const Space&, const ModEventDelta&) const {
00800     return PropCost::unary(PropCost::LO);
00801   }
00802 
00803   template<class VX, class VY>
00804   ExecStatus
00805   NaryOr<VX,VY>::advise(Space&, Advisor&, const Delta& d) {
00806     // Decides whether the propagator must be run
00807     if (VX::zero(d) && (++n_zero < x.size()))
00808       return ES_FIX;
00809     else
00810       return ES_NOFIX;
00811   }
00812 
00813   template<class VX, class VY>
00814   void
00815   NaryOr<VX,VY>::reschedule(Space& home) {
00816     y.reschedule(home,*this,PC_BOOL_VAL);
00817     if (n_zero == x.size())
00818       VX::schedule(home,*this,ME_BOOL_VAL);
00819     for (int i=0; i<x.size(); i++)
00820       if (x[i].one()) {
00821         VX::schedule(home,*this,ME_BOOL_VAL);
00822         break;
00823       }
00824   }
00825 
00826   template<class VX, class VY>
00827   forceinline size_t
00828   NaryOr<VX,VY>::dispose(Space& home) {
00829     Advisors<Advisor> as(c);
00830     x.cancel(home,as.advisor());
00831     c.dispose(home);
00832     (void) MixNaryOnePropagator<VX,PC_BOOL_NONE,VY,PC_BOOL_VAL>
00833       ::dispose(home);
00834     return sizeof(*this);
00835   }
00836 
00837   template<class VX, class VY>
00838   ExecStatus
00839   NaryOr<VX,VY>::propagate(Space& home, const ModEventDelta&) {
00840     if (y.one())
00841       GECODE_REWRITE(*this,NaryOrTrue<VX>::post(home(*this),x));
00842     if (y.zero()) {
00843       // Note that this might trigger the advisor of this propagator!
00844       for (int i=0; i<x.size(); i++)
00845         GECODE_ME_CHECK(x[i].zero(home));
00846     } else if (n_zero == x.size()) {
00847       // All views are zero
00848       GECODE_ME_CHECK(y.zero_none(home));
00849     } else {
00850       // There is at least one view which is one
00851       GECODE_ME_CHECK(y.one_none(home));
00852     }
00853     return home.ES_SUBSUMED(*this);
00854   }
00855 
00856 }}}
00857 
00858 // STATISTICS: int-prop
00859