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 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
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
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
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
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
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
00638 for (int i=n; i--; )
00639 if (x[i].one()) {
00640
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
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
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
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
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
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(!x.shared());
00771 if (y.one())
00772 return NaryOrTrue<VX>::post(home,x);
00773 if (y.zero()) {
00774 for (int 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
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=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
00844 for (int i = x.size(); i--; )
00845 GECODE_ME_CHECK(x[i].zero(home));
00846 } else if (n_zero == x.size()) {
00847
00848 GECODE_ME_CHECK(y.zero_none(home));
00849 } else {
00850
00851 GECODE_ME_CHECK(y.one_none(home));
00852 }
00853 return home.ES_SUBSUMED(*this);
00854 }
00855
00856 }}}
00857
00858
00859