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 #include <gecode/int/linear/int-noview.hpp>
00039
00040 namespace Gecode { namespace Int { namespace Linear {
00041
00046 template<class P, class N>
00047 forceinline bool
00048 isunit(ViewArray<P>&, ViewArray<N>&) { return false; }
00049 template<>
00050 forceinline bool
00051 isunit(ViewArray<IntView>&, ViewArray<IntView>&) { return true; }
00052 template<>
00053 forceinline bool
00054 isunit(ViewArray<IntView>&, ViewArray<NoView>&) { return true; }
00055 template<>
00056 forceinline bool
00057 isunit(ViewArray<NoView>&, ViewArray<IntView>&) { return true; }
00058
00059
00060
00061
00062
00063 template<class Val, class P, class N, PropCond pc>
00064 forceinline
00065 Lin<Val,P,N,pc>::Lin(Home home, ViewArray<P>& x0, ViewArray<N>& y0, Val c0)
00066 : Propagator(home), x(x0), y(y0), c(c0) {
00067 x.subscribe(home,*this,pc);
00068 y.subscribe(home,*this,pc);
00069 }
00070
00071 template<class Val, class P, class N, PropCond pc>
00072 forceinline
00073 Lin<Val,P,N,pc>::Lin(Space& home, bool share, Lin<Val,P,N,pc>& p)
00074 : Propagator(home,share,p), c(p.c) {
00075 x.update(home,share,p.x);
00076 y.update(home,share,p.y);
00077 }
00078
00079 template<class Val, class P, class N, PropCond pc>
00080 PropCost
00081 Lin<Val,P,N,pc>::cost(const Space&, const ModEventDelta&) const {
00082 return PropCost::linear(PropCost::LO, x.size()+y.size());
00083 }
00084
00085 template<class Val, class P, class N, PropCond pc>
00086 forceinline size_t
00087 Lin<Val,P,N,pc>::dispose(Space& home) {
00088 x.cancel(home,*this,pc);
00089 y.cancel(home,*this,pc);
00090 (void) Propagator::dispose(home);
00091 return sizeof(*this);
00092 }
00093
00094
00095
00096
00097
00098 template<class Val, class P, class N, PropCond pc, class Ctrl>
00099 forceinline
00100 ReLin<Val,P,N,pc,Ctrl>::ReLin
00101 (Home home, ViewArray<P>& x, ViewArray<N>& y, Val c, Ctrl b0)
00102 : Lin<Val,P,N,pc>(home,x,y,c), b(b0) {
00103 b.subscribe(home,*this,PC_INT_VAL);
00104 }
00105
00106 template<class Val, class P, class N, PropCond pc, class Ctrl>
00107 forceinline
00108 ReLin<Val,P,N,pc,Ctrl>::ReLin
00109 (Space& home, bool share, ReLin<Val,P,N,pc,Ctrl>& p)
00110 : Lin<Val,P,N,pc>(home,share,p) {
00111 b.update(home,share,p.b);
00112 }
00113
00114 template<class Val, class P, class N, PropCond pc, class Ctrl>
00115 forceinline size_t
00116 ReLin<Val,P,N,pc,Ctrl>::dispose(Space& home) {
00117 b.cancel(home,*this,PC_BOOL_VAL);
00118 (void) Lin<Val,P,N,pc>::dispose(home);
00119 return sizeof(*this);
00120 }
00121
00122
00123
00124
00125
00126
00127 template<class Val, class View>
00128 void
00129 bounds_p(ModEventDelta med, ViewArray<View>& x, Val& c, Val& sl, Val& su) {
00130 int n = x.size();
00131 if (IntView::me(med) == ME_INT_VAL) {
00132 for (int i = n; i--; ) {
00133 Val m = x[i].min();
00134 if (x[i].assigned()) {
00135 c -= m; x[i] = x[--n];
00136 } else {
00137 sl -= m; su -= x[i].max();
00138 }
00139 }
00140 x.size(n);
00141 } else {
00142 for (int i = n; i--; ) {
00143 sl -= x[i].min(); su -= x[i].max();
00144 }
00145 }
00146 }
00147
00148 template<class Val, class View>
00149 void
00150 bounds_n(ModEventDelta med, ViewArray<View>& y, Val& c, Val& sl, Val& su) {
00151 int n = y.size();
00152 if (IntView::me(med) == ME_INT_VAL) {
00153 for (int i = n; i--; ) {
00154 Val m = y[i].max();
00155 if (y[i].assigned()) {
00156 c += m; y[i] = y[--n];
00157 } else {
00158 sl += m; su += y[i].min();
00159 }
00160 }
00161 y.size(n);
00162 } else {
00163 for (int i = n; i--; ) {
00164 sl += y[i].max(); su += y[i].min();
00165 }
00166 }
00167 }
00168
00169
00170 template<class Val, class P, class N>
00171 ExecStatus
00172 prop_bnd(Space& home, ModEventDelta med, Propagator& p,
00173 ViewArray<P>& x, ViewArray<N>& y, Val& c) {
00174
00175 Val sl = 0;
00176 Val su = 0;
00177
00178 bounds_p<Val,P>(med, x, c, sl, su);
00179 bounds_n<Val,N>(med, y, c, sl, su);
00180
00181 if ((IntView::me(med) == ME_INT_VAL) && ((x.size() + y.size()) <= 1)) {
00182 if (x.size() == 1) {
00183 GECODE_ME_CHECK(x[0].eq(home,c));
00184 return home.ES_SUBSUMED(p);
00185 }
00186 if (y.size() == 1) {
00187 GECODE_ME_CHECK(y[0].eq(home,-c));
00188 return home.ES_SUBSUMED(p);
00189 }
00190 return (c == static_cast<Val>(0)) ?
00191 home.ES_SUBSUMED(p) : ES_FAILED;
00192 }
00193
00194 sl += c; su += c;
00195
00196 const int mod_sl = 1;
00197 const int mod_su = 2;
00198
00199 int mod = mod_sl | mod_su;
00200
00201 do {
00202 if (mod & mod_sl) {
00203 mod -= mod_sl;
00204
00205 for (int i = x.size(); i--; ) {
00206 const Val xi_max = x[i].max();
00207 ModEvent me = x[i].lq(home,sl + x[i].min());
00208 if (me_failed(me))
00209 return ES_FAILED;
00210 if (me_modified(me)) {
00211 su += xi_max - x[i].max();
00212 mod |= mod_su;
00213 }
00214 }
00215
00216 for (int i = y.size(); i--; ) {
00217 const Val yi_min = y[i].min();
00218 ModEvent me = y[i].gq(home,y[i].max() - sl);
00219 if (me_failed(me))
00220 return ES_FAILED;
00221 if (me_modified(me)) {
00222 su += y[i].min() - yi_min;
00223 mod |= mod_su;
00224 }
00225 }
00226 }
00227 if (mod & mod_su) {
00228 mod -= mod_su;
00229
00230 for (int i = x.size(); i--; ) {
00231 const Val xi_min = x[i].min();
00232 ModEvent me = x[i].gq(home,su + x[i].max());
00233 if (me_failed(me))
00234 return ES_FAILED;
00235 if (me_modified(me)) {
00236 sl += xi_min - x[i].min();
00237 mod |= mod_sl;
00238 }
00239 }
00240
00241 for (int i = y.size(); i--; ) {
00242 const Val yi_max = y[i].max();
00243 ModEvent me = y[i].lq(home,y[i].min() - su);
00244 if (me_failed(me))
00245 return ES_FAILED;
00246 if (me_modified(me)) {
00247 sl += y[i].max() - yi_max;
00248 mod |= mod_sl;
00249 }
00250 }
00251 }
00252 } while (mod);
00253
00254 return (sl == su) ? home.ES_SUBSUMED(p) : ES_FIX;
00255 }
00256
00257
00258
00259
00260
00261
00262 template<class Val, class P, class N>
00263 forceinline
00264 Eq<Val,P,N>::Eq(Home home, ViewArray<P>& x, ViewArray<N>& y, Val c)
00265 : Lin<Val,P,N,PC_INT_BND>(home,x,y,c) {}
00266
00267 template<class Val, class P, class N>
00268 ExecStatus
00269 Eq<Val,P,N>::post(Home home, ViewArray<P>& x, ViewArray<N>& y, Val c) {
00270 ViewArray<NoView> nva;
00271 if (y.size() == 0) {
00272 (void) new (home) Eq<Val,P,NoView>(home,x,nva,c);
00273 } else if (x.size() == 0) {
00274 (void) new (home) Eq<Val,N,NoView>(home,y,nva,-c);
00275 } else {
00276 (void) new (home) Eq<Val,P,N>(home,x,y,c);
00277 }
00278 return ES_OK;
00279 }
00280
00281
00282 template<class Val, class P, class N>
00283 forceinline
00284 Eq<Val,P,N>::Eq(Space& home, bool share, Eq<Val,P,N>& p)
00285 : Lin<Val,P,N,PC_INT_BND>(home,share,p) {}
00286
00291 template<class Val, class P, class N>
00292 forceinline Actor*
00293 eqtobin(Space&, bool, Propagator&, ViewArray<P>&, ViewArray<N>&, Val) {
00294 return NULL;
00295 }
00296 template<class Val>
00297 forceinline Actor*
00298 eqtobin(Space& home, bool share, Propagator& p,
00299 ViewArray<IntView>& x, ViewArray<NoView>&, Val c) {
00300 assert(x.size() == 2);
00301 return new (home) EqBin<Val,IntView,IntView>
00302 (home,share,p,x[0],x[1],c);
00303 }
00304 template<class Val>
00305 forceinline Actor*
00306 eqtobin(Space& home, bool share, Propagator& p,
00307 ViewArray<NoView>&, ViewArray<IntView>& y, Val c) {
00308 assert(y.size() == 2);
00309 return new (home) EqBin<Val,IntView,IntView>
00310 (home,share,p,y[0],y[1],-c);
00311 }
00312 template<class Val>
00313 forceinline Actor*
00314 eqtobin(Space& home, bool share, Propagator& p,
00315 ViewArray<IntView>& x, ViewArray<IntView>& y, Val c) {
00316 if (x.size() == 2)
00317 return new (home) EqBin<Val,IntView,IntView>
00318 (home,share,p,x[0],x[1],c);
00319 if (x.size() == 1)
00320 return new (home) EqBin<Val,IntView,MinusView>
00321 (home,share,p,x[0],MinusView(y[0]),c);
00322 return new (home) EqBin<Val,IntView,IntView>
00323 (home,share,p,y[0],y[1],-c);
00324 }
00325
00330 template<class Val, class P, class N>
00331 forceinline Actor*
00332 eqtoter(Space&, bool, Propagator&, ViewArray<P>&, ViewArray<N>&, Val) {
00333 return NULL;
00334 }
00335 template<class Val>
00336 forceinline Actor*
00337 eqtoter(Space& home, bool share, Propagator& p,
00338 ViewArray<IntView>& x, ViewArray<NoView>&, Val c) {
00339 assert(x.size() == 3);
00340 return new (home) EqTer<Val,IntView,IntView,IntView>
00341 (home,share,p,x[0],x[1],x[2],c);
00342 }
00343 template<class Val>
00344 forceinline Actor*
00345 eqtoter(Space& home, bool share, Propagator& p,
00346 ViewArray<NoView>&, ViewArray<IntView>& y, Val c) {
00347 assert(y.size() == 3);
00348 return new (home) EqTer<Val,IntView,IntView,IntView>
00349 (home,share,p,y[0],y[1],y[2],-c);
00350 }
00351 template<class Val>
00352 forceinline Actor*
00353 eqtoter(Space& home, bool share, Propagator& p,
00354 ViewArray<IntView>& x, ViewArray<IntView>& y, Val c) {
00355 if (x.size() == 3)
00356 return new (home) EqTer<Val,IntView,IntView,IntView>
00357 (home,share,p,x[0],x[1],x[2],c);
00358 if (x.size() == 2)
00359 return new (home) EqTer<Val,IntView,IntView,MinusView>
00360 (home,share,p,x[0],x[1],MinusView(y[0]),c);
00361 if (x.size() == 1)
00362 return new (home) EqTer<Val,IntView,IntView,MinusView>
00363 (home,share,p,y[0],y[1],MinusView(x[0]),-c);
00364 return new (home) EqTer<Val,IntView,IntView,IntView>
00365 (home,share,p,y[0],y[1],y[2],-c);
00366 }
00367
00368 template<class Val, class P, class N>
00369 Actor*
00370 Eq<Val,P,N>::copy(Space& home, bool share) {
00371 if (isunit(x,y)) {
00372
00373 if (x.size() + y.size() == 2)
00374 return eqtobin(home,share,*this,x,y,c);
00375 if (x.size() + y.size() == 3)
00376 return eqtoter(home,share,*this,x,y,c);
00377 }
00378 return new (home) Eq<Val,P,N>(home,share,*this);
00379 }
00380
00381 template<class Val, class P, class N>
00382 ExecStatus
00383 Eq<Val,P,N>::propagate(Space& home, const ModEventDelta& med) {
00384 return prop_bnd<Val,P,N>(home,med,*this,x,y,c);
00385 }
00386
00387
00388
00389
00390
00391
00392 template<class Val, class P, class N, class Ctrl, ReifyMode rm>
00393 forceinline
00394 ReEq<Val,P,N,Ctrl,rm>::ReEq(Home home,
00395 ViewArray<P>& x, ViewArray<N>& y, Val c, Ctrl b)
00396 : ReLin<Val,P,N,PC_INT_BND,Ctrl>(home,x,y,c,b) {}
00397
00398 template<class Val, class P, class N, class Ctrl, ReifyMode rm>
00399 ExecStatus
00400 ReEq<Val,P,N,Ctrl,rm>::post(Home home,
00401 ViewArray<P>& x, ViewArray<N>& y, Val c, Ctrl b) {
00402 ViewArray<NoView> nva;
00403 if (y.size() == 0) {
00404 (void) new (home) ReEq<Val,P,NoView,Ctrl,rm>(home,x,nva,c,b);
00405 } else if (x.size() == 0) {
00406 (void) new (home) ReEq<Val,N,NoView,Ctrl,rm>(home,y,nva,-c,b);
00407 } else {
00408 (void) new (home) ReEq<Val,P,N,Ctrl,rm>(home,x,y,c,b);
00409 }
00410 return ES_OK;
00411 }
00412
00413
00414 template<class Val, class P, class N, class Ctrl, ReifyMode rm>
00415 forceinline
00416 ReEq<Val,P,N,Ctrl,rm>::ReEq(Space& home, bool share,
00417 ReEq<Val,P,N,Ctrl,rm>& p)
00418 : ReLin<Val,P,N,PC_INT_BND,Ctrl>(home,share,p) {}
00419
00420 template<class Val, class P, class N, class Ctrl, ReifyMode rm>
00421 Actor*
00422 ReEq<Val,P,N,Ctrl,rm>::copy(Space& home, bool share) {
00423 return new (home) ReEq<Val,P,N,Ctrl,rm>(home,share,*this);
00424 }
00425
00426 template<class Val, class P, class N, class Ctrl, ReifyMode rm>
00427 ExecStatus
00428 ReEq<Val,P,N,Ctrl,rm>::propagate(Space& home, const ModEventDelta& med) {
00429 if (b.zero()) {
00430 if (rm == RM_IMP)
00431 return home.ES_SUBSUMED(*this);
00432 GECODE_REWRITE(*this,(Nq<Val,P,N>::post(home(*this),x,y,c)));
00433 }
00434 if (b.one()) {
00435 if (rm == RM_PMI)
00436 return home.ES_SUBSUMED(*this);
00437 GECODE_REWRITE(*this,(Eq<Val,P,N>::post(home(*this),x,y,c)));
00438 }
00439
00440 Val sl = 0;
00441 Val su = 0;
00442
00443 bounds_p<Val,P>(med, x, c, sl, su);
00444 bounds_n<Val,N>(med, y, c, sl, su);
00445
00446 if ((-sl == c) && (-su == c)) {
00447 if (rm != RM_IMP)
00448 GECODE_ME_CHECK(b.one_none(home));
00449 return home.ES_SUBSUMED(*this);
00450 }
00451 if ((-sl > c) || (-su < c)) {
00452 if (rm != RM_PMI)
00453 GECODE_ME_CHECK(b.zero_none(home));
00454 return home.ES_SUBSUMED(*this);
00455 }
00456 return ES_FIX;
00457 }
00458
00459
00460
00461
00462
00463
00464
00465 template<class Val, class P, class N>
00466 forceinline
00467 Nq<Val,P,N>::Nq(Home home, ViewArray<P>& x, ViewArray<N>& y, Val c)
00468 : Lin<Val,P,N,PC_INT_VAL>(home,x,y,c) {}
00469
00470 template<class Val, class P, class N>
00471 ExecStatus
00472 Nq<Val,P,N>::post(Home home, ViewArray<P>& x, ViewArray<N>& y, Val c) {
00473 ViewArray<NoView> nva;
00474 if (y.size() == 0) {
00475 (void) new (home) Nq<Val,P,NoView>(home,x,nva,c);
00476 } else if (x.size() == 0) {
00477 (void) new (home) Nq<Val,N,NoView>(home,y,nva,-c);
00478 } else {
00479 (void) new (home) Nq<Val,P,N>(home,x,y,c);
00480 }
00481 return ES_OK;
00482 }
00483
00484
00485 template<class Val, class P, class N>
00486 forceinline
00487 Nq<Val,P,N>::Nq(Space& home, bool share, Nq<Val,P,N>& p)
00488 : Lin<Val,P,N,PC_INT_VAL>(home,share,p) {}
00489
00494 template<class Val, class P, class N>
00495 forceinline Actor*
00496 nqtobin(Space&, bool, Propagator&, ViewArray<P>&, ViewArray<N>&, Val) {
00497 return NULL;
00498 }
00499 template<class Val>
00500 forceinline Actor*
00501 nqtobin(Space& home, bool share, Propagator& p,
00502 ViewArray<IntView>& x, ViewArray<NoView>&, Val c) {
00503 assert(x.size() == 2);
00504 return new (home) NqBin<Val,IntView,IntView>
00505 (home,share,p,x[0],x[1],c);
00506 }
00507 template<class Val>
00508 forceinline Actor*
00509 nqtobin(Space& home, bool share, Propagator& p,
00510 ViewArray<NoView>&, ViewArray<IntView>& y, Val c) {
00511 assert(y.size() == 2);
00512 return new (home) NqBin<Val,IntView,IntView>
00513 (home,share,p,y[0],y[1],-c);
00514 }
00515 template<class Val>
00516 forceinline Actor*
00517 nqtobin(Space& home, bool share, Propagator& p,
00518 ViewArray<IntView>& x, ViewArray<IntView>& y, Val c) {
00519 if (x.size() == 2)
00520 return new (home) NqBin<Val,IntView,IntView>
00521 (home,share,p,x[0],x[1],c);
00522 if (x.size() == 1)
00523 return new (home) NqBin<Val,IntView,MinusView>
00524 (home,share,p,x[0],MinusView(y[0]),c);
00525 return new (home) NqBin<Val,IntView,IntView>
00526 (home,share,p,y[0],y[1],-c);
00527 }
00528
00533 template<class Val, class P, class N>
00534 forceinline Actor*
00535 nqtoter(Space&, bool, Propagator&,ViewArray<P>&, ViewArray<N>&, Val) {
00536 return NULL;
00537 }
00538 template<class Val>
00539 forceinline Actor*
00540 nqtoter(Space& home, bool share, Propagator& p,
00541 ViewArray<IntView>& x, ViewArray<NoView>&, Val c) {
00542 assert(x.size() == 3);
00543 return new (home) NqTer<Val,IntView,IntView,IntView>
00544 (home,share,p,x[0],x[1],x[2],c);
00545 }
00546 template<class Val>
00547 forceinline Actor*
00548 nqtoter(Space& home, bool share, Propagator& p,
00549 ViewArray<NoView>&, ViewArray<IntView>& y, Val c) {
00550 assert(y.size() == 3);
00551 return new (home) NqTer<Val,IntView,IntView,IntView>
00552 (home,share,p,y[0],y[1],y[2],-c);
00553 }
00554 template<class Val>
00555 forceinline Actor*
00556 nqtoter(Space& home, bool share, Propagator& p,
00557 ViewArray<IntView>& x, ViewArray<IntView>& y, Val c) {
00558 if (x.size() == 3)
00559 return new (home) NqTer<Val,IntView,IntView,IntView>
00560 (home,share,p,x[0],x[1],x[2],c);
00561 if (x.size() == 2)
00562 return new (home) NqTer<Val,IntView,IntView,MinusView>
00563 (home,share,p,x[0],x[1],MinusView(y[0]),c);
00564 if (x.size() == 1)
00565 return new (home) NqTer<Val,IntView,IntView,MinusView>
00566 (home,share,p,y[0],y[1],MinusView(x[0]),-c);
00567 return new (home) NqTer<Val,IntView,IntView,IntView>
00568 (home,share,p,y[0],y[1],y[2],-c);
00569 }
00570
00571 template<class Val, class P, class N>
00572 Actor*
00573 Nq<Val,P,N>::copy(Space& home, bool share) {
00574 if (isunit(x,y)) {
00575
00576 if (x.size() + y.size() == 2)
00577 return nqtobin(home,share,*this,x,y,c);
00578 if (x.size() + y.size() == 3)
00579 return nqtoter(home,share,*this,x,y,c);
00580 }
00581 return new (home) Nq<Val,P,N>(home,share,*this);
00582 }
00583
00584 template<class Val, class P, class N>
00585 ExecStatus
00586 Nq<Val,P,N>::propagate(Space& home, const ModEventDelta&) {
00587 for (int i = x.size(); i--; )
00588 if (x[i].assigned()) {
00589 c -= x[i].val(); x.move_lst(i);
00590 }
00591 for (int i = y.size(); i--; )
00592 if (y[i].assigned()) {
00593 c += y[i].val(); y.move_lst(i);
00594 }
00595 if (x.size() + y.size() <= 1) {
00596 if (x.size() == 1) {
00597 GECODE_ME_CHECK(x[0].nq(home,c)); return home.ES_SUBSUMED(*this);
00598 }
00599 if (y.size() == 1) {
00600 GECODE_ME_CHECK(y[0].nq(home,-c)); return home.ES_SUBSUMED(*this);
00601 }
00602 return (c == static_cast<Val>(0)) ?
00603 ES_FAILED : home.ES_SUBSUMED(*this);
00604 }
00605 return ES_FIX;
00606 }
00607
00608
00609
00610
00611
00612
00613
00614 template<class Val, class P, class N>
00615 forceinline
00616 Lq<Val,P,N>::Lq(Home home, ViewArray<P>& x, ViewArray<N>& y, Val c)
00617 : Lin<Val,P,N,PC_INT_BND>(home,x,y,c) {}
00618
00619 template<class Val, class P, class N>
00620 ExecStatus
00621 Lq<Val,P,N>::post(Home home, ViewArray<P>& x, ViewArray<N>& y, Val c) {
00622 ViewArray<NoView> nva;
00623 if (y.size() == 0) {
00624 (void) new (home) Lq<Val,P,NoView>(home,x,nva,c);
00625 } else if (x.size() == 0) {
00626 (void) new (home) Lq<Val,NoView,N>(home,nva,y,c);
00627 } else {
00628 (void) new (home) Lq<Val,P,N>(home,x,y,c);
00629 }
00630 return ES_OK;
00631 }
00632
00633
00634 template<class Val, class P, class N>
00635 forceinline
00636 Lq<Val,P,N>::Lq(Space& home, bool share, Lq<Val,P,N>& p)
00637 : Lin<Val,P,N,PC_INT_BND>(home,share,p) {}
00638
00643 template<class Val, class P, class N>
00644 forceinline Actor*
00645 lqtobin(Space&, bool, Propagator&,ViewArray<P>&, ViewArray<N>&, Val) {
00646 return NULL;
00647 }
00648 template<class Val>
00649 forceinline Actor*
00650 lqtobin(Space& home, bool share, Propagator& p,
00651 ViewArray<IntView>& x, ViewArray<NoView>&, Val c) {
00652 assert(x.size() == 2);
00653 return new (home) LqBin<Val,IntView,IntView>
00654 (home,share,p,x[0],x[1],c);
00655 }
00656 template<class Val>
00657 forceinline Actor*
00658 lqtobin(Space& home, bool share, Propagator& p,
00659 ViewArray<NoView>&, ViewArray<IntView>& y, Val c) {
00660 assert(y.size() == 2);
00661 return new (home) LqBin<Val,MinusView,MinusView>
00662 (home,share,p,MinusView(y[0]),MinusView(y[1]),c);
00663 }
00664 template<class Val>
00665 forceinline Actor*
00666 lqtobin(Space& home, bool share, Propagator& p,
00667 ViewArray<IntView>& x, ViewArray<IntView>& y, Val c) {
00668 if (x.size() == 2)
00669 return new (home) LqBin<Val,IntView,IntView>
00670 (home,share,p,x[0],x[1],c);
00671 if (x.size() == 1)
00672 return new (home) LqBin<Val,IntView,MinusView>
00673 (home,share,p,x[0],MinusView(y[0]),c);
00674 return new (home) LqBin<Val,MinusView,MinusView>
00675 (home,share,p,MinusView(y[0]),MinusView(y[1]),c);
00676 }
00677
00682 template<class Val, class P, class N>
00683 forceinline Actor*
00684 lqtoter(Space&, bool, Propagator&, ViewArray<P>&, ViewArray<N>&, Val) {
00685 return NULL;
00686 }
00687 template<class Val>
00688 forceinline Actor*
00689 lqtoter(Space& home, bool share, Propagator& p,
00690 ViewArray<IntView>& x, ViewArray<NoView>&, Val c) {
00691 assert(x.size() == 3);
00692 return new (home) LqTer<Val,IntView,IntView,IntView>
00693 (home,share,p,x[0],x[1],x[2],c);
00694 }
00695 template<class Val>
00696 forceinline Actor*
00697 lqtoter(Space& home, bool share, Propagator& p,
00698 ViewArray<NoView>&, ViewArray<IntView>& y, Val c) {
00699 assert(y.size() == 3);
00700 return new (home) LqTer<Val,MinusView,MinusView,MinusView>
00701 (home,share,p,MinusView(y[0]),MinusView(y[1]),MinusView(y[2]),c);
00702 }
00703 template<class Val>
00704 forceinline Actor*
00705 lqtoter(Space& home, bool share, Propagator& p,
00706 ViewArray<IntView>& x, ViewArray<IntView>& y, Val c) {
00707 if (x.size() == 3)
00708 return new (home) LqTer<Val,IntView,IntView,IntView>
00709 (home,share,p,x[0],x[1],x[2],c);
00710 if (x.size() == 2)
00711 return new (home) LqTer<Val,IntView,IntView,MinusView>
00712 (home,share,p,x[0],x[1],MinusView(y[0]),c);
00713 if (x.size() == 1)
00714 return new (home) LqTer<Val,IntView,MinusView,MinusView>
00715 (home,share,p,x[0],MinusView(y[0]),MinusView(y[1]),c);
00716 return new (home) LqTer<Val,MinusView,MinusView,MinusView>
00717 (home,share,p,MinusView(y[0]),MinusView(y[1]),MinusView(y[2]),c);
00718 }
00719
00720 template<class Val, class P, class N>
00721 Actor*
00722 Lq<Val,P,N>::copy(Space& home, bool share) {
00723 if (isunit(x,y)) {
00724
00725 if (x.size() + y.size() == 2)
00726 return lqtobin(home,share,*this,x,y,c);
00727 if (x.size() + y.size() == 3)
00728 return lqtoter(home,share,*this,x,y,c);
00729 }
00730 return new (home) Lq<Val,P,N>(home,share,*this);
00731 }
00732
00733 template<class Val, class P, class N>
00734 ExecStatus
00735 Lq<Val,P,N>::propagate(Space& home, const ModEventDelta& med) {
00736
00737 Val sl = 0;
00738
00739 if (IntView::me(med) == ME_INT_VAL) {
00740 for (int i = x.size(); i--; ) {
00741 Val m = x[i].min();
00742 if (x[i].assigned()) {
00743 c -= m; x.move_lst(i);
00744 } else {
00745 sl -= m;
00746 }
00747 }
00748 for (int i = y.size(); i--; ) {
00749 Val m = y[i].max();
00750 if (y[i].assigned()) {
00751 c += m; y.move_lst(i);
00752 } else {
00753 sl += m;
00754 }
00755 }
00756 if ((x.size() + y.size()) <= 1) {
00757 if (x.size() == 1) {
00758 GECODE_ME_CHECK(x[0].lq(home,c));
00759 return home.ES_SUBSUMED(*this);
00760 }
00761 if (y.size() == 1) {
00762 GECODE_ME_CHECK(y[0].gq(home,-c));
00763 return home.ES_SUBSUMED(*this);
00764 }
00765 return (c >= static_cast<Val>(0)) ?
00766 home.ES_SUBSUMED(*this) : ES_FAILED;
00767 }
00768 } else {
00769 for (int i = x.size(); i--; )
00770 sl -= x[i].min();
00771 for (int i = y.size(); i--; )
00772 sl += y[i].max();
00773 }
00774
00775 sl += c;
00776
00777 ExecStatus es = ES_FIX;
00778 bool assigned = true;
00779 for (int i = x.size(); i--; ) {
00780 assert(!x[i].assigned());
00781 Val slx = sl + x[i].min();
00782 ModEvent me = x[i].lq(home,slx);
00783 if (me == ME_INT_FAILED)
00784 return ES_FAILED;
00785 if (me != ME_INT_VAL)
00786 assigned = false;
00787 if (me_modified(me) && (slx != x[i].max()))
00788 es = ES_NOFIX;
00789 }
00790
00791 for (int i = y.size(); i--; ) {
00792 assert(!y[i].assigned());
00793 Val sly = y[i].max() - sl;
00794 ModEvent me = y[i].gq(home,sly);
00795 if (me == ME_INT_FAILED)
00796 return ES_FAILED;
00797 if (me != ME_INT_VAL)
00798 assigned = false;
00799 if (me_modified(me) && (sly != y[i].min()))
00800 es = ES_NOFIX;
00801 }
00802 return assigned ? home.ES_SUBSUMED(*this) : es;
00803 }
00804
00805
00806
00807
00808
00809
00810 template<class Val, class P, class N, ReifyMode rm>
00811 forceinline
00812 ReLq<Val,P,N,rm>::ReLq(Home home,
00813 ViewArray<P>& x, ViewArray<N>& y, Val c, BoolView b)
00814 : ReLin<Val,P,N,PC_INT_BND,BoolView>(home,x,y,c,b) {}
00815
00816 template<class Val, class P, class N, ReifyMode rm>
00817 ExecStatus
00818 ReLq<Val,P,N,rm>::post(Home home,
00819 ViewArray<P>& x, ViewArray<N>& y, Val c, BoolView b) {
00820 ViewArray<NoView> nva;
00821 if (y.size() == 0) {
00822 (void) new (home) ReLq<Val,P,NoView,rm>(home,x,nva,c,b);
00823 } else if (x.size() == 0) {
00824 (void) new (home) ReLq<Val,NoView,N,rm>(home,nva,y,c,b);
00825 } else {
00826 (void) new (home) ReLq<Val,P,N,rm>(home,x,y,c,b);
00827 }
00828 return ES_OK;
00829 }
00830
00831
00832 template<class Val, class P, class N, ReifyMode rm>
00833 forceinline
00834 ReLq<Val,P,N,rm>::ReLq(Space& home, bool share, ReLq<Val,P,N,rm>& p)
00835 : ReLin<Val,P,N,PC_INT_BND,BoolView>(home,share,p) {}
00836
00837 template<class Val, class P, class N, ReifyMode rm>
00838 Actor*
00839 ReLq<Val,P,N,rm>::copy(Space& home, bool share) {
00840 return new (home) ReLq<Val,P,N,rm>(home,share,*this);
00841 }
00842
00843 template<class Val, class P, class N, ReifyMode rm>
00844 ExecStatus
00845 ReLq<Val,P,N,rm>::propagate(Space& home, const ModEventDelta& med) {
00846 if (b.zero()) {
00847 if (rm == RM_IMP)
00848 return home.ES_SUBSUMED(*this);
00849 GECODE_REWRITE(*this,(Lq<Val,N,P>::post(home(*this),y,x,-c-1)));
00850 }
00851 if (b.one()) {
00852 if (rm == RM_PMI)
00853 return home.ES_SUBSUMED(*this);
00854 GECODE_REWRITE(*this,(Lq<Val,P,N>::post(home(*this),x,y,c)));
00855 }
00856
00857
00858 Val sl = 0;
00859 Val su = 0;
00860
00861 bounds_p<Val,P>(med,x,c,sl,su);
00862 bounds_n<Val,N>(med,y,c,sl,su);
00863
00864 if (-sl > c) {
00865 if (rm != RM_PMI)
00866 GECODE_ME_CHECK(b.zero_none(home));
00867 return home.ES_SUBSUMED(*this);
00868 }
00869 if (-su <= c) {
00870 if (rm != RM_IMP)
00871 GECODE_ME_CHECK(b.one_none(home));
00872 return home.ES_SUBSUMED(*this);
00873 }
00874
00875 return ES_FIX;
00876 }
00877
00878 }}}
00879
00880
00881