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 Rel {
00039
00040
00041
00042
00043
00044
00045 template<class View0, class View1>
00046 forceinline
00047 EqBnd<View0,View1>::EqBnd(Home home, View0 x0, View1 x1)
00048 : MixBinaryPropagator<View0,PC_INT_BND,View1,PC_INT_BND>(home,x0,x1) {}
00049
00050 template<class View0, class View1>
00051 ExecStatus
00052 EqBnd<View0,View1>::post(Home home, View0 x0, View1 x1){
00053 if (x0.assigned()) {
00054 GECODE_ME_CHECK(x1.eq(home,x0.val()));
00055 } else if (x1.assigned()) {
00056 GECODE_ME_CHECK(x0.eq(home,x1.val()));
00057 } else if (!same(x0,x1)) {
00058 GECODE_ME_CHECK(x0.lq(home,x1.max()));
00059 GECODE_ME_CHECK(x1.lq(home,x0.max()));
00060 GECODE_ME_CHECK(x0.gq(home,x1.min()));
00061 GECODE_ME_CHECK(x1.gq(home,x0.min()));
00062 (void) new (home) EqBnd<View0,View1>(home,x0,x1);
00063 }
00064 return ES_OK;
00065 }
00066
00067 template<class View0, class View1>
00068 forceinline
00069 EqBnd<View0,View1>::EqBnd(Space& home, bool share, EqBnd<View0,View1>& p)
00070 : MixBinaryPropagator<View0,PC_INT_BND,View1,PC_INT_BND>(home,share,p) {}
00071
00072 template<class View0, class View1>
00073 forceinline
00074 EqBnd<View0,View1>::EqBnd(Space& home, bool share, Propagator& p,
00075 View0 x0, View1 x1)
00076 : MixBinaryPropagator<View0,PC_INT_BND,View1,PC_INT_BND>(home,share,p,
00077 x0,x1) {}
00078
00079 template<class View0, class View1>
00080 Actor*
00081 EqBnd<View0,View1>::copy(Space& home, bool share) {
00082 return new (home) EqBnd<View0,View1>(home,share,*this);
00083 }
00084
00085 template<class View0, class View1>
00086 ExecStatus
00087 EqBnd<View0,View1>::propagate(Space& home, const ModEventDelta&) {
00088 if (x0.assigned()) {
00089 GECODE_ME_CHECK(x1.eq(home,x0.val()));
00090 } else if (x1.assigned()) {
00091 GECODE_ME_CHECK(x0.eq(home,x1.val()));
00092 } else {
00093 do {
00094 GECODE_ME_CHECK(x0.gq(home,x1.min()));
00095 GECODE_ME_CHECK(x1.gq(home,x0.min()));
00096 } while (x0.min() != x1.min());
00097 do {
00098 GECODE_ME_CHECK(x0.lq(home,x1.max()));
00099 GECODE_ME_CHECK(x1.lq(home,x0.max()));
00100 } while (x0.max() != x1.max());
00101 if (!x0.assigned())
00102 return ES_FIX;
00103 }
00104 assert(x0.assigned() && x1.assigned());
00105 return home.ES_SUBSUMED(*this);
00106 }
00107
00108
00109
00110
00111
00112
00113 template<class View0, class View1>
00114 forceinline
00115 EqDom<View0,View1>::EqDom(Home home, View0 x0, View1 x1)
00116 : MixBinaryPropagator<View0,PC_INT_DOM,View1,PC_INT_DOM>(home,x0,x1) {}
00117
00118 template<class View0, class View1>
00119 ExecStatus
00120 EqDom<View0,View1>::post(Home home, View0 x0, View1 x1){
00121 if (x0.assigned()) {
00122 GECODE_ME_CHECK(x1.eq(home,x0.val()));
00123 } else if (x1.assigned()) {
00124 GECODE_ME_CHECK(x0.eq(home,x1.val()));
00125 } else if (!same(x0,x1)) {
00126 GECODE_ME_CHECK(x0.lq(home,x1.max()));
00127 GECODE_ME_CHECK(x1.lq(home,x0.max()));
00128 GECODE_ME_CHECK(x0.gq(home,x1.min()));
00129 GECODE_ME_CHECK(x1.gq(home,x0.min()));
00130 (void) new (home) EqDom<View0,View1>(home,x0,x1);
00131 }
00132 return ES_OK;
00133 }
00134
00135
00136 template<class View0, class View1>
00137 forceinline
00138 EqDom<View0,View1>::EqDom(Space& home, bool share, EqDom<View0,View1>& p)
00139 : MixBinaryPropagator<View0,PC_INT_DOM,View1,PC_INT_DOM>(home,share,p) {}
00140
00141 template<class View0, class View1>
00142 forceinline
00143 EqDom<View0,View1>::EqDom(Space& home, bool share, Propagator& p,
00144 View0 x0, View1 x1)
00145 : MixBinaryPropagator<View0,PC_INT_DOM,View1,PC_INT_DOM>(home,share,p,
00146 x0,x1) {}
00147
00148 template<class View0, class View1>
00149 Actor*
00150 EqDom<View0,View1>::copy(Space& home, bool share) {
00151 return new (home) EqDom<View0,View1>(home,share,*this);
00152 }
00153
00154 template<class View0, class View1>
00155 PropCost
00156 EqDom<View0,View1>::cost(const Space&, const ModEventDelta& med) const {
00157 if ((View0::me(med) == ME_INT_VAL) || (View1::me(med) == ME_INT_VAL))
00158 return PropCost::unary(PropCost::LO);
00159 else if ((View0::me(med) == ME_INT_DOM) || (View1::me(med) == ME_INT_DOM))
00160 return PropCost::binary(PropCost::LO);
00161 else
00162 return PropCost::binary(PropCost::HI);
00163 }
00164
00165 template<class View0, class View1>
00166 ExecStatus
00167 EqDom<View0,View1>::propagate(Space& home, const ModEventDelta& med) {
00168 if (x0.assigned()) {
00169 GECODE_ME_CHECK(x1.eq(home,x0.val()));
00170 return home.ES_SUBSUMED(*this);
00171 }
00172 if (x1.assigned()) {
00173 GECODE_ME_CHECK(x0.eq(home,x1.val()));
00174 return home.ES_SUBSUMED(*this);
00175 }
00176 if ((View0::me(med) != ME_INT_DOM) && (View1::me(med) != ME_INT_DOM)) {
00177 do {
00178 GECODE_ME_CHECK(x0.gq(home,x1.min()));
00179 GECODE_ME_CHECK(x1.gq(home,x0.min()));
00180 } while (x0.min() != x1.min());
00181 do {
00182 GECODE_ME_CHECK(x0.lq(home,x1.max()));
00183 GECODE_ME_CHECK(x1.lq(home,x0.max()));
00184 } while (x0.max() != x1.max());
00185 if (x0.assigned())
00186 return home.ES_SUBSUMED(*this);
00187 if (x0.range() && x1.range())
00188 return ES_FIX;
00189 return home.ES_FIX_PARTIAL(*this,View0::med(ME_INT_DOM));
00190 }
00191 ViewRanges<View0> r0(x0);
00192 GECODE_ME_CHECK(x1.inter_r(home,r0,shared(x0,x1)));
00193 ViewRanges<View1> r1(x1);
00194 GECODE_ME_CHECK(x0.narrow_r(home,r1,shared(x0,x1)));
00195 if (x0.assigned())
00196 return home.ES_SUBSUMED(*this);
00197 return ES_FIX;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207 template<class View>
00208 forceinline
00209 NaryEqDom<View>::NaryEqDom(Home home, ViewArray<View>& x)
00210 : NaryPropagator<View,PC_INT_DOM>(home,x) {}
00211
00212 template<class View>
00213 ExecStatus
00214 NaryEqDom<View>::post(Home home, ViewArray<View>& x) {
00215 x.unique(home);
00216 if (x.size() == 2) {
00217 return EqDom<View,View>::post(home,x[0],x[1]);
00218 } else if (x.size() > 2) {
00219 int l = x[0].min();
00220 int u = x[0].max();
00221 for (int i=x.size(); i-- > 1; ) {
00222 l = std::max(l,x[i].min());
00223 u = std::min(u,x[i].max());
00224 }
00225 for (int i=x.size(); i--; ) {
00226 GECODE_ME_CHECK(x[i].gq(home,l));
00227 GECODE_ME_CHECK(x[i].lq(home,u));
00228 }
00229 (void) new (home) NaryEqDom<View>(home,x);
00230 }
00231 return ES_OK;
00232 }
00233
00234 template<class View>
00235 forceinline
00236 NaryEqDom<View>::NaryEqDom(Space& home, bool share, NaryEqDom<View>& p)
00237 : NaryPropagator<View,PC_INT_DOM>(home,share,p) {}
00238
00239 template<class View>
00240 Actor*
00241 NaryEqDom<View>::copy(Space& home, bool share) {
00242 return new (home) NaryEqDom<View>(home,share,*this);
00243 }
00244
00245 template<class View>
00246 PropCost
00247 NaryEqDom<View>::cost(const Space&, const ModEventDelta& med) const {
00248 if (View::me(med) == ME_INT_VAL)
00249 return PropCost::unary(PropCost::LO);
00250 else
00251 return PropCost::linear((View::me(med) == ME_INT_DOM) ?
00252 PropCost::LO : PropCost::HI, x.size());
00253 }
00254
00255 template<class View>
00256 ExecStatus
00257 NaryEqDom<View>::propagate(Space& home, const ModEventDelta& med) {
00258 assert(x.size() > 2);
00259
00260 ModEvent me = View::me(med);
00261 if (me == ME_INT_VAL) {
00262
00263 for (int i = 0; ; i++)
00264 if (x[i].assigned()) {
00265 int n = x[i].val();
00266 x.move_lst(i);
00267 for (int j = x.size(); j--; )
00268 GECODE_ME_CHECK(x[j].eq(home,n));
00269 return home.ES_SUBSUMED(*this);
00270 }
00271 GECODE_NEVER;
00272 }
00273
00274 if (me == ME_INT_BND) {
00275 {
00276
00277 int mn = x[0].min();
00278 restart_min:
00279 for (int i = x.size(); i--; ) {
00280 GECODE_ME_CHECK(x[i].gq(home,mn));
00281 if (mn < x[i].min()) {
00282 mn = x[i].min();
00283 goto restart_min;
00284 }
00285 }
00286 }
00287 {
00288
00289 int mx = x[0].max();
00290 restart_max:
00291 for (int i = x.size(); i--; ) {
00292 GECODE_ME_CHECK(x[i].lq(home,mx));
00293 if (mx > x[i].max()) {
00294 mx = x[i].max();
00295 goto restart_max;
00296 }
00297 }
00298 }
00299 if (x[0].assigned())
00300 return home.ES_SUBSUMED(*this);
00301 return home.ES_FIX_PARTIAL(*this,View::med(ME_INT_DOM));
00302 }
00303
00304 int n = x.size();
00305
00306 Region re(home);
00307 ViewRanges<View>* i_x = re.alloc<ViewRanges<View> >(n);
00308 for (int i = n; i--; ) {
00309 ViewRanges<View> i_xi(x[i]);
00310 i_x[i] = i_xi;
00311 }
00312 Iter::Ranges::NaryInter r(re,i_x,n);
00313
00314 if (!r())
00315 return ES_FAILED;
00316 ++r;
00317 if (!r()) {
00318 r.reset();
00319 for (int i = n; i--; ) {
00320 GECODE_ME_CHECK(x[i].gq(home,r.min()));
00321 GECODE_ME_CHECK(x[i].lq(home,r.max()));
00322 }
00323 } else {
00324 for (int i = n; i--; ) {
00325 r.reset();
00326 GECODE_ME_CHECK(x[i].narrow_r(home,r,false));
00327 }
00328 }
00329 return ES_FIX;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339 template<class View>
00340 forceinline
00341 NaryEqBnd<View>::NaryEqBnd(Home home, ViewArray<View>& x)
00342 : NaryPropagator<View,PC_INT_BND>(home,x) {}
00343
00344 template<class View>
00345 ExecStatus
00346 NaryEqBnd<View>::post(Home home, ViewArray<View>& x) {
00347 x.unique(home);
00348 if (x.size() == 2) {
00349 return EqBnd<View,View>::post(home,x[0],x[1]);
00350 } else if (x.size() > 2) {
00351 int l = x[0].min();
00352 int u = x[0].max();
00353 for (int i=x.size(); i-- > 1; ) {
00354 l = std::max(l,x[i].min());
00355 u = std::min(u,x[i].max());
00356 }
00357 for (int i=x.size(); i--; ) {
00358 GECODE_ME_CHECK(x[i].gq(home,l));
00359 GECODE_ME_CHECK(x[i].lq(home,u));
00360 }
00361 (void) new (home) NaryEqBnd<View>(home,x);
00362 }
00363 return ES_OK;
00364 }
00365
00366 template<class View>
00367 forceinline
00368 NaryEqBnd<View>::NaryEqBnd(Space& home, bool share, NaryEqBnd<View>& p)
00369 : NaryPropagator<View,PC_INT_BND>(home,share,p) {}
00370
00371 template<class View>
00372 Actor*
00373 NaryEqBnd<View>::copy(Space& home, bool share) {
00374 return new (home) NaryEqBnd<View>(home,share,*this);
00375 }
00376
00377 template<class View>
00378 PropCost
00379 NaryEqBnd<View>::cost(const Space&, const ModEventDelta& med) const {
00380 if (View::me(med) == ME_INT_VAL)
00381 return PropCost::unary(PropCost::LO);
00382 else
00383 return PropCost::linear(PropCost::LO, x.size());
00384 }
00385
00386 template<class View>
00387 ExecStatus
00388 NaryEqBnd<View>::propagate(Space& home, const ModEventDelta& med) {
00389 assert(x.size() > 2);
00390 if (View::me(med) == ME_INT_VAL) {
00391
00392 for (int i = 0; ; i++)
00393 if (x[i].assigned()) {
00394 int n = x[i].val();
00395 x.move_lst(i);
00396 for (int j = x.size(); j--; )
00397 GECODE_ME_CHECK(x[j].eq(home,n));
00398 return home.ES_SUBSUMED(*this);
00399 }
00400 GECODE_NEVER;
00401 }
00402
00403 int mn = x[0].min();
00404 restart_min:
00405 for (int i = x.size(); i--; ) {
00406 GECODE_ME_CHECK(x[i].gq(home,mn));
00407 if (mn < x[i].min()) {
00408 mn = x[i].min();
00409 goto restart_min;
00410 }
00411 }
00412 int mx = x[0].max();
00413 restart_max:
00414 for (int i = x.size(); i--; ) {
00415 GECODE_ME_CHECK(x[i].lq(home,mx));
00416 if (mx > x[i].max()) {
00417 mx = x[i].max();
00418 goto restart_max;
00419 }
00420 }
00421 return x[0].assigned() ? home.ES_SUBSUMED(*this) : ES_FIX;
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431 template<class View, class CtrlView, ReifyMode rm>
00432 forceinline
00433 ReEqDom<View,CtrlView,rm>::ReEqDom(Home home, View x0, View x1, CtrlView b)
00434 : ReBinaryPropagator<View,PC_INT_DOM,CtrlView>(home,x0,x1,b) {}
00435
00436 template<class View, class CtrlView, ReifyMode rm>
00437 ExecStatus
00438 ReEqDom<View,CtrlView,rm>::post(Home home, View x0, View x1, CtrlView b) {
00439 if (b.one()) {
00440 if (rm == RM_PMI)
00441 return ES_OK;
00442 return EqDom<View,View>::post(home,x0,x1);
00443 }
00444 if (b.zero()) {
00445 if (rm == RM_IMP)
00446 return ES_OK;
00447 return Nq<View>::post(home,x0,x1);
00448 }
00449 if (!same(x0,x1)) {
00450 (void) new (home) ReEqDom(home,x0,x1,b);
00451 } else if (rm != RM_IMP) {
00452 GECODE_ME_CHECK(b.one(home));
00453 }
00454 return ES_OK;
00455 }
00456
00457
00458 template<class View, class CtrlView, ReifyMode rm>
00459 forceinline
00460 ReEqDom<View,CtrlView,rm>::ReEqDom(Space& home, bool share, ReEqDom& p)
00461 : ReBinaryPropagator<View,PC_INT_DOM,CtrlView>(home,share,p) {}
00462
00463 template<class View, class CtrlView, ReifyMode rm>
00464 Actor*
00465 ReEqDom<View,CtrlView,rm>::copy(Space& home, bool share) {
00466 return new (home) ReEqDom<View,CtrlView,rm>(home,share,*this);
00467 }
00468
00469 template<class View, class CtrlView, ReifyMode rm>
00470 ExecStatus
00471 ReEqDom<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) {
00472 if (b.one()) {
00473 if (rm == RM_PMI)
00474 return home.ES_SUBSUMED(*this);
00475 GECODE_REWRITE(*this,(EqDom<View,View>::post(home(*this),x0,x1)));
00476 }
00477 if (b.zero()) {
00478 if (rm == RM_IMP)
00479 return home.ES_SUBSUMED(*this);
00480 GECODE_REWRITE(*this,Nq<View>::post(home(*this),x0,x1));
00481 }
00482 switch (rtest_eq_dom(x0,x1)) {
00483 case RT_TRUE:
00484 if (rm != RM_IMP)
00485 GECODE_ME_CHECK(b.one_none(home));
00486 break;
00487 case RT_FALSE:
00488 if (rm != RM_PMI)
00489 GECODE_ME_CHECK(b.zero_none(home));
00490 break;
00491 case RT_MAYBE:
00492 return ES_FIX;
00493 default: GECODE_NEVER;
00494 }
00495 return home.ES_SUBSUMED(*this);
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505 template<class View, class CtrlView, ReifyMode rm>
00506 forceinline
00507 ReEqBnd<View,CtrlView,rm>::ReEqBnd(Home home, View x0, View x1, CtrlView b)
00508 : ReBinaryPropagator<View,PC_INT_BND,CtrlView>(home,x0,x1,b) {}
00509
00510 template<class View, class CtrlView, ReifyMode rm>
00511 ExecStatus
00512 ReEqBnd<View,CtrlView,rm>::post(Home home, View x0, View x1, CtrlView b){
00513 if (b.one()) {
00514 if (rm == RM_PMI)
00515 return ES_OK;
00516 return EqBnd<View,View>::post(home,x0,x1);
00517 }
00518 if (b.zero()) {
00519 if (rm == RM_IMP)
00520 return ES_OK;
00521 return Nq<View>::post(home,x0,x1);
00522 }
00523 if (!same(x0,x1)) {
00524 (void) new (home) ReEqBnd(home,x0,x1,b);
00525 } else if (rm != RM_IMP) {
00526 GECODE_ME_CHECK(b.one(home));
00527 }
00528 return ES_OK;
00529 }
00530
00531
00532 template<class View, class CtrlView, ReifyMode rm>
00533 forceinline
00534 ReEqBnd<View,CtrlView,rm>::ReEqBnd(Space& home, bool share, ReEqBnd& p)
00535 : ReBinaryPropagator<View,PC_INT_BND,CtrlView>(home,share,p) {}
00536
00537 template<class View, class CtrlView, ReifyMode rm>
00538 Actor*
00539 ReEqBnd<View,CtrlView,rm>::copy(Space& home, bool share) {
00540 return new (home) ReEqBnd<View,CtrlView,rm>(home,share,*this);
00541 }
00542
00543 template<class View, class CtrlView, ReifyMode rm>
00544 ExecStatus
00545 ReEqBnd<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) {
00546 if (b.one()) {
00547 if (rm == RM_PMI)
00548 return home.ES_SUBSUMED(*this);
00549 GECODE_REWRITE(*this,(EqBnd<View,View>::post(home(*this),x0,x1)));
00550 }
00551 if (b.zero()) {
00552 if (rm == RM_IMP)
00553 return home.ES_SUBSUMED(*this);
00554 GECODE_REWRITE(*this,Nq<View>::post(home(*this),x0,x1));
00555 }
00556 switch (rtest_eq_bnd(x0,x1)) {
00557 case RT_TRUE:
00558 if (rm != RM_IMP)
00559 GECODE_ME_CHECK(b.one_none(home));
00560 break;
00561 case RT_FALSE:
00562 if (rm != RM_PMI)
00563 GECODE_ME_CHECK(b.zero_none(home));
00564 break;
00565 case RT_MAYBE:
00566 return ES_FIX;
00567 default: GECODE_NEVER;
00568 }
00569 return home.ES_SUBSUMED(*this);
00570 }
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 template<class View, class CtrlView, ReifyMode rm>
00581 forceinline
00582 ReEqDomInt<View,CtrlView,rm>::ReEqDomInt
00583 (Home home, View x, int c0, CtrlView b)
00584 : ReUnaryPropagator<View,PC_INT_DOM,CtrlView>(home,x,b), c(c0) {}
00585
00586 template<class View, class CtrlView, ReifyMode rm>
00587 ExecStatus
00588 ReEqDomInt<View,CtrlView,rm>::post(Home home, View x, int c, CtrlView b) {
00589 if (b.one()) {
00590 if (rm != RM_PMI)
00591 GECODE_ME_CHECK(x.eq(home,c));
00592 } else if (b.zero()) {
00593 if (rm != RM_IMP)
00594 GECODE_ME_CHECK(x.nq(home,c));
00595 } else if (x.assigned()) {
00596 assert(b.none());
00597 if (x.val() == c) {
00598 if (rm != RM_IMP)
00599 GECODE_ME_CHECK(b.one_none(home));
00600 } else {
00601 if (rm != RM_PMI)
00602 GECODE_ME_CHECK(b.zero_none(home));
00603 }
00604 } else {
00605 (void) new (home) ReEqDomInt(home,x,c,b);
00606 }
00607 return ES_OK;
00608 }
00609
00610
00611 template<class View, class CtrlView, ReifyMode rm>
00612 forceinline
00613 ReEqDomInt<View,CtrlView,rm>::ReEqDomInt(Space& home, bool share,
00614 ReEqDomInt& p)
00615 : ReUnaryPropagator<View,PC_INT_DOM,CtrlView>(home,share,p), c(p.c) {}
00616
00617 template<class View, class CtrlView, ReifyMode rm>
00618 Actor*
00619 ReEqDomInt<View,CtrlView,rm>::copy(Space& home, bool share) {
00620 return new (home) ReEqDomInt<View,CtrlView,rm>(home,share,*this);
00621 }
00622
00623 template<class View, class CtrlView, ReifyMode rm>
00624 ExecStatus
00625 ReEqDomInt<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) {
00626 if (b.one()) {
00627 if (rm != RM_PMI)
00628 GECODE_ME_CHECK(x0.eq(home,c));
00629 } else if (b.zero()) {
00630 if (rm != RM_IMP)
00631 GECODE_ME_CHECK(x0.nq(home,c));
00632 } else {
00633 switch (rtest_eq_dom(x0,c)) {
00634 case RT_TRUE:
00635 if (rm != RM_IMP)
00636 GECODE_ME_CHECK(b.one_none(home));
00637 break;
00638 case RT_FALSE:
00639 if (rm != RM_PMI)
00640 GECODE_ME_CHECK(b.zero_none(home));
00641 break;
00642 case RT_MAYBE:
00643 return ES_FIX;
00644 default: GECODE_NEVER;
00645 }
00646 }
00647 return home.ES_SUBSUMED(*this);
00648 }
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 template<class View, class CtrlView, ReifyMode rm>
00659 forceinline
00660 ReEqBndInt<View,CtrlView,rm>::ReEqBndInt
00661 (Home home, View x, int c0, CtrlView b)
00662 : ReUnaryPropagator<View,PC_INT_BND,CtrlView>(home,x,b), c(c0) {}
00663
00664 template<class View, class CtrlView, ReifyMode rm>
00665 ExecStatus
00666 ReEqBndInt<View,CtrlView,rm>::post(Home home, View x, int c, CtrlView b) {
00667 if (b.one()) {
00668 if (rm != RM_PMI)
00669 GECODE_ME_CHECK(x.eq(home,c));
00670 } else if (b.zero()) {
00671 if (rm != RM_IMP)
00672 GECODE_ME_CHECK(x.nq(home,c));
00673 } else if (x.assigned()) {
00674 assert(b.none());
00675 if (x.val() == c) {
00676 if (rm != RM_IMP)
00677 GECODE_ME_CHECK(b.one_none(home));
00678 } else {
00679 if (rm != RM_PMI)
00680 GECODE_ME_CHECK(b.zero_none(home));
00681 }
00682 } else {
00683 (void) new (home) ReEqBndInt(home,x,c,b);
00684 }
00685 return ES_OK;
00686 }
00687
00688
00689 template<class View, class CtrlView, ReifyMode rm>
00690 forceinline
00691 ReEqBndInt<View,CtrlView,rm>::ReEqBndInt(Space& home, bool share, ReEqBndInt& p)
00692 : ReUnaryPropagator<View,PC_INT_BND,CtrlView>(home,share,p), c(p.c) {}
00693
00694 template<class View, class CtrlView, ReifyMode rm>
00695 Actor*
00696 ReEqBndInt<View,CtrlView,rm>::copy(Space& home, bool share) {
00697 return new (home) ReEqBndInt<View,CtrlView,rm>(home,share,*this);
00698 }
00699
00700 template<class View, class CtrlView, ReifyMode rm>
00701 ExecStatus
00702 ReEqBndInt<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) {
00703 if (b.one()) {
00704 if (rm != RM_PMI)
00705 GECODE_ME_CHECK(x0.eq(home,c));
00706 } else if (b.zero()) {
00707 if (rm != RM_IMP)
00708 GECODE_ME_CHECK(x0.nq(home,c));
00709 } else {
00710 switch (rtest_eq_bnd(x0,c)) {
00711 case RT_TRUE:
00712 if (rm != RM_IMP)
00713 GECODE_ME_CHECK(b.one_none(home));
00714 break;
00715 case RT_FALSE:
00716 if (rm != RM_PMI)
00717 GECODE_ME_CHECK(b.zero_none(home));
00718 break;
00719 case RT_MAYBE:
00720 return ES_FIX;
00721 default: GECODE_NEVER;
00722 }
00723 }
00724 return home.ES_SUBSUMED(*this);
00725 }
00726
00727 }}}
00728
00729