gecode » int » rel

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: 2009-11-04 17:06:05 +0100 (Wed, 04 Nov 2009) $ by $Author: tack $ 00011 * $Revision: 10045 $ 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 Rel { 00039 00040 /* 00041 * Binary bounds consistent equality 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 ES_SUBSUMED(*this,sizeof(*this)); 00106 } 00107 00108 /* 00109 * Binary domain consistent equality 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 ES_SUBSUMED(*this,sizeof(*this)); 00171 } 00172 if (x1.assigned()) { 00173 GECODE_ME_CHECK(x0.eq(home,x1.val())); 00174 return ES_SUBSUMED(*this,sizeof(*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 ES_SUBSUMED(*this,sizeof(*this)); 00187 if (x0.range() && x1.range()) 00188 return ES_FIX; 00189 return 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 ES_SUBSUMED(*this,sizeof(*this)); 00197 return ES_FIX; 00198 } 00199 00200 00201 00202 /* 00203 * Nary domain consistent equality 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 // One of the variables is assigned 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 ES_SUBSUMED(*this,sizeof(*this)); 00270 } 00271 GECODE_NEVER; 00272 return ES_SUBSUMED(*this,sizeof(*this)); 00273 } 00274 00275 if (me == ME_INT_BND) { 00276 { 00277 // One of the mins has changed 00278 int mn = x[0].min(); 00279 restart_min: 00280 for (int i = x.size(); i--; ) { 00281 GECODE_ME_CHECK(x[i].gq(home,mn)); 00282 if (mn < x[i].min()) { 00283 mn = x[i].min(); 00284 goto restart_min; 00285 } 00286 } 00287 } 00288 { 00289 // One of the maxs has changed 00290 int mx = x[0].max(); 00291 restart_max: 00292 for (int i = x.size(); i--; ) { 00293 GECODE_ME_CHECK(x[i].lq(home,mx)); 00294 if (mx > x[i].max()) { 00295 mx = x[i].max(); 00296 goto restart_max; 00297 } 00298 } 00299 } 00300 if (x[0].assigned()) 00301 return ES_SUBSUMED(*this,sizeof(*this)); 00302 return ES_FIX_PARTIAL(*this,View::med(ME_INT_DOM)); 00303 } 00304 00305 int n = x.size(); 00306 00307 Region re(home); 00308 ViewRanges<View>* i_x = re.alloc<ViewRanges<View> >(n); 00309 for (int i = n; i--; ) { 00310 ViewRanges<View> i_xi(x[i]); 00311 i_x[i] = i_xi; 00312 } 00313 Iter::Ranges::NaryInter<ViewRanges<View> > r(i_x,n); 00314 Iter::Ranges::Cache<Iter::Ranges::NaryInter<ViewRanges<View> > > rc(r); 00315 00316 if (!rc()) 00317 return ES_FAILED; 00318 ++rc; 00319 if (!rc()) { 00320 rc.reset(); 00321 for (int i = n; i--; ) { 00322 GECODE_ME_CHECK(x[i].gq(home,rc.min())); 00323 GECODE_ME_CHECK(x[i].lq(home,rc.max())); 00324 } 00325 } else { 00326 for (int i = n; i--; ) { 00327 rc.reset(); 00328 GECODE_ME_CHECK(x[i].narrow_r(home,rc,false)); 00329 } 00330 } 00331 return ES_FIX; 00332 } 00333 00334 00335 00336 /* 00337 * Nary bound consistent equality 00338 * 00339 */ 00340 00341 template<class View> 00342 forceinline 00343 NaryEqBnd<View>::NaryEqBnd(Home home, ViewArray<View>& x) 00344 : NaryPropagator<View,PC_INT_BND>(home,x) {} 00345 00346 template<class View> 00347 ExecStatus 00348 NaryEqBnd<View>::post(Home home, ViewArray<View>& x) { 00349 if (x.size() == 2) { 00350 return EqBnd<View,View>::post(home,x[0],x[1]); 00351 } else if (x.size() > 2) { 00352 int l = x[0].min(); 00353 int u = x[0].max(); 00354 for (int i=x.size(); i-- > 1; ) { 00355 l = std::max(l,x[i].min()); 00356 u = std::min(u,x[i].max()); 00357 } 00358 for (int i=x.size(); i--; ) { 00359 GECODE_ME_CHECK(x[i].gq(home,l)); 00360 GECODE_ME_CHECK(x[i].lq(home,u)); 00361 } 00362 (void) new (home) NaryEqBnd<View>(home,x); 00363 } 00364 return ES_OK; 00365 } 00366 00367 template<class View> 00368 forceinline 00369 NaryEqBnd<View>::NaryEqBnd(Space& home, bool share, NaryEqBnd<View>& p) 00370 : NaryPropagator<View,PC_INT_BND>(home,share,p) {} 00371 00372 template<class View> 00373 Actor* 00374 NaryEqBnd<View>::copy(Space& home, bool share) { 00375 return new (home) NaryEqBnd<View>(home,share,*this); 00376 } 00377 00378 template<class View> 00379 PropCost 00380 NaryEqBnd<View>::cost(const Space&, const ModEventDelta& med) const { 00381 if (View::me(med) == ME_INT_VAL) 00382 return PropCost::unary(PropCost::LO); 00383 else 00384 return PropCost::linear(PropCost::LO, x.size()); 00385 } 00386 00387 template<class View> 00388 ExecStatus 00389 NaryEqBnd<View>::propagate(Space& home, const ModEventDelta& med) { 00390 assert(x.size() > 2); 00391 if (View::me(med) == ME_INT_VAL) { 00392 // One of the variables is assigned 00393 for (int i = 0; ; i++) 00394 if (x[i].assigned()) { 00395 int n = x[i].val(); 00396 x.move_lst(i); 00397 for (int j = x.size(); j--; ) 00398 GECODE_ME_CHECK(x[j].eq(home,n)); 00399 return ES_SUBSUMED(*this,sizeof(*this)); 00400 } 00401 GECODE_NEVER; 00402 return ES_SUBSUMED(*this,sizeof(*this)); 00403 } 00404 00405 int mn = x[0].min(); 00406 restart_min: 00407 for (int i = x.size(); i--; ) { 00408 GECODE_ME_CHECK(x[i].gq(home,mn)); 00409 if (mn < x[i].min()) { 00410 mn = x[i].min(); 00411 goto restart_min; 00412 } 00413 } 00414 int mx = x[0].max(); 00415 restart_max: 00416 for (int i = x.size(); i--; ) { 00417 GECODE_ME_CHECK(x[i].lq(home,mx)); 00418 if (mx > x[i].max()) { 00419 mx = x[i].max(); 00420 goto restart_max; 00421 } 00422 } 00423 return x[0].assigned() ? ES_SUBSUMED(*this,sizeof(*this)) : ES_FIX; 00424 } 00425 00426 00427 00428 /* 00429 * Reified domain consistent equality 00430 * 00431 */ 00432 00433 template<class View, class CtrlView> 00434 forceinline 00435 ReEqDom<View,CtrlView>::ReEqDom(Home home, View x0, View x1, CtrlView b) 00436 : ReBinaryPropagator<View,PC_INT_DOM,CtrlView>(home,x0,x1,b) {} 00437 00438 template<class View, class CtrlView> 00439 ExecStatus 00440 ReEqDom<View,CtrlView>::post(Home home, View x0, View x1, CtrlView b) { 00441 if (b.one()) 00442 return EqDom<View,View>::post(home,x0,x1); 00443 if (b.zero()) 00444 return Nq<View>::post(home,x0,x1); 00445 if (!same(x0,x1)) { 00446 (void) new (home) ReEqDom(home,x0,x1,b); 00447 } else { 00448 GECODE_ME_CHECK(b.one(home)); 00449 } 00450 return ES_OK; 00451 } 00452 00453 00454 template<class View, class CtrlView> 00455 forceinline 00456 ReEqDom<View,CtrlView>::ReEqDom(Space& home, bool share, ReEqDom& p) 00457 : ReBinaryPropagator<View,PC_INT_DOM,CtrlView>(home,share,p) {} 00458 00459 template<class View, class CtrlView> 00460 Actor* 00461 ReEqDom<View,CtrlView>::copy(Space& home, bool share) { 00462 return new (home) ReEqDom<View,CtrlView>(home,share,*this); 00463 } 00464 00465 template<class View, class CtrlView> 00466 ExecStatus 00467 ReEqDom<View,CtrlView>::propagate(Space& home, const ModEventDelta&) { 00468 if (b.one()) 00469 GECODE_REWRITE(*this,(EqDom<View,View>::post(home(*this),x0,x1))); 00470 if (b.zero()) 00471 GECODE_REWRITE(*this,Nq<View>::post(home(*this),x0,x1)); 00472 switch (rtest_eq_dom(x0,x1)) { 00473 case RT_TRUE: 00474 GECODE_ME_CHECK(b.one_none(home)); return ES_SUBSUMED(*this,home); 00475 case RT_FALSE: 00476 GECODE_ME_CHECK(b.zero_none(home)); return ES_SUBSUMED(*this,home); 00477 case RT_MAYBE: 00478 break; 00479 default: GECODE_NEVER; 00480 } 00481 return ES_FIX; 00482 } 00483 00484 00485 00486 /* 00487 * Reified bounds consistent equality 00488 * 00489 */ 00490 00491 template<class View, class CtrlView> 00492 forceinline 00493 ReEqBnd<View,CtrlView>::ReEqBnd(Home home, View x0, View x1, CtrlView b) 00494 : ReBinaryPropagator<View,PC_INT_BND,CtrlView>(home,x0,x1,b) {} 00495 00496 template<class View, class CtrlView> 00497 ExecStatus 00498 ReEqBnd<View,CtrlView>::post(Home home, View x0, View x1, CtrlView b){ 00499 if (b.one()) 00500 return EqBnd<View,View>::post(home,x0,x1); 00501 if (b.zero()) 00502 return Nq<View>::post(home,x0,x1); 00503 if (!same(x0,x1)) { 00504 (void) new (home) ReEqBnd(home,x0,x1,b); 00505 } else { 00506 GECODE_ME_CHECK(b.one(home)); 00507 } 00508 return ES_OK; 00509 } 00510 00511 00512 template<class View, class CtrlView> 00513 forceinline 00514 ReEqBnd<View,CtrlView>::ReEqBnd(Space& home, bool share, ReEqBnd& p) 00515 : ReBinaryPropagator<View,PC_INT_BND,CtrlView>(home,share,p) {} 00516 00517 template<class View, class CtrlView> 00518 Actor* 00519 ReEqBnd<View,CtrlView>::copy(Space& home, bool share) { 00520 return new (home) ReEqBnd<View,CtrlView>(home,share,*this); 00521 } 00522 00523 template<class View, class CtrlView> 00524 ExecStatus 00525 ReEqBnd<View,CtrlView>::propagate(Space& home, const ModEventDelta&) { 00526 if (b.one()) 00527 GECODE_REWRITE(*this,(EqBnd<View,View>::post(home(*this),x0,x1))); 00528 if (b.zero()) 00529 GECODE_REWRITE(*this,Nq<View>::post(home(*this),x0,x1)); 00530 switch (rtest_eq_bnd(x0,x1)) { 00531 case RT_TRUE: 00532 GECODE_ME_CHECK(b.one_none(home)); return ES_SUBSUMED(*this,home); 00533 case RT_FALSE: 00534 GECODE_ME_CHECK(b.zero_none(home)); return ES_SUBSUMED(*this,home); 00535 case RT_MAYBE: 00536 break; 00537 default: GECODE_NEVER; 00538 } 00539 return ES_FIX; 00540 } 00541 00542 00543 00544 00545 /* 00546 * Reified domain consistent equality (one variable) 00547 * 00548 */ 00549 00550 template<class View, class CtrlView> 00551 forceinline 00552 ReEqDomInt<View,CtrlView>::ReEqDomInt 00553 (Home home, View x, int c0, CtrlView b) 00554 : ReUnaryPropagator<View,PC_INT_DOM,CtrlView>(home,x,b), c(c0) {} 00555 00556 template<class View, class CtrlView> 00557 ExecStatus 00558 ReEqDomInt<View,CtrlView>::post(Home home, View x, int c, CtrlView b) { 00559 if (b.one()) { 00560 GECODE_ME_CHECK(x.eq(home,c)); 00561 } else if (b.zero()) { 00562 GECODE_ME_CHECK(x.nq(home,c)); 00563 } else if (x.assigned()) { 00564 assert(b.none()); 00565 if (x.val() == c) { 00566 GECODE_ME_CHECK(b.one_none(home)); 00567 } else { 00568 GECODE_ME_CHECK(b.zero_none(home)); 00569 } 00570 } else { 00571 (void) new (home) ReEqDomInt(home,x,c,b); 00572 } 00573 return ES_OK; 00574 } 00575 00576 00577 template<class View, class CtrlView> 00578 forceinline 00579 ReEqDomInt<View,CtrlView>::ReEqDomInt(Space& home, bool share, ReEqDomInt& p) 00580 : ReUnaryPropagator<View,PC_INT_DOM,CtrlView>(home,share,p), c(p.c) {} 00581 00582 template<class View, class CtrlView> 00583 Actor* 00584 ReEqDomInt<View,CtrlView>::copy(Space& home, bool share) { 00585 return new (home) ReEqDomInt<View,CtrlView>(home,share,*this); 00586 } 00587 00588 template<class View, class CtrlView> 00589 ExecStatus 00590 ReEqDomInt<View,CtrlView>::propagate(Space& home, const ModEventDelta&) { 00591 if (b.one()) { 00592 GECODE_ME_CHECK(x0.eq(home,c)); 00593 assert(x0.assigned()); 00594 goto subsumed; 00595 } 00596 if (b.zero()) { 00597 GECODE_ME_CHECK(x0.nq(home,c)); 00598 x0.cancel(home,*this,PC_INT_DOM); 00599 goto subsumed; 00600 } 00601 switch (rtest_eq_dom(x0,c)) { 00602 case RT_TRUE: 00603 GECODE_ME_CHECK(b.one_none(home)); 00604 assert(x0.assigned()); 00605 goto subsumed; 00606 case RT_FALSE: 00607 GECODE_ME_CHECK(b.zero_none(home)); 00608 x0.cancel(home,*this,PC_INT_DOM); 00609 goto subsumed; 00610 case RT_MAYBE: 00611 break; 00612 default: GECODE_NEVER; 00613 } 00614 return ES_FIX; 00615 subsumed: 00616 return ES_SUBSUMED(*this,sizeof(*this)); 00617 } 00618 00619 00620 00621 00622 /* 00623 * Reified bounds consistent equality (one variable) 00624 * 00625 */ 00626 00627 template<class View, class CtrlView> 00628 forceinline 00629 ReEqBndInt<View,CtrlView>::ReEqBndInt 00630 (Home home, View x, int c0, CtrlView b) 00631 : ReUnaryPropagator<View,PC_INT_BND,CtrlView>(home,x,b), c(c0) {} 00632 00633 template<class View, class CtrlView> 00634 ExecStatus 00635 ReEqBndInt<View,CtrlView>::post(Home home, View x, int c, CtrlView b) { 00636 if (b.one()) { 00637 GECODE_ME_CHECK(x.eq(home,c)); 00638 } else if (b.zero()) { 00639 GECODE_ME_CHECK(x.nq(home,c)); 00640 } else if (x.assigned()) { 00641 assert(b.none()); 00642 if (x.val() == c) { 00643 GECODE_ME_CHECK(b.one_none(home)); 00644 } else { 00645 GECODE_ME_CHECK(b.zero_none(home)); 00646 } 00647 } else { 00648 (void) new (home) ReEqBndInt(home,x,c,b); 00649 } 00650 return ES_OK; 00651 } 00652 00653 00654 template<class View, class CtrlView> 00655 forceinline 00656 ReEqBndInt<View,CtrlView>::ReEqBndInt(Space& home, bool share, ReEqBndInt& p) 00657 : ReUnaryPropagator<View,PC_INT_BND,CtrlView>(home,share,p), c(p.c) {} 00658 00659 template<class View, class CtrlView> 00660 Actor* 00661 ReEqBndInt<View,CtrlView>::copy(Space& home, bool share) { 00662 return new (home) ReEqBndInt<View,CtrlView>(home,share,*this); 00663 } 00664 00665 template<class View, class CtrlView> 00666 ExecStatus 00667 ReEqBndInt<View,CtrlView>::propagate(Space& home, const ModEventDelta&) { 00668 if (b.one()) { 00669 GECODE_ME_CHECK(x0.eq(home,c)); 00670 assert(x0.assigned()); 00671 goto subsumed; 00672 } 00673 if (b.zero()) { 00674 GECODE_ME_CHECK(x0.nq(home,c)); 00675 x0.cancel(home,*this,PC_INT_BND); 00676 goto subsumed; 00677 } 00678 switch (rtest_eq_bnd(x0,c)) { 00679 case RT_TRUE: 00680 GECODE_ME_CHECK(b.one_none(home)); 00681 assert(x0.assigned()); 00682 goto subsumed; 00683 case RT_FALSE: 00684 GECODE_ME_CHECK(b.zero_none(home)); 00685 x0.cancel(home,*this,PC_INT_BND); 00686 goto subsumed; 00687 case RT_MAYBE: 00688 break; 00689 default: GECODE_NEVER; 00690 } 00691 return ES_FIX; 00692 subsumed: 00693 return ES_SUBSUMED(*this,sizeof(*this)); 00694 } 00695 00696 }}} 00697 00698 // STATISTICS: int-prop