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