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.icc"
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(Space* 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(ModEventDelta) const {
00082 return cost_lo(x.size() + y.size(), PC_LINEAR_LO);
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 assert(!home->failed());
00089 x.cancel(home,this,pc);
00090 y.cancel(home,this,pc);
00091 (void) Propagator::dispose(home);
00092 return sizeof(*this);
00093 }
00094
00095 template <class Val, class P, class N, PropCond pc>
00096 Reflection::ActorSpec
00097 Lin<Val,P,N,pc>::spec(const Space* home, Reflection::VarMap& m,
00098 const Support::Symbol& ati) const {
00099 Reflection::ActorSpec s(ati);
00100 return s << x.spec(home, m)
00101 << y.spec(home, m)
00102 << c;
00103 }
00104
00105
00106
00107
00108
00109 template <class Val, class P, class N, PropCond pc, class Ctrl>
00110 forceinline
00111 ReLin<Val,P,N,pc,Ctrl>::ReLin
00112 (Space* home, ViewArray<P>& x, ViewArray<N>& y, Val c, Ctrl b0)
00113 : Lin<Val,P,N,pc>(home,x,y,c), b(b0) {
00114 b.subscribe(home,this,PC_INT_VAL);
00115 }
00116
00117 template <class Val, class P, class N, PropCond pc, class Ctrl>
00118 forceinline
00119 ReLin<Val,P,N,pc,Ctrl>::ReLin
00120 (Space* home, bool share, ReLin<Val,P,N,pc,Ctrl>& p)
00121 : Lin<Val,P,N,pc>(home,share,p) {
00122 b.update(home,share,p.b);
00123 }
00124
00125 template <class Val, class P, class N, PropCond pc, class Ctrl>
00126 forceinline size_t
00127 ReLin<Val,P,N,pc,Ctrl>::dispose(Space* home) {
00128 assert(!home->failed());
00129 b.cancel(home,this,PC_BOOL_VAL);
00130 (void) Lin<Val,P,N,pc>::dispose(home);
00131 return sizeof(*this);
00132 }
00133
00134 template <class Val, class P, class N, PropCond pc, class Ctrl>
00135 Reflection::ActorSpec
00136 ReLin<Val,P,N,pc,Ctrl>::spec(const Space* home, Reflection::VarMap& m,
00137 const Support::Symbol& ati) const {
00138 Reflection::ActorSpec s(ati);
00139 return s << Lin<Val,P,N,pc>::x.spec(home, m)
00140 << Lin<Val,P,N,pc>::y.spec(home, m)
00141 << Lin<Val,P,N,pc>::c
00142 << b.spec(home, m);
00143 }
00144
00145
00146
00147
00148
00149
00150 template <class Val, class View>
00151 void
00152 bounds_p(ModEventDelta med, ViewArray<View>& x, Val& c, Val& sl, Val& su) {
00153 int n = x.size();
00154 if (IntView::me(med) == ME_INT_VAL) {
00155 for (int i = n; i--; ) {
00156 Val m = x[i].min();
00157 if (x[i].assigned()) {
00158 c -= m; x[i] = x[--n];
00159 } else {
00160 sl -= m; su -= x[i].max();
00161 }
00162 }
00163 x.size(n);
00164 } else {
00165 for (int i = n; i--; ) {
00166 sl -= x[i].min(); su -= x[i].max();
00167 }
00168 }
00169 }
00170
00171 template <class Val, class View>
00172 void
00173 bounds_n(ModEventDelta med, ViewArray<View>& y, Val& c, Val& sl, Val& su) {
00174 int n = y.size();
00175 if (IntView::me(med) == ME_INT_VAL) {
00176 for (int i = n; i--; ) {
00177 Val m = y[i].max();
00178 if (y[i].assigned()) {
00179 c += m; y[i] = y[--n];
00180 } else {
00181 sl += m; su += y[i].min();
00182 }
00183 }
00184 y.size(n);
00185 } else {
00186 for (int i = n; i--; ) {
00187 sl += y[i].max(); su += y[i].min();
00188 }
00189 }
00190 }
00191
00192
00193 template <class Val, class P, class N>
00194 ExecStatus
00195 prop_bnd(Space* home, ModEventDelta med, Propagator* p,
00196 ViewArray<P>& x, ViewArray<N>& y, Val& c) {
00197
00198 Val sl = 0;
00199 Val su = 0;
00200
00201 bounds_p<Val,P>(med, x, c, sl, su);
00202 bounds_n<Val,N>(med, y, c, sl, su);
00203
00204 if ((IntView::me(med) == ME_INT_VAL) && ((x.size() + y.size()) <= 1)) {
00205 if (x.size() == 1) {
00206 GECODE_ME_CHECK(x[0].eq(home,c));
00207 return ES_SUBSUMED(p,sizeof(*p));
00208 }
00209 if (y.size() == 1) {
00210 GECODE_ME_CHECK(y[0].eq(home,-c));
00211 return ES_SUBSUMED(p,sizeof(*p));
00212 }
00213 return (c == static_cast<Val>(0)) ?
00214 ES_SUBSUMED(p,sizeof(*p)) : ES_FAILED;
00215 }
00216
00217 sl += c; su += c;
00218
00219 const int mod_sl = 1;
00220 const int mod_su = 2;
00221
00222 int mod = mod_sl | mod_su;
00223
00224 do {
00225 if (mod & mod_sl) {
00226 mod -= mod_sl;
00227
00228 for (int i = x.size(); i--; ) {
00229 const Val xi_max = x[i].max();
00230 ModEvent me = x[i].lq(home,sl + x[i].min());
00231 if (me_failed(me))
00232 return ES_FAILED;
00233 if (me_modified(me)) {
00234 su += xi_max - x[i].max();
00235 mod |= mod_su;
00236 }
00237 }
00238
00239 for (int i = y.size(); i--; ) {
00240 const Val yi_min = y[i].min();
00241 ModEvent me = y[i].gq(home,y[i].max() - sl);
00242 if (me_failed(me))
00243 return ES_FAILED;
00244 if (me_modified(me)) {
00245 su += y[i].min() - yi_min;
00246 mod |= mod_su;
00247 }
00248 }
00249 }
00250 if (mod & mod_su) {
00251 mod -= mod_su;
00252
00253 for (int i = x.size(); i--; ) {
00254 const Val xi_min = x[i].min();
00255 ModEvent me = x[i].gq(home,su + x[i].max());
00256 if (me_failed(me))
00257 return ES_FAILED;
00258 if (me_modified(me)) {
00259 sl += xi_min - x[i].min();
00260 mod |= mod_sl;
00261 }
00262 }
00263
00264 for (int i = y.size(); i--; ) {
00265 const Val yi_max = y[i].max();
00266 ModEvent me = y[i].lq(home,y[i].min() - su);
00267 if (me_failed(me))
00268 return ES_FAILED;
00269 if (me_modified(me)) {
00270 sl += y[i].max() - yi_max;
00271 mod |= mod_sl;
00272 }
00273 }
00274 }
00275 } while (mod);
00276
00277 return (sl == su) ? ES_SUBSUMED(p,sizeof(*p)) : ES_FIX;
00278 }
00279
00280
00281
00282
00283
00284
00285 template <class Val, class P, class N>
00286 forceinline
00287 Eq<Val,P,N>::Eq(Space* home, ViewArray<P>& x, ViewArray<N>& y, Val c)
00288 : Lin<Val,P,N,PC_INT_BND>(home,x,y,c) {}
00289
00290 template <class Val, class P, class N>
00291 ExecStatus
00292 Eq<Val,P,N>::post(Space* home, ViewArray<P>& x, ViewArray<N>& y, Val c) {
00293 ViewArray<NoView> nva;
00294 if (y.size() == 0) {
00295 (void) new (home) Eq<Val,P,NoView>(home,x,nva,c);
00296 } else if (x.size() == 0) {
00297 (void) new (home) Eq<Val,N,NoView>(home,y,nva,-c);
00298 } else {
00299 (void) new (home) Eq<Val,P,N>(home,x,y,c);
00300 }
00301 return ES_OK;
00302 }
00303
00304
00305 template <class Val, class P, class N>
00306 forceinline
00307 Eq<Val,P,N>::Eq(Space* home, bool share, Eq<Val,P,N>& p)
00308 : Lin<Val,P,N,PC_INT_BND>(home,share,p) {}
00309
00314 template <class Val, class P, class N>
00315 forceinline Actor*
00316 eqtobin(Space*, bool, Propagator&, ViewArray<P>&, ViewArray<N>&, Val) {
00317 return NULL;
00318 }
00319 template <class Val>
00320 forceinline Actor*
00321 eqtobin(Space* home, bool share, Propagator& p,
00322 ViewArray<IntView>& x, ViewArray<NoView>&, Val c) {
00323 assert(x.size() == 2);
00324 return new (home) EqBin<Val,IntView,IntView>
00325 (home,share,p,x[0],x[1],c);
00326 }
00327 template <class Val>
00328 forceinline Actor*
00329 eqtobin(Space* home, bool share, Propagator& p,
00330 ViewArray<NoView>&, ViewArray<IntView>& y, Val c) {
00331 assert(y.size() == 2);
00332 return new (home) EqBin<Val,IntView,IntView>
00333 (home,share,p,y[0],y[1],-c);
00334 }
00335 template <class Val>
00336 forceinline Actor*
00337 eqtobin(Space* home, bool share, Propagator& p,
00338 ViewArray<IntView>& x, ViewArray<IntView>& y, Val c) {
00339 if (x.size() == 2)
00340 return new (home) EqBin<Val,IntView,IntView>
00341 (home,share,p,x[0],x[1],c);
00342 if (x.size() == 1)
00343 return new (home) EqBin<Val,IntView,MinusView>
00344 (home,share,p,x[0],y[0],c);
00345 return new (home) EqBin<Val,IntView,IntView>
00346 (home,share,p,y[0],y[1],-c);
00347 }
00348
00353 template <class Val, class P, class N>
00354 forceinline Actor*
00355 eqtoter(Space*, bool, Propagator&, ViewArray<P>&, ViewArray<N>&, Val) {
00356 return NULL;
00357 }
00358 template <class Val>
00359 forceinline Actor*
00360 eqtoter(Space* home, bool share, Propagator& p,
00361 ViewArray<IntView>& x, ViewArray<NoView>&, Val c) {
00362 assert(x.size() == 3);
00363 return new (home) EqTer<Val,IntView,IntView,IntView>
00364 (home,share,p,x[0],x[1],x[2],c);
00365 }
00366 template <class Val>
00367 forceinline Actor*
00368 eqtoter(Space* home, bool share, Propagator& p,
00369 ViewArray<NoView>&, ViewArray<IntView>& y, Val c) {
00370 assert(y.size() == 3);
00371 return new (home) EqTer<Val,IntView,IntView,IntView>
00372 (home,share,p,y[0],y[1],y[2],-c);
00373 }
00374 template <class Val>
00375 forceinline Actor*
00376 eqtoter(Space* home, bool share, Propagator& p,
00377 ViewArray<IntView>& x, ViewArray<IntView>& y, Val c) {
00378 if (x.size() == 3)
00379 return new (home) EqTer<Val,IntView,IntView,IntView>
00380 (home,share,p,x[0],x[1],x[2],c);
00381 if (x.size() == 2)
00382 return new (home) EqTer<Val,IntView,IntView,MinusView>
00383 (home,share,p,x[0],x[1],y[0],c);
00384 if (x.size() == 1)
00385 return new (home) EqTer<Val,IntView,IntView,MinusView>
00386 (home,share,p,y[0],y[1],x[0],-c);
00387 return new (home) EqTer<Val,IntView,IntView,IntView>
00388 (home,share,p,y[0],y[1],y[2],-c);
00389 }
00390
00391 template <class Val, class P, class N>
00392 Actor*
00393 Eq<Val,P,N>::copy(Space* home, bool share) {
00394 if (isunit(x,y)) {
00395
00396 if (x.size() + y.size() == 2)
00397 return eqtobin(home,share,*this,x,y,c);
00398 if (x.size() + y.size() == 3)
00399 return eqtoter(home,share,*this,x,y,c);
00400 }
00401 return new (home) Eq<Val,P,N>(home,share,*this);
00402 }
00403
00404
00405 template <class Val, class P, class N>
00406 inline Support::Symbol
00407 Eq<Val,P,N>::ati(void) {
00408 return Reflection::mangle<Val,P,N>("Gecode::Int::Linear::Eq");
00409 }
00410
00411 template <class Val, class P, class N>
00412 Reflection::ActorSpec
00413 Eq<Val,P,N>::spec(const Space* home, Reflection::VarMap& m) const {
00414 return Lin<Val,P,N,PC_INT_BND>::spec(home, m, ati());
00415 }
00416
00417 template <class Val, class P, class N>
00418 void
00419 Eq<Val,P,N>::post(Space* home, Reflection::VarMap& vars,
00420 const Reflection::ActorSpec& spec) {
00421 spec.checkArity(3);
00422 ViewArray<P> x(home, vars, spec[0]);
00423 ViewArray<N> y(home, vars, spec[1]);
00424 Val c = spec[2]->toInt();
00425 (void) new (home) Eq<Val,P,N>(home, x, y, c);
00426 }
00427
00428 template <class Val, class P, class N>
00429 ExecStatus
00430 Eq<Val,P,N>::propagate(Space* home, ModEventDelta med) {
00431 return prop_bnd<Val,P,N>(home,med,this,x,y,c);
00432 }
00433
00434
00435
00436
00437
00438
00439 template <class Val, class P, class N, class Ctrl>
00440 forceinline
00441 ReEq<Val,P,N,Ctrl>::ReEq(Space* home,
00442 ViewArray<P>& x, ViewArray<N>& y, Val c, Ctrl b)
00443 : ReLin<Val,P,N,PC_INT_BND,Ctrl>(home,x,y,c,b) {}
00444
00445 template <class Val, class P, class N, class Ctrl>
00446 ExecStatus
00447 ReEq<Val,P,N,Ctrl>::post(Space* home,
00448 ViewArray<P>& x, ViewArray<N>& y, Val c, Ctrl b) {
00449 ViewArray<NoView> nva;
00450 if (y.size() == 0) {
00451 (void) new (home) ReEq<Val,P,NoView,Ctrl>(home,x,nva,c,b);
00452 } else if (x.size() == 0) {
00453 (void) new (home) ReEq<Val,N,NoView,Ctrl>(home,y,nva,-c,b);
00454 } else {
00455 (void) new (home) ReEq<Val,P,N,Ctrl>(home,x,y,c,b);
00456 }
00457 return ES_OK;
00458 }
00459
00460
00461 template <class Val, class P, class N, class Ctrl>
00462 forceinline
00463 ReEq<Val,P,N,Ctrl>::ReEq(Space* home, bool share, ReEq<Val,P,N,Ctrl>& p)
00464 : ReLin<Val,P,N,PC_INT_BND,Ctrl>(home,share,p) {}
00465
00466 template <class Val, class P, class N, class Ctrl>
00467 Actor*
00468 ReEq<Val,P,N,Ctrl>::copy(Space* home, bool share) {
00469 return new (home) ReEq<Val,P,N,Ctrl>(home,share,*this);
00470 }
00471
00472 template <class Val, class P, class N, class Ctrl>
00473 inline Support::Symbol
00474 ReEq<Val,P,N,Ctrl>::ati(void) {
00475 return Reflection::mangle<Val,P,N,Ctrl>("Gecode::Int::Linear::ReEq");
00476 }
00477
00478 template <class Val, class P, class N, class Ctrl>
00479 Reflection::ActorSpec
00480 ReEq<Val,P,N,Ctrl>::spec(const Space* home, Reflection::VarMap& m) const {
00481 return ReLin<Val,P,N,PC_INT_BND,Ctrl>::spec(home, m, ati());
00482 }
00483
00484 template <class Val, class P, class N, class Ctrl>
00485 void
00486 ReEq<Val,P,N,Ctrl>::post(Space* home, Reflection::VarMap& vars,
00487 const Reflection::ActorSpec& spec) {
00488 spec.checkArity(4);
00489 ViewArray<P> x(home, vars, spec[0]);
00490 ViewArray<N> y(home, vars, spec[1]);
00491 Val c = spec[2]->toInt();
00492 Ctrl b(home, vars, spec[3]);
00493 (void) new (home) ReEq<Val,P,N,Ctrl>(home, x, y, c, b);
00494 }
00495
00496 template <class Val, class P, class N, class Ctrl>
00497 ExecStatus
00498 ReEq<Val,P,N,Ctrl>::propagate(Space* home, ModEventDelta med) {
00499 if (b.zero())
00500 GECODE_REWRITE(this,(Nq<Val,P,N>::post(home,x,y,c)));
00501 if (b.one())
00502 GECODE_REWRITE(this,(Eq<Val,P,N>::post(home,x,y,c)));
00503
00504 Val sl = 0;
00505 Val su = 0;
00506
00507 bounds_p<Val,P>(med, x, c, sl, su);
00508 bounds_n<Val,N>(med, y, c, sl, su);
00509
00510 if ((-sl == c) && (-su == c)) {
00511 GECODE_ME_CHECK(b.one_none(home));
00512 return ES_SUBSUMED(this,sizeof(*this));
00513 }
00514 if ((-sl > c) || (-su < c)) {
00515 GECODE_ME_CHECK(b.zero_none(home));
00516 return ES_SUBSUMED(this,home);
00517 }
00518 return ES_FIX;
00519 }
00520
00521
00522
00523
00524
00525
00526
00527 template <class Val, class P, class N>
00528 forceinline
00529 Nq<Val,P,N>::Nq(Space* home, ViewArray<P>& x, ViewArray<N>& y, Val c)
00530 : Lin<Val,P,N,PC_INT_VAL>(home,x,y,c) {}
00531
00532 template <class Val, class P, class N>
00533 ExecStatus
00534 Nq<Val,P,N>::post(Space* home, ViewArray<P>& x, ViewArray<N>& y, Val c) {
00535 ViewArray<NoView> nva;
00536 if (y.size() == 0) {
00537 (void) new (home) Nq<Val,P,NoView>(home,x,nva,c);
00538 } else if (x.size() == 0) {
00539 (void) new (home) Nq<Val,N,NoView>(home,y,nva,-c);
00540 } else {
00541 (void) new (home) Nq<Val,P,N>(home,x,y,c);
00542 }
00543 return ES_OK;
00544 }
00545
00546
00547 template <class Val, class P, class N>
00548 forceinline
00549 Nq<Val,P,N>::Nq(Space* home, bool share, Nq<Val,P,N>& p)
00550 : Lin<Val,P,N,PC_INT_VAL>(home,share,p) {}
00551
00556 template <class Val, class P, class N>
00557 forceinline Actor*
00558 nqtobin(Space*, bool, Propagator&, ViewArray<P>&, ViewArray<N>&, Val) {
00559 return NULL;
00560 }
00561 template <class Val>
00562 forceinline Actor*
00563 nqtobin(Space* home, bool share, Propagator& p,
00564 ViewArray<IntView>& x, ViewArray<NoView>&, Val c) {
00565 assert(x.size() == 2);
00566 return new (home) NqBin<Val,IntView,IntView>
00567 (home,share,p,x[0],x[1],c);
00568 }
00569 template <class Val>
00570 forceinline Actor*
00571 nqtobin(Space* home, bool share, Propagator& p,
00572 ViewArray<NoView>&, ViewArray<IntView>& y, Val c) {
00573 assert(y.size() == 2);
00574 return new (home) NqBin<Val,IntView,IntView>
00575 (home,share,p,y[0],y[1],-c);
00576 }
00577 template <class Val>
00578 forceinline Actor*
00579 nqtobin(Space* home, bool share, Propagator& p,
00580 ViewArray<IntView>& x, ViewArray<IntView>& y, Val c) {
00581 if (x.size() == 2)
00582 return new (home) NqBin<Val,IntView,IntView>
00583 (home,share,p,x[0],x[1],c);
00584 if (x.size() == 1)
00585 return new (home) NqBin<Val,IntView,MinusView>
00586 (home,share,p,x[0],y[0],c);
00587 return new (home) NqBin<Val,IntView,IntView>
00588 (home,share,p,y[0],y[1],-c);
00589 }
00590
00595 template <class Val, class P, class N>
00596 forceinline Actor*
00597 nqtoter(Space*, bool, Propagator&,ViewArray<P>&, ViewArray<N>&, Val) {
00598 return NULL;
00599 }
00600 template <class Val>
00601 forceinline Actor*
00602 nqtoter(Space* home, bool share, Propagator& p,
00603 ViewArray<IntView>& x, ViewArray<NoView>&, Val c) {
00604 assert(x.size() == 3);
00605 return new (home) NqTer<Val,IntView,IntView,IntView>
00606 (home,share,p,x[0],x[1],x[2],c);
00607 }
00608 template <class Val>
00609 forceinline Actor*
00610 nqtoter(Space* home, bool share, Propagator& p,
00611 ViewArray<NoView>&, ViewArray<IntView>& y, Val c) {
00612 assert(y.size() == 3);
00613 return new (home) NqTer<Val,IntView,IntView,IntView>
00614 (home,share,p,y[0],y[1],y[2],-c);
00615 }
00616 template <class Val>
00617 forceinline Actor*
00618 nqtoter(Space* home, bool share, Propagator& p,
00619 ViewArray<IntView>& x, ViewArray<IntView>& y, Val c) {
00620 if (x.size() == 3)
00621 return new (home) NqTer<Val,IntView,IntView,IntView>
00622 (home,share,p,x[0],x[1],x[2],c);
00623 if (x.size() == 2)
00624 return new (home) NqTer<Val,IntView,IntView,MinusView>
00625 (home,share,p,x[0],x[1],y[0],c);
00626 if (x.size() == 1)
00627 return new (home) NqTer<Val,IntView,IntView,MinusView>
00628 (home,share,p,y[0],y[1],x[0],-c);
00629 return new (home) NqTer<Val,IntView,IntView,IntView>
00630 (home,share,p,y[0],y[1],y[2],-c);
00631 }
00632
00633 template <class Val, class P, class N>
00634 Actor*
00635 Nq<Val,P,N>::copy(Space* home, bool share) {
00636 if (isunit(x,y)) {
00637
00638 if (x.size() + y.size() == 2)
00639 return nqtobin(home,share,*this,x,y,c);
00640 if (x.size() + y.size() == 3)
00641 return nqtoter(home,share,*this,x,y,c);
00642 }
00643 return new (home) Nq<Val,P,N>(home,share,*this);
00644 }
00645
00646 template <class Val, class P, class N>
00647 Support::Symbol
00648 Nq<Val,P,N>::ati(void) {
00649 return Reflection::mangle<Val,P,N>("Gecode::Int::Linear::Nq");
00650 }
00651
00652 template <class Val, class P, class N>
00653 Reflection::ActorSpec
00654 Nq<Val,P,N>::spec(const Space* home, Reflection::VarMap& m) const {
00655 return Lin<Val,P,N,PC_INT_VAL>::spec(home, m, ati());
00656 }
00657
00658 template <class Val, class P, class N>
00659 void
00660 Nq<Val,P,N>::post(Space* home, Reflection::VarMap& vars,
00661 const Reflection::ActorSpec& spec) {
00662 spec.checkArity(3);
00663 ViewArray<P> x(home, vars, spec[0]);
00664 ViewArray<N> y(home, vars, spec[1]);
00665 Val c = spec[2]->toInt();
00666 (void) new (home) Nq<Val,P,N>(home, x, y, c);
00667 }
00668
00669 template <class Val, class P, class N>
00670 ExecStatus
00671 Nq<Val,P,N>::propagate(Space* home, ModEventDelta) {
00672 for (int i = x.size(); i--; )
00673 if (x[i].assigned()) {
00674 c -= x[i].val(); x.move_lst(i);
00675 }
00676 for (int i = y.size(); i--; )
00677 if (y[i].assigned()) {
00678 c += y[i].val(); y.move_lst(i);
00679 }
00680 if (x.size() + y.size() <= 1) {
00681 if (x.size() == 1) {
00682 GECODE_ME_CHECK(x[0].nq(home,c)); return ES_SUBSUMED(this,home);
00683 }
00684 if (y.size() == 1) {
00685 GECODE_ME_CHECK(y[0].nq(home,-c)); return ES_SUBSUMED(this,home);
00686 }
00687 return (c == static_cast<Val>(0)) ?
00688 ES_FAILED : ES_SUBSUMED(this,sizeof(*this));
00689 }
00690 return ES_FIX;
00691 }
00692
00693
00694
00695
00696
00697
00698
00699 template <class Val, class P, class N>
00700 forceinline
00701 Lq<Val,P,N>::Lq(Space* home, ViewArray<P>& x, ViewArray<N>& y, Val c)
00702 : Lin<Val,P,N,PC_INT_BND>(home,x,y,c) {}
00703
00704 template <class Val, class P, class N>
00705 ExecStatus
00706 Lq<Val,P,N>::post(Space* home, ViewArray<P>& x, ViewArray<N>& y, Val c) {
00707 ViewArray<NoView> nva;
00708 if (y.size() == 0) {
00709 (void) new (home) Lq<Val,P,NoView>(home,x,nva,c);
00710 } else if (x.size() == 0) {
00711 (void) new (home) Lq<Val,NoView,N>(home,nva,y,c);
00712 } else {
00713 (void) new (home) Lq<Val,P,N>(home,x,y,c);
00714 }
00715 return ES_OK;
00716 }
00717
00718
00719 template <class Val, class P, class N>
00720 forceinline
00721 Lq<Val,P,N>::Lq(Space* home, bool share, Lq<Val,P,N>& p)
00722 : Lin<Val,P,N,PC_INT_BND>(home,share,p) {}
00723
00728 template <class Val, class P, class N>
00729 forceinline Actor*
00730 lqtobin(Space*, bool, Propagator&,ViewArray<P>&, ViewArray<N>&, Val) {
00731 return NULL;
00732 }
00733 template <class Val>
00734 forceinline Actor*
00735 lqtobin(Space* home, bool share, Propagator& p,
00736 ViewArray<IntView>& x, ViewArray<NoView>&, Val c) {
00737 assert(x.size() == 2);
00738 return new (home) LqBin<Val,IntView,IntView>
00739 (home,share,p,x[0],x[1],c);
00740 }
00741 template <class Val>
00742 forceinline Actor*
00743 lqtobin(Space* home, bool share, Propagator& p,
00744 ViewArray<NoView>&, ViewArray<IntView>& y, Val c) {
00745 assert(y.size() == 2);
00746 return new (home) LqBin<Val,MinusView,MinusView>
00747 (home,share,p,y[0],y[1],c);
00748 }
00749 template <class Val>
00750 forceinline Actor*
00751 lqtobin(Space* home, bool share, Propagator& p,
00752 ViewArray<IntView>& x, ViewArray<IntView>& y, Val c) {
00753 if (x.size() == 2)
00754 return new (home) LqBin<Val,IntView,IntView>
00755 (home,share,p,x[0],x[1],c);
00756 if (x.size() == 1)
00757 return new (home) LqBin<Val,IntView,MinusView>
00758 (home,share,p,x[0],y[0],c);
00759 return new (home) LqBin<Val,MinusView,MinusView>
00760 (home,share,p,y[0],y[1],c);
00761 }
00762
00767 template <class Val, class P, class N>
00768 forceinline Actor*
00769 lqtoter(Space*, bool, Propagator&, ViewArray<P>&, ViewArray<N>&, Val) {
00770 return NULL;
00771 }
00772 template <class Val>
00773 forceinline Actor*
00774 lqtoter(Space* home, bool share, Propagator& p,
00775 ViewArray<IntView>& x, ViewArray<NoView>&, Val c) {
00776 assert(x.size() == 3);
00777 return new (home) LqTer<Val,IntView,IntView,IntView>
00778 (home,share,p,x[0],x[1],x[2],c);
00779 }
00780 template <class Val>
00781 forceinline Actor*
00782 lqtoter(Space* home, bool share, Propagator& p,
00783 ViewArray<NoView>&, ViewArray<IntView>& y, Val c) {
00784 assert(y.size() == 3);
00785 return new (home) LqTer<Val,MinusView,MinusView,MinusView>
00786 (home,share,p,y[0],y[1],y[2],c);
00787 }
00788 template <class Val>
00789 forceinline Actor*
00790 lqtoter(Space* home, bool share, Propagator& p,
00791 ViewArray<IntView>& x, ViewArray<IntView>& y, Val c) {
00792 if (x.size() == 3)
00793 return new (home) LqTer<Val,IntView,IntView,IntView>
00794 (home,share,p,x[0],x[1],x[2],c);
00795 if (x.size() == 2)
00796 return new (home) LqTer<Val,IntView,IntView,MinusView>
00797 (home,share,p,x[0],x[1],y[0],c);
00798 if (x.size() == 1)
00799 return new (home) LqTer<Val,IntView,MinusView,MinusView>
00800 (home,share,p,x[0],y[0],y[1],c);
00801 return new (home) LqTer<Val,MinusView,MinusView,MinusView>
00802 (home,share,p,y[0],y[1],y[2],c);
00803 }
00804
00805 template <class Val, class P, class N>
00806 Actor*
00807 Lq<Val,P,N>::copy(Space* home, bool share) {
00808 if (isunit(x,y)) {
00809
00810 if (x.size() + y.size() == 2)
00811 return lqtobin(home,share,*this,x,y,c);
00812 if (x.size() + y.size() == 3)
00813 return lqtoter(home,share,*this,x,y,c);
00814 }
00815 return new (home) Lq<Val,P,N>(home,share,*this);
00816 }
00817
00818 template <class Val, class P, class N>
00819 inline Support::Symbol
00820 Lq<Val,P,N>::ati(void) {
00821 return Reflection::mangle<Val,P,N>("Gecode::Int::Linear::Lq");
00822 }
00823
00824 template <class Val, class P, class N>
00825 Reflection::ActorSpec
00826 Lq<Val,P,N>::spec(const Space* home, Reflection::VarMap& m) const {
00827 return Lin<Val,P,N,PC_INT_BND>::spec(home, m, ati());
00828 }
00829
00830 template <class Val, class P, class N>
00831 void
00832 Lq<Val,P,N>::post(Space* home, Reflection::VarMap& vars,
00833 const Reflection::ActorSpec& spec) {
00834 spec.checkArity(3);
00835 ViewArray<P> x(home, vars, spec[0]);
00836 ViewArray<N> y(home, vars, spec[1]);
00837 Val c = spec[2]->toInt();
00838 (void) new (home) Lq<Val,P,N>(home, x, y, c);
00839 }
00840
00841 template <class Val, class P, class N>
00842 ExecStatus
00843 Lq<Val,P,N>::propagate(Space* home, ModEventDelta med) {
00844
00845 Val sl = 0;
00846
00847 if (IntView::me(med) == ME_INT_VAL) {
00848 for (int i = x.size(); i--; ) {
00849 Val m = x[i].min();
00850 if (x[i].assigned()) {
00851 c -= m; x.move_lst(i);
00852 } else {
00853 sl -= m;
00854 }
00855 }
00856 for (int i = y.size(); i--; ) {
00857 Val m = y[i].max();
00858 if (y[i].assigned()) {
00859 c += m; y.move_lst(i);
00860 } else {
00861 sl += m;
00862 }
00863 }
00864 if ((x.size() + y.size()) <= 1) {
00865 if (x.size() == 1) {
00866 GECODE_ME_CHECK(x[0].lq(home,c));
00867 return ES_SUBSUMED(this,home);
00868 }
00869 if (y.size() == 1) {
00870 GECODE_ME_CHECK(y[0].gq(home,-c));
00871 return ES_SUBSUMED(this,home);
00872 }
00873 return (c >= static_cast<Val>(0)) ?
00874 ES_SUBSUMED(this,sizeof(*this)) : ES_FAILED;
00875 }
00876 } else {
00877 for (int i = x.size(); i--; )
00878 sl -= x[i].min();
00879 for (int i = y.size(); i--; )
00880 sl += y[i].max();
00881 }
00882
00883 sl += c;
00884
00885 ExecStatus es = ES_FIX;
00886 bool assigned = true;
00887 for (int i = x.size(); i--; ) {
00888 assert(!x[i].assigned());
00889 Val slx = sl + x[i].min();
00890 ModEvent me = x[i].lq(home,slx);
00891 if (me == ME_INT_FAILED)
00892 return ES_FAILED;
00893 if (me != ME_INT_VAL)
00894 assigned = false;
00895 if (me_modified(me) && (slx != x[i].max()))
00896 es = ES_NOFIX;
00897 }
00898
00899 for (int i = y.size(); i--; ) {
00900 assert(!y[i].assigned());
00901 Val sly = y[i].max() - sl;
00902 ModEvent me = y[i].gq(home,sly);
00903 if (me == ME_INT_FAILED)
00904 return ES_FAILED;
00905 if (me != ME_INT_VAL)
00906 assigned = false;
00907 if (me_modified(me) && (sly != y[i].min()))
00908 es = ES_NOFIX;
00909 }
00910 return assigned ? ES_SUBSUMED(this,sizeof(*this)) : es;
00911 }
00912
00913
00914
00915
00916
00917
00918 template <class Val, class P, class N>
00919 forceinline
00920 ReLq<Val,P,N>::ReLq
00921 (Space* home, ViewArray<P>& x, ViewArray<N>& y, Val c, BoolView b)
00922 : ReLin<Val,P,N,PC_INT_BND,BoolView>(home,x,y,c,b) {}
00923
00924 template <class Val, class P, class N>
00925 ExecStatus
00926 ReLq<Val,P,N>::post
00927 (Space* home, ViewArray<P>& x, ViewArray<N>& y, Val c, BoolView b) {
00928 ViewArray<NoView> nva;
00929 if (y.size() == 0) {
00930 (void) new (home) ReLq<Val,P,NoView>(home,x,nva,c,b);
00931 } else if (x.size() == 0) {
00932 (void) new (home) ReLq<Val,NoView,N>(home,nva,y,c,b);
00933 } else {
00934 (void) new (home) ReLq<Val,P,N>(home,x,y,c,b);
00935 }
00936 return ES_OK;
00937 }
00938
00939
00940 template <class Val, class P, class N>
00941 forceinline
00942 ReLq<Val,P,N>::ReLq(Space* home, bool share, ReLq<Val,P,N>& p)
00943 : ReLin<Val,P,N,PC_INT_BND,BoolView>(home,share,p) {}
00944
00945 template <class Val, class P, class N>
00946 Actor*
00947 ReLq<Val,P,N>::copy(Space* home, bool share) {
00948 return new (home) ReLq<Val,P,N>(home,share,*this);
00949 }
00950
00951 template <class Val, class P, class N>
00952 inline Support::Symbol
00953 ReLq<Val,P,N>::ati(void) {
00954 return Reflection::mangle<Val,P,N>("Gecode::Int::Linear::ReLq");
00955 }
00956
00957 template <class Val, class P, class N>
00958 Reflection::ActorSpec
00959 ReLq<Val,P,N>::spec(const Space* home, Reflection::VarMap& m) const {
00960 return ReLin<Val,P,N,PC_INT_BND,BoolView>::spec(home, m, ati());
00961 }
00962
00963 template <class Val, class P, class N>
00964 void
00965 ReLq<Val,P,N>::post(Space* home, Reflection::VarMap& vars,
00966 const Reflection::ActorSpec& spec) {
00967 ViewArray<P> x(home, vars, spec[0]);
00968 ViewArray<N> y(home, vars, spec[1]);
00969 Val c = spec[2]->toInt();
00970 BoolView b(home, vars, spec[3]);
00971 (void) new (home) ReLq<Val,P,N>(home, x, y, c, b);
00972 }
00973
00974 template <class Val, class P, class N>
00975 ExecStatus
00976 ReLq<Val,P,N>::propagate(Space* home, ModEventDelta med) {
00977 if (b.zero())
00978 GECODE_REWRITE(this,(Lq<Val,N,P>::post(home,y,x,-c-1)));
00979 if (b.one())
00980 GECODE_REWRITE(this,(Lq<Val,P,N>::post(home,x,y,c)));
00981
00982
00983 Val sl = 0;
00984 Val su = 0;
00985
00986 bounds_p<Val,P>(med,x,c,sl,su);
00987 bounds_n<Val,N>(med,y,c,sl,su);
00988
00989 if (-sl > c) {
00990 GECODE_ME_CHECK(b.zero_none(home));
00991 return ES_SUBSUMED(this,home);
00992 }
00993 if (-su <= c) {
00994 GECODE_ME_CHECK(b.one_none(home));
00995 return ES_SUBSUMED(this,home);
00996 }
00997
00998 return ES_FIX;
00999 }
01000
01001 }}}
01002
01003
01004