Generated on Mon Aug 25 11:35:35 2008 for Gecode by doxygen 1.5.6

or.icc

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: 2008-08-20 18:02:33 +0200 (Wed, 20 Aug 2008) $ by $Author: schulte $
00011  *     $Revision: 7665 $
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 Bool {
00039 
00041   template<class BV>
00042   class OrTrueSubsumed : public BoolBinary<BV,BV> {
00043   protected:
00044     using BoolBinary<BV,BV>::x0;
00045     using BoolBinary<BV,BV>::x1;
00047     OrTrueSubsumed(Space* home, bool share, OrTrueSubsumed& p);
00048   public:
00050     OrTrueSubsumed(Space* home, BV b0, BV b1);
00052     OrTrueSubsumed(Space* home, bool share, Propagator& p,
00053                    BV b0, BV b1);
00055     virtual Actor* copy(Space* home, bool share);
00057     virtual ExecStatus propagate(Space* home, ModEventDelta med);
00059     virtual Reflection::ActorSpec spec(const Space* home,
00060                                         Reflection::VarMap& m) const;
00062     static void post(Space* home, Reflection::VarMap& vars,
00063                      const Reflection::ActorSpec& spec);
00065     static Support::Symbol ati(void);    
00066   };
00067 
00068   template <class BV>
00069   forceinline
00070   OrTrueSubsumed<BV>::OrTrueSubsumed
00071   (Space* home, BV b0, BV b1)
00072     : BoolBinary<BV,BV>(home,b0,b1) {}
00073 
00074   template <class BV>
00075   forceinline
00076   OrTrueSubsumed<BV>::OrTrueSubsumed
00077   (Space* home, bool share, OrTrueSubsumed<BV>& p)
00078     : BoolBinary<BV,BV>(home,share,p) {}
00079 
00080   template <class BV>
00081   forceinline
00082   OrTrueSubsumed<BV>::OrTrueSubsumed(Space* home, bool share, Propagator& p,
00083                                      BV b0, BV b1)
00084     : BoolBinary<BV,BV>(home,share,p,b0,b1) {}
00085 
00086   template <class BV>
00087   Actor*
00088   OrTrueSubsumed<BV>::copy(Space* home, bool share) {
00089     return new (home) OrTrueSubsumed<BV>(home,share,*this);
00090   }
00091 
00092   template <class BV>
00093   ExecStatus
00094   OrTrueSubsumed<BV>::propagate(Space* home, ModEventDelta) {
00095     return ES_SUBSUMED(this,home);
00096   }
00097 
00098   template <class BV>
00099   inline Support::Symbol
00100   OrTrueSubsumed<BV>::ati(void) {
00101     return Reflection::mangle<BV>("Gecode::Int::Bool::OrTrueSubsumed");
00102   }
00103 
00104   template <class BV>
00105   Reflection::ActorSpec
00106   OrTrueSubsumed<BV>::spec(const Space* home, Reflection::VarMap& m) const {
00107     return BoolBinary<BV,BV>::spec(home, m, ati());
00108   }
00109 
00110   template<class BV>
00111   void
00112   OrTrueSubsumed<BV>::post(Space* home, Reflection::VarMap& vars,
00113                            const Reflection::ActorSpec& spec) {
00114     spec.checkArity(2);
00115     BV b0(home, vars, spec[0]);
00116     BV b1(home, vars, spec[1]);
00117     (void) new (home) OrTrueSubsumed<BV>(home,b0,b1);
00118   }
00119 
00120 
00121   /*
00122    * Binary Boolean disjunction propagator (true)
00123    *
00124    */
00125 
00126   template <class BVA, class BVB>
00127   forceinline
00128   BinOrTrue<BVA,BVB>::BinOrTrue(Space* home, BVA b0, BVB b1)
00129     : BoolBinary<BVA,BVB>(home,b0,b1) {}
00130 
00131   template <class BVA, class BVB>
00132   forceinline
00133   BinOrTrue<BVA,BVB>::BinOrTrue(Space* home, bool share, BinOrTrue<BVA,BVB>& p)
00134     : BoolBinary<BVA,BVB>(home,share,p) {}
00135 
00136   template <class BVA, class BVB>
00137   forceinline
00138   BinOrTrue<BVA,BVB>::BinOrTrue(Space* home, bool share, Propagator& p,
00139                               BVA b0, BVB b1)
00140     : BoolBinary<BVA,BVB>(home,share,p,b0,b1) {}
00141 
00142   template <class BVA, class BVB>
00143   Actor*
00144   BinOrTrue<BVA,BVB>::copy(Space* home, bool share) {
00145     return new (home) BinOrTrue<BVA,BVB>(home,share,*this);
00146   }
00147 
00148   template <class BVA, class BVB>
00149   inline ExecStatus
00150   BinOrTrue<BVA,BVB>::post(Space* home, BVA b0, BVB b1) {
00151     switch (bool_test(b0,b1)) {
00152     case BT_SAME:
00153       GECODE_ME_CHECK(b0.one(home));
00154       break;
00155     case BT_COMP:
00156       break;
00157     case BT_NONE:
00158       if (b0.zero()) {
00159         GECODE_ME_CHECK(b1.one(home));
00160       } else if (b1.zero()) {
00161         GECODE_ME_CHECK(b0.one(home));
00162       } else if (!b0.one() && !b1.one()) {
00163         (void) new (home) BinOrTrue<BVA,BVB>(home,b0,b1);
00164       }
00165       break;
00166     default: GECODE_NEVER;
00167     }
00168     return ES_OK;
00169   }
00170 
00171   template <class BVA, class BVB>
00172   ExecStatus
00173   BinOrTrue<BVA,BVB>::propagate(Space* home, ModEventDelta) {
00174 #define GECODE_INT_STATUS(S0,S1) \
00175   ((BVA::S0<<(1*BVA::BITS))|(BVB::S1<<(0*BVB::BITS)))
00176     switch ((x0.status() << (1*BVA::BITS)) | (x1.status() << (0*BVB::BITS))) {
00177     case GECODE_INT_STATUS(NONE,NONE):
00178       GECODE_NEVER;
00179     case GECODE_INT_STATUS(NONE,ZERO):
00180       GECODE_ME_CHECK(x0.one_none(home)); break;
00181     case GECODE_INT_STATUS(NONE,ONE):
00182       x0.cancel(home,this,PC_BOOL_VAL); break;
00183     case GECODE_INT_STATUS(ZERO,NONE):
00184       GECODE_ME_CHECK(x1.one_none(home)); break;
00185     case GECODE_INT_STATUS(ZERO,ZERO):
00186       return ES_FAILED;
00187     case GECODE_INT_STATUS(ZERO,ONE):
00188       break;
00189     case GECODE_INT_STATUS(ONE,NONE):
00190       x1.cancel(home,this,PC_BOOL_VAL); break;
00191     case GECODE_INT_STATUS(ONE,ZERO):
00192       break;
00193     case GECODE_INT_STATUS(ONE,ONE):
00194       break;
00195     default:
00196         GECODE_NEVER;
00197     }
00198     return ES_SUBSUMED(this,sizeof(*this));
00199 #undef GECODE_INT_STATUS
00200   }
00201 
00202   template <class BVA, class BVB>
00203   Support::Symbol
00204   BinOrTrue<BVA,BVB>::ati(void) {
00205     return Reflection::mangle<BVA,BVB>("Gecode::Int::Bool::BinOrTrue");
00206   }
00207 
00208   template <class BVA, class BVB>
00209   Reflection::ActorSpec
00210   BinOrTrue<BVA,BVB>::spec(const Space* home, Reflection::VarMap& m) const {
00211     return BoolBinary<BVA,BVB>::spec(home, m, ati());
00212   }
00213 
00214   template<class BVA, class BVB>
00215   void
00216   BinOrTrue<BVA,BVB>::post(Space* home, Reflection::VarMap& vars,
00217                            const Reflection::ActorSpec& spec) {
00218     spec.checkArity(2);
00219     BVA b0(home, vars, spec[0]);
00220     BVB b1(home, vars, spec[1]);
00221     (void) new (home) BinOrTrue<BVA,BVB>(home,b0,b1);
00222   }
00223 
00224   /*
00225    * Boolean disjunction propagator (true)
00226    *
00227    */
00228 
00229   template <class BV>
00230   forceinline
00231   TerOrTrue<BV>::TerOrTrue(Space* home, BV b0, BV b1, BV b2)
00232     : BoolBinary<BV,BV>(home,b0,b1), x2(b2) {}
00233 
00234   template<class BV>
00235   forceinline size_t
00236   TerOrTrue<BV>::dispose(Space* home) {
00237     (void) BoolBinary<BV,BV>::dispose(home);
00238     return sizeof(*this);
00239   }
00240 
00241   template <class BV>
00242   forceinline
00243   TerOrTrue<BV>::TerOrTrue(Space* home, bool share, TerOrTrue<BV>& p)
00244     : BoolBinary<BV,BV>(home,share,p) {
00245     x2.update(home,share,p.x2);
00246   }
00247 
00248   template <class BV>
00249   forceinline
00250   TerOrTrue<BV>::TerOrTrue(Space* home, bool share, Propagator& p,
00251                            BV b0, BV b1, BV b2)
00252     : BoolBinary<BV,BV>(home,share,p,b0,b1) {
00253     x2.update(home,share,b2);
00254   }
00255 
00256   template <class BV>
00257   Actor*
00258   TerOrTrue<BV>::copy(Space* home, bool share) {
00259     assert(x0.none() && x1.none());
00260     if (x2.one())
00261       return new (home) OrTrueSubsumed<BV>(home,share,*this,x0,x1);
00262     else if (x2.zero())
00263       return new (home) BinOrTrue<BV,BV>(home,share,*this,x0,x1);
00264     else
00265       return new (home) TerOrTrue<BV>(home,share,*this);
00266   }
00267 
00268   template <class BV>
00269   forceinline ExecStatus
00270   TerOrTrue<BV>::post(Space* home, BV b0, BV b1, BV b2) {
00271     (void) new (home) TerOrTrue<BV>(home,b0,b1,b2);
00272     return ES_OK;
00273   }
00274 
00275   template <class BV>
00276   ExecStatus
00277   TerOrTrue<BV>::propagate(Space* home, ModEventDelta) {
00278 #define GECODE_INT_STATUS(S0,S1,S2) \
00279     ((BV::S0<<(2*BV::BITS))|(BV::S1<<(1*BV::BITS))|(BV::S2<<(0*BV::BITS)))
00280     switch ((x0.status() << (2*BV::BITS)) | (x1.status() << (1*BV::BITS)) |
00281             (x2.status() << (0*BV::BITS))) {
00282     case GECODE_INT_STATUS(NONE,NONE,NONE):
00283     case GECODE_INT_STATUS(NONE,NONE,ZERO):
00284     case GECODE_INT_STATUS(NONE,NONE,ONE):
00285       GECODE_NEVER;
00286     case GECODE_INT_STATUS(NONE,ZERO,NONE):
00287       std::swap(x1,x2); x1.subscribe(home,this,PC_BOOL_VAL);
00288       return ES_FIX;
00289     case GECODE_INT_STATUS(NONE,ZERO,ZERO):
00290       GECODE_ME_CHECK(x0.one_none(home)); break;
00291     case GECODE_INT_STATUS(NONE,ZERO,ONE):
00292     case GECODE_INT_STATUS(NONE,ONE,NONE):
00293     case GECODE_INT_STATUS(NONE,ONE,ZERO):
00294     case GECODE_INT_STATUS(NONE,ONE,ONE):
00295       x0.cancel(home,this,PC_BOOL_VAL); break;
00296     case GECODE_INT_STATUS(ZERO,NONE,NONE):
00297       std::swap(x0,x2); x0.subscribe(home,this,PC_BOOL_VAL);
00298       return ES_FIX;
00299     case GECODE_INT_STATUS(ZERO,NONE,ZERO):
00300       GECODE_ME_CHECK(x1.one_none(home)); break;
00301     case GECODE_INT_STATUS(ZERO,NONE,ONE):
00302       x1.cancel(home,this,PC_BOOL_VAL); break;
00303     case GECODE_INT_STATUS(ZERO,ZERO,NONE):
00304       GECODE_ME_CHECK(x2.one_none(home)); break;
00305     case GECODE_INT_STATUS(ZERO,ZERO,ZERO):
00306       return ES_FAILED;
00307     case GECODE_INT_STATUS(ZERO,ZERO,ONE):
00308     case GECODE_INT_STATUS(ZERO,ONE,NONE):
00309     case GECODE_INT_STATUS(ZERO,ONE,ZERO):
00310     case GECODE_INT_STATUS(ZERO,ONE,ONE):
00311       break;
00312     case GECODE_INT_STATUS(ONE,NONE,NONE):
00313     case GECODE_INT_STATUS(ONE,NONE,ZERO):
00314     case GECODE_INT_STATUS(ONE,NONE,ONE):
00315       x1.cancel(home,this,PC_BOOL_VAL); break;
00316     case GECODE_INT_STATUS(ONE,ZERO,NONE):
00317     case GECODE_INT_STATUS(ONE,ZERO,ZERO):
00318     case GECODE_INT_STATUS(ONE,ZERO,ONE):
00319     case GECODE_INT_STATUS(ONE,ONE,NONE):
00320     case GECODE_INT_STATUS(ONE,ONE,ZERO):
00321     case GECODE_INT_STATUS(ONE,ONE,ONE):
00322       break;
00323     default:
00324       GECODE_NEVER;
00325     }
00326     return ES_SUBSUMED(this,sizeof(*this));
00327 #undef GECODE_INT_STATUS
00328   }
00329 
00330   template <class BV>
00331   Support::Symbol
00332   TerOrTrue<BV>::ati(void) {
00333     return Reflection::mangle<BV>("Gecode::Int::Bool::TerOrTrue");
00334   }
00335 
00336   template <class BV>
00337   Reflection::ActorSpec
00338   TerOrTrue<BV>::spec(const Space* home, Reflection::VarMap& m) const {
00339     return BoolBinary<BV,BV>::spec(home, m, ati())
00340            << x2.spec(home, m);
00341   }
00342 
00343   template<class BV>
00344   void
00345   TerOrTrue<BV>::post(Space* home, Reflection::VarMap& vars,
00346                       const Reflection::ActorSpec& spec) {
00347     spec.checkArity(3);
00348     BV b0(home, vars, spec[0]);
00349     BV b1(home, vars, spec[1]);
00350     BV b2(home, vars, spec[2]);
00351     (void) new (home) TerOrTrue<BV>(home,b0,b1,b2);
00352   }
00353 
00354   /*
00355    * Boolean disjunction propagator (true)
00356    *
00357    */
00358 
00359   template <class BV>
00360   forceinline
00361   QuadOrTrue<BV>::QuadOrTrue(Space* home, BV b0, BV b1, BV b2, BV b3)
00362     : BoolBinary<BV,BV>(home,b0,b1), x2(b2), x3(b3) {}
00363 
00364   template<class BV>
00365   forceinline size_t
00366   QuadOrTrue<BV>::dispose(Space* home) {
00367     (void) BoolBinary<BV,BV>::dispose(home);
00368     return sizeof(*this);
00369   }
00370 
00371   template <class BV>
00372   forceinline
00373   QuadOrTrue<BV>::QuadOrTrue(Space* home, bool share, QuadOrTrue<BV>& p)
00374     : BoolBinary<BV,BV>(home,share,p) {
00375     x2.update(home,share,p.x2);
00376     x3.update(home,share,p.x3);
00377   }
00378 
00379   template <class BV>
00380   forceinline
00381   QuadOrTrue<BV>::QuadOrTrue(Space* home, bool share, Propagator& p,
00382                              BV b0, BV b1, BV b2, BV b3)
00383     : BoolBinary<BV,BV>(home,share,p,b0,b1) {
00384     x2.update(home,share,b2);
00385     x3.update(home,share,b3);
00386   }
00387 
00388   template <class BV>
00389   Actor*
00390   QuadOrTrue<BV>::copy(Space* home, bool share) {
00391     assert(x0.none() && x1.none());
00392     if (x2.one() || x3.one())
00393       return new (home) OrTrueSubsumed<BV>(home,share,*this,x0,x1);
00394     else if (x2.zero() && x3.zero())
00395       return new (home) BinOrTrue<BV,BV>(home,share,*this,x0,x1);
00396     else if (x2.zero())
00397       return new (home) TerOrTrue<BV>(home,share,*this,x0,x1,x3);
00398     else if (x3.zero())
00399       return new (home) TerOrTrue<BV>(home,share,*this,x0,x1,x2);
00400     else
00401       return new (home) QuadOrTrue<BV>(home,share,*this);
00402   }
00403 
00404   template <class BV>
00405   forceinline ExecStatus
00406   QuadOrTrue<BV>::post(Space* home, BV b0, BV b1, BV b2, BV b3) {
00407     (void) new (home) QuadOrTrue<BV>(home,b0,b1,b2,b3);
00408     return ES_OK;
00409   }
00410 
00411   template <class BV>
00412   ExecStatus
00413   QuadOrTrue<BV>::propagate(Space* home, ModEventDelta) {
00414 #define GECODE_INT_STATUS(S0,S1,S2,S3)                        \
00415     ((BV::S0 << (3*BV::BITS)) | (BV::S1 << (2*BV::BITS)) |    \
00416      (BV::S2 << (1*BV::BITS)) | (BV::S3 << (0*BV::BITS)))
00417     switch ((x0.status() << (3*BV::BITS)) | (x1.status() << (2*BV::BITS)) |
00418             (x2.status() << (1*BV::BITS)) | (x3.status() << (0*BV::BITS))) {
00419     case GECODE_INT_STATUS(NONE,NONE,NONE,NONE):
00420     case GECODE_INT_STATUS(NONE,NONE,NONE,ZERO):
00421     case GECODE_INT_STATUS(NONE,NONE,NONE,ONE):
00422     case GECODE_INT_STATUS(NONE,NONE,ZERO,NONE):
00423     case GECODE_INT_STATUS(NONE,NONE,ZERO,ZERO):
00424     case GECODE_INT_STATUS(NONE,NONE,ZERO,ONE):
00425     case GECODE_INT_STATUS(NONE,NONE,ONE,NONE):
00426     case GECODE_INT_STATUS(NONE,NONE,ONE,ZERO):
00427     case GECODE_INT_STATUS(NONE,NONE,ONE,ONE):
00428       GECODE_NEVER;
00429     case GECODE_INT_STATUS(NONE,ZERO,NONE,NONE):
00430     case GECODE_INT_STATUS(NONE,ZERO,NONE,ZERO):
00431       std::swap(x1,x2); x1.subscribe(home,this,PC_BOOL_VAL,false);
00432       return ES_FIX;
00433     case GECODE_INT_STATUS(NONE,ZERO,NONE,ONE):
00434       x0.cancel(home,this,PC_BOOL_VAL); break;
00435     case GECODE_INT_STATUS(NONE,ZERO,ZERO,NONE):
00436       std::swap(x1,x3); x1.subscribe(home,this,PC_BOOL_VAL,false);
00437       return ES_FIX;
00438     case GECODE_INT_STATUS(NONE,ZERO,ZERO,ZERO):
00439       GECODE_ME_CHECK(x0.one_none(home)); break;
00440     case GECODE_INT_STATUS(NONE,ZERO,ZERO,ONE):
00441     case GECODE_INT_STATUS(NONE,ZERO,ONE,NONE):
00442     case GECODE_INT_STATUS(NONE,ZERO,ONE,ZERO):
00443     case GECODE_INT_STATUS(NONE,ZERO,ONE,ONE):
00444     case GECODE_INT_STATUS(NONE,ONE,NONE,NONE):
00445     case GECODE_INT_STATUS(NONE,ONE,NONE,ZERO):
00446     case GECODE_INT_STATUS(NONE,ONE,NONE,ONE):
00447     case GECODE_INT_STATUS(NONE,ONE,ZERO,NONE):
00448     case GECODE_INT_STATUS(NONE,ONE,ZERO,ZERO):
00449     case GECODE_INT_STATUS(NONE,ONE,ZERO,ONE):
00450     case GECODE_INT_STATUS(NONE,ONE,ONE,NONE):
00451     case GECODE_INT_STATUS(NONE,ONE,ONE,ZERO):
00452     case GECODE_INT_STATUS(NONE,ONE,ONE,ONE):
00453       x0.cancel(home,this,PC_BOOL_VAL); break;
00454     case GECODE_INT_STATUS(ZERO,NONE,NONE,NONE):
00455     case GECODE_INT_STATUS(ZERO,NONE,NONE,ZERO):
00456       std::swap(x0,x2); x0.subscribe(home,this,PC_BOOL_VAL,false);
00457       return ES_FIX;
00458     case GECODE_INT_STATUS(ZERO,NONE,NONE,ONE):
00459       x1.cancel(home,this,PC_BOOL_VAL); break;
00460     case GECODE_INT_STATUS(ZERO,NONE,ZERO,NONE):
00461       std::swap(x0,x3); x0.subscribe(home,this,PC_BOOL_VAL,false);
00462       return ES_FIX;
00463     case GECODE_INT_STATUS(ZERO,NONE,ZERO,ZERO):
00464       GECODE_ME_CHECK(x1.one_none(home)); break;
00465     case GECODE_INT_STATUS(ZERO,NONE,ZERO,ONE):
00466       x1.cancel(home,this,PC_BOOL_VAL); break;
00467     case GECODE_INT_STATUS(ZERO,NONE,ONE,NONE):
00468     case GECODE_INT_STATUS(ZERO,NONE,ONE,ZERO):
00469     case GECODE_INT_STATUS(ZERO,NONE,ONE,ONE):
00470       x1.cancel(home,this,PC_BOOL_VAL); break;
00471     case GECODE_INT_STATUS(ZERO,ZERO,NONE,NONE):
00472       std::swap(x0,x2); x0.subscribe(home,this,PC_BOOL_VAL,false);
00473       std::swap(x1,x3); x1.subscribe(home,this,PC_BOOL_VAL,false);
00474       return ES_FIX;
00475     case GECODE_INT_STATUS(ZERO,ZERO,NONE,ZERO):
00476       GECODE_ME_CHECK(x2.one_none(home)); break;
00477     case GECODE_INT_STATUS(ZERO,ZERO,NONE,ONE):
00478       break;
00479     case GECODE_INT_STATUS(ZERO,ZERO,ZERO,NONE):
00480       GECODE_ME_CHECK(x3.one_none(home)); break;
00481     case GECODE_INT_STATUS(ZERO,ZERO,ZERO,ZERO):
00482       return ES_FAILED;
00483     case GECODE_INT_STATUS(ZERO,ZERO,ZERO,ONE):
00484     case GECODE_INT_STATUS(ZERO,ZERO,ONE,NONE):
00485     case GECODE_INT_STATUS(ZERO,ZERO,ONE,ZERO):
00486     case GECODE_INT_STATUS(ZERO,ZERO,ONE,ONE):
00487     case GECODE_INT_STATUS(ZERO,ONE,NONE,NONE):
00488     case GECODE_INT_STATUS(ZERO,ONE,NONE,ZERO):
00489     case GECODE_INT_STATUS(ZERO,ONE,NONE,ONE):
00490     case GECODE_INT_STATUS(ZERO,ONE,ZERO,NONE):
00491     case GECODE_INT_STATUS(ZERO,ONE,ZERO,ZERO):
00492     case GECODE_INT_STATUS(ZERO,ONE,ZERO,ONE):
00493     case GECODE_INT_STATUS(ZERO,ONE,ONE,NONE):
00494     case GECODE_INT_STATUS(ZERO,ONE,ONE,ZERO):
00495     case GECODE_INT_STATUS(ZERO,ONE,ONE,ONE):
00496       break;
00497     case GECODE_INT_STATUS(ONE,NONE,NONE,NONE):
00498     case GECODE_INT_STATUS(ONE,NONE,NONE,ZERO):
00499     case GECODE_INT_STATUS(ONE,NONE,NONE,ONE):
00500     case GECODE_INT_STATUS(ONE,NONE,ZERO,NONE):
00501     case GECODE_INT_STATUS(ONE,NONE,ZERO,ZERO):
00502     case GECODE_INT_STATUS(ONE,NONE,ZERO,ONE):
00503     case GECODE_INT_STATUS(ONE,NONE,ONE,NONE):
00504     case GECODE_INT_STATUS(ONE,NONE,ONE,ZERO):
00505     case GECODE_INT_STATUS(ONE,NONE,ONE,ONE):
00506       x1.cancel(home,this,PC_BOOL_VAL); break;
00507     case GECODE_INT_STATUS(ONE,ZERO,NONE,NONE):
00508     case GECODE_INT_STATUS(ONE,ZERO,NONE,ZERO):
00509     case GECODE_INT_STATUS(ONE,ZERO,NONE,ONE):
00510     case GECODE_INT_STATUS(ONE,ZERO,ZERO,NONE):
00511     case GECODE_INT_STATUS(ONE,ZERO,ZERO,ZERO):
00512     case GECODE_INT_STATUS(ONE,ZERO,ZERO,ONE):
00513     case GECODE_INT_STATUS(ONE,ZERO,ONE,NONE):
00514     case GECODE_INT_STATUS(ONE,ZERO,ONE,ZERO):
00515     case GECODE_INT_STATUS(ONE,ZERO,ONE,ONE):
00516     case GECODE_INT_STATUS(ONE,ONE,NONE,NONE):
00517     case GECODE_INT_STATUS(ONE,ONE,NONE,ZERO):
00518     case GECODE_INT_STATUS(ONE,ONE,NONE,ONE):
00519     case GECODE_INT_STATUS(ONE,ONE,ZERO,NONE):
00520     case GECODE_INT_STATUS(ONE,ONE,ZERO,ZERO):
00521     case GECODE_INT_STATUS(ONE,ONE,ZERO,ONE):
00522     case GECODE_INT_STATUS(ONE,ONE,ONE,NONE):
00523     case GECODE_INT_STATUS(ONE,ONE,ONE,ZERO):
00524     case GECODE_INT_STATUS(ONE,ONE,ONE,ONE):
00525       break;
00526     default:
00527       GECODE_NEVER;
00528     }
00529     return ES_SUBSUMED(this,sizeof(*this));
00530 #undef GECODE_INT_STATUS
00531   }
00532 
00533   template <class BV>
00534   Support::Symbol
00535   QuadOrTrue<BV>::ati(void) {
00536     return Reflection::mangle<BV>("Gecode::Int::Bool::QuadOrTrue");
00537   }
00538 
00539   template <class BV>
00540   Reflection::ActorSpec
00541   QuadOrTrue<BV>::spec(const Space* home, Reflection::VarMap& m) const {
00542     return BoolBinary<BV,BV>::spec(home, m, ati())
00543       << x2.spec(home, m)
00544       << x3.spec(home, m);
00545   }
00546 
00547   template<class BV>
00548   void
00549   QuadOrTrue<BV>::post(Space* home, Reflection::VarMap& vars,
00550                        const Reflection::ActorSpec& spec) {
00551     spec.checkArity(4);
00552     BV b0(home, vars, spec[0]);
00553     BV b1(home, vars, spec[1]);
00554     BV b2(home, vars, spec[2]);
00555     BV b3(home, vars, spec[3]);
00556     (void) new (home) QuadOrTrue<BV>(home,b0,b1,b2,b3);
00557   }
00558 
00559   /*
00560    * Boolean disjunction propagator
00561    *
00562    */
00563 
00564   template <class BVA, class BVB, class BVC>
00565   forceinline
00566   Or<BVA,BVB,BVC>::Or(Space* home, BVA b0, BVB b1, BVC b2)
00567     : BoolTernary<BVA,BVB,BVC>(home,b0,b1,b2) {}
00568 
00569   template <class BVA, class BVB, class BVC>
00570   forceinline
00571   Or<BVA,BVB,BVC>::Or(Space* home, bool share, Or<BVA,BVB,BVC>& p)
00572     : BoolTernary<BVA,BVB,BVC>(home,share,p) {}
00573 
00574   template <class BVA, class BVB, class BVC>
00575   forceinline
00576   Or<BVA,BVB,BVC>::Or(Space* home, bool share, Propagator& p,
00577                         BVA b0, BVB b1, BVC b2)
00578     : BoolTernary<BVA,BVB,BVC>(home,share,p,b0,b1,b2) {}
00579 
00580   template <class BVA, class BVB, class BVC>
00581   Actor*
00582   Or<BVA,BVB,BVC>::copy(Space* home, bool share) {
00583     if (x2.one()) {
00584       assert(x0.none() && x1.none());
00585       return new (home) BinOrTrue<BVA,BVB>(home,share,*this,x0,x1);
00586     } else if (x0.zero()) {
00587       assert(x1.none() && x2.none());
00588       return new (home) Eq<BVB,BVC>(home,share,*this,x1,x2);
00589     } else if (x1.zero()) {
00590       assert(x0.none() && x2.none());
00591       return new (home) Eq<BVA,BVC>(home,share,*this,x0,x2);
00592     } else {
00593       return new (home) Or<BVA,BVB,BVC>(home,share,*this);
00594     }
00595   }
00596 
00597   template <class BVA, class BVB, class BVC>
00598   inline ExecStatus
00599   Or<BVA,BVB,BVC>::post(Space* home, BVA b0, BVB b1, BVC b2) {
00600     if (b2.zero()) {
00601       GECODE_ME_CHECK(b0.zero(home));
00602       GECODE_ME_CHECK(b1.zero(home));
00603     } else if (b2.one()) {
00604       return BinOrTrue<BVA,BVB>::post(home,b0,b1);
00605     } else {
00606       switch (bool_test(b0,b1)) {
00607       case BT_SAME:
00608         return Eq<BVA,BVC>::post(home,b0,b2);
00609       case BT_COMP:
00610         GECODE_ME_CHECK(b2.one(home));
00611         break;
00612       case BT_NONE:
00613         if (b0.one() || b1.one()) {
00614           GECODE_ME_CHECK(b2.one(home));
00615         } else if (b0.zero()) {
00616           return Eq<BVB,BVC>::post(home,b1,b2);
00617         } else if (b1.zero()) {
00618           return Eq<BVA,BVC>::post(home,b0,b2);
00619         } else {
00620           (void) new (home) Or<BVA,BVB,BVC>(home,b0,b1,b2);
00621         }
00622         break;
00623       default: GECODE_NEVER;
00624       }
00625     }
00626     return ES_OK;
00627   }
00628 
00629   template <class BVA, class BVB, class BVC>
00630   ExecStatus
00631   Or<BVA,BVB,BVC>::propagate(Space* home, ModEventDelta) {
00632 #define GECODE_INT_STATUS(S0,S1,S2) \
00633   ((BVA::S0<<(2*BVA::BITS))|(BVB::S1<<(1*BVB::BITS))|(BVC::S2<<(0*BVC::BITS)))
00634     switch ((x0.status() << (2*BVA::BITS)) | (x1.status() << (1*BVB::BITS)) |
00635             (x2.status() << (0*BVC::BITS))) {
00636     case GECODE_INT_STATUS(NONE,NONE,NONE):
00637       GECODE_NEVER;
00638     case GECODE_INT_STATUS(NONE,NONE,ZERO):
00639       GECODE_ME_CHECK(x0.zero_none(home)); 
00640       GECODE_ME_CHECK(x1.zero_none(home)); 
00641       break;
00642     case GECODE_INT_STATUS(NONE,NONE,ONE):
00643       return ES_FIX;
00644     case GECODE_INT_STATUS(NONE,ZERO,NONE):
00645       switch (bool_test(x0,x2)) {
00646       case BT_SAME: return ES_SUBSUMED(this,home);
00647       case BT_COMP: return ES_FAILED;
00648       case BT_NONE: return ES_FIX;
00649       default: GECODE_NEVER;
00650       }
00651       GECODE_NEVER;
00652     case GECODE_INT_STATUS(NONE,ZERO,ZERO):
00653       GECODE_ME_CHECK(x0.zero_none(home)); break;
00654     case GECODE_INT_STATUS(NONE,ZERO,ONE):
00655       GECODE_ME_CHECK(x0.one_none(home)); break;
00656     case GECODE_INT_STATUS(NONE,ONE,NONE):
00657       x0.cancel(home,this,PC_BOOL_VAL); 
00658       GECODE_ME_CHECK(x2.one_none(home)); 
00659       break;
00660     case GECODE_INT_STATUS(NONE,ONE,ZERO):
00661       return ES_FAILED;      
00662     case GECODE_INT_STATUS(NONE,ONE,ONE):
00663       x0.cancel(home,this,PC_BOOL_VAL); break;
00664     case GECODE_INT_STATUS(ZERO,NONE,NONE):
00665       switch (bool_test(x1,x2)) {
00666       case BT_SAME: return ES_SUBSUMED(this,home);
00667       case BT_COMP: return ES_FAILED;
00668       case BT_NONE: return ES_FIX;
00669       default: GECODE_NEVER;
00670       }
00671       GECODE_NEVER;
00672     case GECODE_INT_STATUS(ZERO,NONE,ZERO):
00673       GECODE_ME_CHECK(x1.zero_none(home)); break;
00674     case GECODE_INT_STATUS(ZERO,NONE,ONE):
00675       GECODE_ME_CHECK(x1.one_none(home)); break;
00676     case GECODE_INT_STATUS(ZERO,ZERO,NONE):
00677       GECODE_ME_CHECK(x2.zero_none(home)); break;
00678     case GECODE_INT_STATUS(ZERO,ZERO,ZERO):
00679       break;
00680     case GECODE_INT_STATUS(ZERO,ZERO,ONE):
00681       return ES_FAILED;
00682     case GECODE_INT_STATUS(ZERO,ONE,NONE):
00683       GECODE_ME_CHECK(x2.one_none(home)); break;
00684     case GECODE_INT_STATUS(ZERO,ONE,ZERO):
00685       return ES_FAILED;
00686     case GECODE_INT_STATUS(ZERO,ONE,ONE):
00687       break;
00688     case GECODE_INT_STATUS(ONE,NONE,NONE):
00689       x1.cancel(home,this,PC_BOOL_VAL); 
00690       GECODE_ME_CHECK(x2.one_none(home)); break;
00691     case GECODE_INT_STATUS(ONE,NONE,ZERO):
00692       return ES_FAILED;
00693     case GECODE_INT_STATUS(ONE,NONE,ONE):
00694       x1.cancel(home,this,PC_BOOL_VAL); break;
00695     case GECODE_INT_STATUS(ONE,ZERO,NONE):
00696       GECODE_ME_CHECK(x2.one_none(home)); break;
00697     case GECODE_INT_STATUS(ONE,ZERO,ZERO):
00698       return ES_FAILED;
00699     case GECODE_INT_STATUS(ONE,ZERO,ONE):
00700       break;
00701     case GECODE_INT_STATUS(ONE,ONE,NONE):
00702       GECODE_ME_CHECK(x2.one_none(home)); break;
00703     case GECODE_INT_STATUS(ONE,ONE,ZERO):
00704       return ES_FAILED;
00705     case GECODE_INT_STATUS(ONE,ONE,ONE):
00706       break;
00707     default:
00708       GECODE_NEVER;
00709     }
00710     return ES_SUBSUMED(this,sizeof(*this));
00711 #undef GECODE_INT_STATUS
00712   }
00713 
00714   template <class BVA, class BVB, class BVC>
00715   Support::Symbol
00716   Or<BVA,BVB,BVC>::ati(void) {
00717     return Reflection::mangle<BVA,BVB,BVC>("Gecode::Int::Bool::Or");
00718   }
00719 
00720   template <class BVA, class BVB, class BVC>
00721   Reflection::ActorSpec
00722   Or<BVA,BVB,BVC>::spec(const Space* home, Reflection::VarMap& m) const {
00723     return BoolTernary<BVA,BVB,BVC>::spec(home, m, ati());      
00724   }
00725 
00726   template<class BVA, class BVB, class BVC>
00727   void
00728   Or<BVA,BVB,BVC>::post(Space* home, Reflection::VarMap& vars,
00729                         const Reflection::ActorSpec& spec) {
00730     spec.checkArity(3);
00731     BVA b0(home, vars, spec[0]);
00732     BVB b1(home, vars, spec[1]);
00733     BVB b2(home, vars, spec[2]);
00734     (void) new (home) Or<BVA,BVB,BVC>(home,b0,b1,b2);
00735   }
00736 
00737   /*
00738    * N-ary Boolean disjunction propagator (true)
00739    *
00740    */
00741 
00742   template<class BV>
00743   forceinline
00744   NaryOrTrue<BV>::NaryOrTrue(Space* home, ViewArray<BV>& b)
00745     : BinaryPropagator<BV,PC_BOOL_VAL>(home,
00746                                       b[b.size()-2],
00747                                       b[b.size()-1]), x(b) {
00748     assert(x.size() > 2);
00749     x.size(x.size()-2);
00750   }
00751 
00752   template<class BV>
00753   PropCost
00754   NaryOrTrue<BV>::cost(ModEventDelta) const {
00755     return PC_BINARY_LO;
00756   }
00757 
00758   template<class BV>
00759   forceinline
00760   NaryOrTrue<BV>::NaryOrTrue(Space* home, bool share, NaryOrTrue<BV>& p)
00761     : BinaryPropagator<BV,PC_BOOL_VAL>(home,share,p) {
00762     x.update(home,share,p.x);
00763   }
00764 
00765   template<class BV>
00766   Actor*
00767   NaryOrTrue<BV>::copy(Space* home, bool share) {
00768     int n = x.size();
00769     if (n > 0) {
00770       // Check whether the original has already been purged
00771       if (x[0].one()) {
00772         x.size(1); // The rest does not matter any longer
00773         return new (home) OrTrueSubsumed<BV>(home,share,*this,x0,x1);
00774       }
00775       // Eliminate all zeros and find a one
00776       for (int i=n; i--; )
00777         if (x[i].one()) {
00778           // Only keep the one
00779           x[0]=x[i]; x.size(1);
00780           return new (home) OrTrueSubsumed<BV>(home,share,*this,x0,x1);
00781         } else if (x[i].zero()) {
00782           // Eliminate the zero
00783           x[i]=x[--n];
00784         }
00785       x.size(n);
00786     }
00787     switch (n) {
00788     case 0:
00789       return new (home) BinOrTrue<BV,BV>(home,share,*this,x0,x1);
00790     case 1:
00791       return new (home) TerOrTrue<BV>(home,share,*this,x0,x1,x[0]);
00792     case 2:
00793       return new (home) QuadOrTrue<BV>(home,share,*this,x0,x1,x[0],x[1]);
00794     default:
00795       return new (home) NaryOrTrue<BV>(home,share,*this);
00796     }
00797   }
00798 
00799   template<class BV>
00800   inline ExecStatus
00801   NaryOrTrue<BV>::post(Space* home, ViewArray<BV>& b) {
00802     for (int i=b.size(); i--; )
00803       if (b[i].one())
00804         return ES_OK;
00805       else if (b[i].zero())
00806         b.move_lst(i);
00807     if (b.size() == 0)
00808       return ES_FAILED;
00809     if (b.size() == 1) {
00810       GECODE_ME_CHECK(b[0].one(home));
00811     } else if (b.size() == 2) {
00812        return BinOrTrue<BV,BV>::post(home,b[0],b[1]);
00813     } else if (b.size() == 3) {
00814        return TerOrTrue<BV>::post(home,b[0],b[1],b[2]);
00815     } else if (b.size() == 4) {
00816        return QuadOrTrue<BV>::post(home,b[0],b[1],b[2],b[3]);
00817     } else {
00818       (void) new (home) NaryOrTrue(home,b);
00819     }
00820     return ES_OK;
00821   }
00822 
00823   template<class BV>
00824   forceinline ExecStatus
00825   NaryOrTrue<BV>::resubscribe(Space* home, BV& x0, BV x1) {
00826     if (x0.zero()) {
00827       int n = x.size();
00828       for (int i=n; i--; )
00829         if (x[i].one()) {
00830           x.size(n);
00831           return ES_SUBSUMED(this,home);
00832         } else if (x[i].zero()) {
00833           x[i] = x[--n];
00834         } else {
00835           // New unassigned view found
00836           assert(!x[i].zero() && !x[i].one());
00837           // Rewrite if there is just one view left
00838           if (i == 0) {
00839             BV y = x[0]; x.size(0);
00840             GECODE_REWRITE(this,(BinOrTrue<BV,BV>::post(home,x1,y)));
00841           }
00842           // Move to x0 and subscribe
00843           x0=x[i]; x[i]=x[--n]; 
00844           x.size(n);
00845           x0.subscribe(home,this,PC_BOOL_VAL,false);
00846           return ES_FIX;
00847         }
00848       // All views have been assigned!
00849       x.size(0);
00850       GECODE_ME_CHECK(x1.one(home));
00851       return ES_SUBSUMED(this,sizeof(*this));
00852     }
00853     return ES_FIX;
00854   }
00855 
00856   template<class BV>
00857   ExecStatus
00858   NaryOrTrue<BV>::propagate(Space* home, ModEventDelta) {
00859     if (x0.one() || x1.one())
00860       return ES_SUBSUMED(this,home);
00861     GECODE_ES_CHECK(resubscribe(home,x0,x1));
00862     GECODE_ES_CHECK(resubscribe(home,x1,x0));
00863     return ES_FIX;
00864   }
00865 
00866   template <class BV>
00867   Support::Symbol
00868   NaryOrTrue<BV>::ati(void) {
00869     return Reflection::mangle<BV>("Gecode::Int::Bool::NaryOrTrue");
00870   }
00871 
00872   template<class BV>
00873   Reflection::ActorSpec
00874   NaryOrTrue<BV>::spec(const Space* home, Reflection::VarMap& m) const {
00875     return BinaryPropagator<BV,PC_BOOL_VAL>::spec(home, m, ati())
00876       << x.spec(home, m);
00877   }
00878 
00879   template<class BV>
00880   void
00881   NaryOrTrue<BV>::post(Space* home, Reflection::VarMap& vars,
00882                        const Reflection::ActorSpec& spec) {
00883     spec.checkArity(3);
00884     BV b0(home, vars, spec[0]);
00885     BV b1(home, vars, spec[1]);
00886     ViewArray<BV> b(home, vars, spec[2]);
00887     ViewArray<BV> bb(home, b.size()+2);
00888     for (int i=b.size(); i--;)
00889       bb[i] = b[i];
00890     bb[b.size()]   = b0;
00891     bb[b.size()+1] = b1;
00892     (void) new (home) NaryOrTrue<BV>(home,bb);
00893   }
00894 
00895   /*
00896    * N-ary Boolean disjunction propagator
00897    *
00898    */
00899 
00900   template<class BV>
00901   forceinline
00902   NaryOr<BV>::NaryOr(Space* home, ViewArray<BV>& b, BV c)
00903     : NaryOnePropagator<BV,PC_BOOL_VAL>(home,b,c) {}
00904 
00905   template<class BV>
00906   forceinline
00907   NaryOr<BV>::NaryOr(Space* home, bool share, NaryOr<BV>& p)
00908     : NaryOnePropagator<BV,PC_BOOL_VAL>(home,share,p) {}
00909 
00910   template<class BV>
00911   Actor*
00912   NaryOr<BV>::copy(Space* home, bool share) {
00913     if (x.size() == 1)
00914       return new (home) Eq<BV,BV>(home,share,*this,x[0],y);
00915     if (x.size() == 2)
00916       return new (home) Or<BV,BV,BV>(home,share,*this,x[0],x[1],y);
00917     return new (home) NaryOr<BV>(home,share,*this);
00918   }
00919 
00920   template<class BV>
00921   inline ExecStatus
00922   NaryOr<BV>::post(Space* home, ViewArray<BV>& b, BV c) {
00923     if (c.one())
00924       return NaryOrTrue<BV>::post(home,b);
00925     if (c.zero()) {
00926       for (int i=b.size(); i--; )
00927         GECODE_ME_CHECK(b[i].zero(home));
00928       return ES_OK;
00929     }
00930     for (int i=b.size(); i--; )
00931       if (b[i].one()) {
00932         GECODE_ME_CHECK(c.one_none(home));
00933         return ES_OK;
00934       } else if (b[i].zero()) {
00935         b.move_lst(i);
00936       }
00937     if (b.size() == 0) {
00938       GECODE_ME_CHECK(c.zero_none(home));
00939     } else if (b.size() == 1) {
00940       return Eq<BV,BV>::post(home,b[0],c);
00941     } else if (b.size() == 2) {
00942       return Or<BV,BV,BV>::post(home,b[0],b[1],c);
00943     } else {
00944       (void) new (home) NaryOr(home,b,c);
00945     }
00946     return ES_OK;
00947   }
00948 
00949   template<class BV>
00950   ExecStatus
00951   NaryOr<BV>::propagate(Space* home, ModEventDelta) {
00952     if (y.zero()) {
00953       for (int i = x.size(); i--; )
00954         GECODE_ME_CHECK(x[i].zero(home));
00955       return ES_SUBSUMED(this,sizeof(*this));
00956     }
00957     if (y.one())
00958       GECODE_REWRITE(this,NaryOrTrue<BV>::post(home,x));
00959     for (int i = x.size(); i--; ) {
00960       if (x[i].one()) {
00961         GECODE_ME_CHECK(y.one_none(home));
00962         return ES_SUBSUMED(this,home);
00963       }
00964       if (x[i].zero())
00965         x.move_lst(i);
00966     }
00967     if (x.size() == 0) {
00968       GECODE_ME_CHECK(y.zero_none(home));
00969       return ES_SUBSUMED(this,sizeof(*this));
00970     }
00971     return ES_FIX;
00972   }
00973 
00974   template <class BV>
00975   Support::Symbol
00976   NaryOr<BV>::ati(void) {
00977     return Reflection::mangle<BV>("Gecode::Int::Bool::NaryOr");
00978   }
00979 
00980   template<class BV>
00981   Reflection::ActorSpec
00982   NaryOr<BV>::spec(const Space* home, Reflection::VarMap& m) const {
00983     return NaryOnePropagator<BV,PC_BOOL_VAL>::spec(home, m, ati());      
00984   }
00985 
00986   template<class BV>
00987   void
00988   NaryOr<BV>::post(Space* home, Reflection::VarMap& vars,
00989                    const Reflection::ActorSpec& spec) {
00990     spec.checkArity(2);
00991     ViewArray<BV> b(home, vars, spec[0]);
00992     BV b0(home, vars, spec[1]);
00993     (void) new (home) NaryOr<BV>(home,b,b0);
00994   }
00995   
00996 
00997 }}}
00998 
00999 // STATISTICS: int-prop
01000