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 Linear {
00039
00040
00041
00042
00043
00044 template <class Val, class A, class B, PropCond pc>
00045 forceinline
00046 LinBin<Val,A,B,pc>::LinBin(Space* home, A y0, B y1, Val c0)
00047 : Propagator(home), x0(y0), x1(y1), c(c0) {
00048 x0.subscribe(home,this,pc);
00049 x1.subscribe(home,this,pc);
00050 }
00051
00052 template <class Val, class A, class B, PropCond pc>
00053 forceinline
00054 LinBin<Val,A,B,pc>::LinBin(Space* home, bool share, LinBin<Val,A,B,pc>& p)
00055 : Propagator(home,share,p), c(p.c) {
00056 x0.update(home,share,p.x0);
00057 x1.update(home,share,p.x1);
00058 }
00059
00060 template <class Val, class A, class B, PropCond pc>
00061 forceinline
00062 LinBin<Val,A,B,pc>::LinBin(Space* home, bool share, Propagator& p,
00063 A y0, B y1, Val c0)
00064 : Propagator(home,share,p), c(c0) {
00065 x0.update(home,share,y0);
00066 x1.update(home,share,y1);
00067 }
00068
00069 template <class Val, class A, class B, PropCond pc>
00070 PropCost
00071 LinBin<Val,A,B,pc>::cost(ModEventDelta) const {
00072 return PC_BINARY_LO;
00073 }
00074
00075 template <class Val, class A, class B, PropCond pc>
00076 Reflection::ActorSpec
00077 LinBin<Val,A,B,pc>::spec(const Space* home, Reflection::VarMap& m,
00078 const Support::Symbol& ati) const {
00079 Reflection::ActorSpec s(ati);
00080 return s << x0.spec(home, m)
00081 << x1.spec(home, m)
00082 << c;
00083 }
00084
00085
00086 template <class Val, class A, class B, PropCond pc>
00087 forceinline size_t
00088 LinBin<Val,A,B,pc>::dispose(Space* home) {
00089 assert(!home->failed());
00090 x0.cancel(home,this,pc);
00091 x1.cancel(home,this,pc);
00092 (void) Propagator::dispose(home);
00093 return sizeof(*this);
00094 }
00095
00096
00097
00098
00099
00100
00101 template <class Val, class A, class B, PropCond pc, class Ctrl>
00102 forceinline
00103 ReLinBin<Val,A,B,pc,Ctrl>::ReLinBin(Space* home, A y0, B y1, Val c0, Ctrl b0)
00104 : Propagator(home), x0(y0), x1(y1), c(c0), b(b0) {
00105 x0.subscribe(home,this,pc);
00106 x1.subscribe(home,this,pc);
00107 b.subscribe(home,this,PC_INT_VAL);
00108 }
00109
00110 template <class Val, class A, class B, PropCond pc, class Ctrl>
00111 forceinline
00112 ReLinBin<Val,A,B,pc,Ctrl>::ReLinBin(Space* home, bool share,
00113 ReLinBin<Val,A,B,pc,Ctrl>& p)
00114 : Propagator(home,share,p), c(p.c) {
00115 x0.update(home,share,p.x0);
00116 x1.update(home,share,p.x1);
00117 b.update(home,share,p.b);
00118 }
00119
00120 template <class Val, class A, class B, PropCond pc, class Ctrl>
00121 PropCost
00122 ReLinBin<Val,A,B,pc,Ctrl>::cost(ModEventDelta) const {
00123 return PC_BINARY_LO;
00124 }
00125
00126 template <class Val, class A, class B, PropCond pc, class Ctrl>
00127 forceinline size_t
00128 ReLinBin<Val,A,B,pc,Ctrl>::dispose(Space* home) {
00129 assert(!home->failed());
00130 x0.cancel(home,this,pc);
00131 x1.cancel(home,this,pc);
00132 b.cancel(home,this,PC_BOOL_VAL);
00133 (void) Propagator::dispose(home);
00134 return sizeof(*this);
00135 }
00136
00137 template <class Val, class A, class B, PropCond pc, class Ctrl>
00138 Reflection::ActorSpec
00139 ReLinBin<Val,A,B,pc,Ctrl>::spec(const Space* home, Reflection::VarMap& m,
00140 const Support::Symbol& ati) const {
00141 Reflection::ActorSpec s(ati);
00142 return s << x0.spec(home, m)
00143 << x1.spec(home, m)
00144 << c
00145 << b.spec(home, m);
00146 }
00147
00148
00149
00150
00151
00152
00153 template <class Val, class A, class B>
00154 forceinline
00155 EqBin<Val,A,B>::EqBin(Space* home, A x0, B x1, Val c)
00156 : LinBin<Val,A,B,PC_INT_BND>(home,x0,x1,c) {}
00157
00158 template <class Val, class A, class B>
00159 ExecStatus
00160 EqBin<Val,A,B>::post(Space* home, A x0, B x1, Val c) {
00161 (void) new (home) EqBin<Val,A,B>(home,x0,x1,c);
00162 return ES_OK;
00163 }
00164
00165
00166 template <class Val, class A, class B>
00167 forceinline
00168 EqBin<Val,A,B>::EqBin(Space* home, bool share, EqBin<Val,A,B>& p)
00169 : LinBin<Val,A,B,PC_INT_BND>(home,share,p) {}
00170
00171 template <class Val, class A, class B>
00172 forceinline
00173 EqBin<Val,A,B>::EqBin(Space* home, bool share, Propagator& p,
00174 A x0, B x1, Val c)
00175 : LinBin<Val,A,B,PC_INT_BND>(home,share,p,x0,x1,c) {}
00176
00177 template <class Val, class A, class B>
00178 Actor*
00179 EqBin<Val,A,B>::copy(Space* home, bool share) {
00180 return new (home) EqBin<Val,A,B>(home,share,*this);
00181 }
00182
00183 template <class Val, class A, class B>
00184 inline Support::Symbol
00185 EqBin<Val,A,B>::ati(void) {
00186 return Reflection::mangle<Val,A,B>("Gecode::Int::Linear::EqBin");
00187 }
00188
00189 template <class Val, class A, class B>
00190 Reflection::ActorSpec
00191 EqBin<Val,A,B>::spec(const Space* home, Reflection::VarMap& m) const {
00192 return LinBin<Val,A,B,PC_INT_BND>::spec(home, m, ati());
00193 }
00194
00195 template <class Val, class A, class B>
00196 void
00197 EqBin<Val,A,B>::post(Space* home, Reflection::VarMap& vars,
00198 const Reflection::ActorSpec& spec) {
00199 spec.checkArity(3);
00200 A x(home, vars, spec[0]);
00201 B y(home, vars, spec[1]);
00202 Val c = spec[2]->toInt();
00203 (void) new (home) EqBin<Val,A,B>(home, x, y, c);
00204 }
00205
00207 enum BinMod {
00208 BM_X0_MIN = 1<<0,
00209 BM_X0_MAX = 1<<1,
00210 BM_X1_MIN = 1<<2,
00211 BM_X1_MAX = 1<<3,
00212 BM_ALL = BM_X0_MIN|BM_X0_MAX|BM_X1_MIN|BM_X1_MAX
00213 };
00214
00215 #define GECODE_INT_PV(CASE,TELL,UPDATE) \
00216 if (bm & (CASE)) { \
00217 bm -= (CASE); ModEvent me = (TELL); \
00218 if (me_failed(me)) return ES_FAILED; \
00219 if (me_modified(me)) bm |= (UPDATE); \
00220 }
00221
00222 template <class Val, class A, class B>
00223 ExecStatus
00224 EqBin<Val,A,B>::propagate(Space* home, ModEventDelta) {
00225 int bm = BM_ALL;
00226 do {
00227 GECODE_INT_PV(BM_X0_MIN, x0.gq(home,c-x1.max()), BM_X1_MAX);
00228 GECODE_INT_PV(BM_X1_MIN, x1.gq(home,c-x0.max()), BM_X0_MAX);
00229 GECODE_INT_PV(BM_X0_MAX, x0.lq(home,c-x1.min()), BM_X1_MIN);
00230 GECODE_INT_PV(BM_X1_MAX, x1.lq(home,c-x0.min()), BM_X0_MIN);
00231 } while (bm);
00232 return x0.assigned() ? ES_SUBSUMED(this,sizeof(*this)) : ES_FIX;
00233 }
00234
00235 #undef GECODE_INT_PV
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 template <class Val, class A, class B, class Ctrl>
00247 forceinline
00248 ReEqBin<Val,A,B,Ctrl>::ReEqBin(Space* home, A x0, B x1, Val c, Ctrl b)
00249 : ReLinBin<Val,A,B,PC_INT_BND,Ctrl>(home,x0,x1,c,b) {}
00250
00251 template <class Val, class A, class B, class Ctrl>
00252 ExecStatus
00253 ReEqBin<Val,A,B,Ctrl>::post(Space* home, A x0, B x1, Val c, Ctrl b) {
00254 (void) new (home) ReEqBin<Val,A,B,Ctrl>(home,x0,x1,c,b);
00255 return ES_OK;
00256 }
00257
00258
00259 template <class Val, class A, class B, class Ctrl>
00260 forceinline
00261 ReEqBin<Val,A,B,Ctrl>::ReEqBin(Space* home, bool share,
00262 ReEqBin<Val,A,B,Ctrl>& p)
00263 : ReLinBin<Val,A,B,PC_INT_BND,Ctrl>(home,share,p) {}
00264
00265 template <class Val, class A, class B, class Ctrl>
00266 Actor*
00267 ReEqBin<Val,A,B,Ctrl>::copy(Space* home, bool share) {
00268 return new (home) ReEqBin<Val,A,B,Ctrl>(home,share,*this);
00269 }
00270
00271 template <class Val, class A, class B, class Ctrl>
00272 inline Support::Symbol
00273 ReEqBin<Val,A,B,Ctrl>::ati(void) {
00274 return Reflection::mangle<Val,A,B,Ctrl>("Gecode::Int::Linear::ReEqBin");
00275 }
00276
00277 template <class Val, class A, class B, class Ctrl>
00278 Reflection::ActorSpec
00279 ReEqBin<Val,A,B,Ctrl>::spec(const Space* home,
00280 Reflection::VarMap& m) const {
00281 return ReLinBin<Val,A,B,PC_INT_BND,Ctrl>::spec(home, m, ati());
00282 }
00283
00284 template <class Val, class A, class B, class Ctrl>
00285 void
00286 ReEqBin<Val,A,B,Ctrl>::post(Space* home, Reflection::VarMap& vars,
00287 const Reflection::ActorSpec& spec) {
00288 spec.checkArity(4);
00289 A x(home, vars, spec[0]);
00290 B y(home, vars, spec[1]);
00291 Val c = spec[2]->toInt();
00292 Ctrl b(home, vars, spec[3]);
00293 (void) new (home) ReEqBin<Val,A,B,Ctrl>(home, x, y, c, b);
00294 }
00295
00296 template <class Val, class A, class B, class Ctrl>
00297 ExecStatus
00298 ReEqBin<Val,A,B,Ctrl>::propagate(Space* home, ModEventDelta) {
00299 if (b.zero())
00300 GECODE_REWRITE(this,(NqBin<Val,A,B>::post(home,x0,x1,c)));
00301 if (b.one())
00302 GECODE_REWRITE(this,(EqBin<Val,A,B>::post(home,x0,x1,c)));
00303 if ((x0.min() + x1.min() > c) || (x0.max() + x1.max() < c)) {
00304 GECODE_ME_CHECK(b.zero_none(home)); return ES_SUBSUMED(this,home);
00305 }
00306 if (x0.assigned() && x1.assigned()) {
00307 assert(x0.val() + x1.val() == c);
00308 GECODE_ME_CHECK(b.one_none(home)); return ES_SUBSUMED(this,home);
00309 }
00310 return ES_FIX;
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320 template <class Val, class A, class B>
00321 forceinline
00322 NqBin<Val,A,B>::NqBin(Space* home, A x0, B x1, Val c)
00323 : LinBin<Val,A,B,PC_INT_VAL>(home,x0,x1,c) {}
00324
00325 template <class Val, class A, class B>
00326 ExecStatus
00327 NqBin<Val,A,B>::post(Space* home, A x0, B x1, Val c) {
00328 (void) new (home) NqBin<Val,A,B>(home,x0,x1,c);
00329 return ES_OK;
00330 }
00331
00332
00333 template <class Val, class A, class B>
00334 forceinline
00335 NqBin<Val,A,B>::NqBin(Space* home, bool share, NqBin<Val,A,B>& p)
00336 : LinBin<Val,A,B,PC_INT_VAL>(home,share,p) {}
00337
00338 template <class Val, class A, class B>
00339 Actor*
00340 NqBin<Val,A,B>::copy(Space* home, bool share) {
00341 return new (home) NqBin<Val,A,B>(home,share,*this);
00342 }
00343
00344 template <class Val, class A, class B>
00345 forceinline
00346 NqBin<Val,A,B>::NqBin(Space* home, bool share, Propagator& p,
00347 A x0, B x1, Val c)
00348 : LinBin<Val,A,B,PC_INT_VAL>(home,share,p,x0,x1,c) {}
00349
00350
00351
00352 template <class Val, class A, class B>
00353 PropCost
00354 NqBin<Val,A,B>::cost(ModEventDelta) const {
00355 return PC_UNARY_LO;
00356 }
00357
00358 template <class Val, class A, class B>
00359 inline Support::Symbol
00360 NqBin<Val,A,B>::ati(void) {
00361 return Reflection::mangle<Val,A,B>("Gecode::Int::Linear::NqBin");
00362 }
00363
00364 template <class Val, class A, class B>
00365 Reflection::ActorSpec
00366 NqBin<Val,A,B>::spec(const Space* home, Reflection::VarMap& m) const {
00367 return LinBin<Val,A,B,PC_INT_VAL>::spec(home, m, ati());
00368 }
00369
00370 template <class Val, class A, class B>
00371 void
00372 NqBin<Val,A,B>::post(Space* home, Reflection::VarMap& vars,
00373 const Reflection::ActorSpec& spec) {
00374 spec.checkArity(3);
00375 A x(home, vars, spec[0]);
00376 B y(home, vars, spec[1]);
00377 Val c = spec[2]->toInt();
00378 (void) new (home) NqBin<Val,A,B>(home, x, y, c);
00379 }
00380
00381 template <class Val, class A, class B>
00382 ExecStatus
00383 NqBin<Val,A,B>::propagate(Space* home, ModEventDelta) {
00384 if (x0.assigned()) {
00385 GECODE_ME_CHECK(x1.nq(home,c-x0.val()));
00386 } else {
00387 assert(x1.assigned());
00388 GECODE_ME_CHECK(x0.nq(home,c-x1.val()));
00389 }
00390 return ES_SUBSUMED(this,home);
00391 }
00392
00393
00394
00395
00396
00397
00398
00399 template <class Val, class A, class B>
00400 forceinline
00401 LqBin<Val,A,B>::LqBin(Space* home, A x0, B x1, Val c)
00402 : LinBin<Val,A,B,PC_INT_BND>(home,x0,x1,c) {}
00403
00404 template <class Val, class A, class B>
00405 ExecStatus
00406 LqBin<Val,A,B>::post(Space* home, A x0, B x1, Val c) {
00407 (void) new (home) LqBin<Val,A,B>(home,x0,x1,c);
00408 return ES_OK;
00409 }
00410
00411
00412 template <class Val, class A, class B>
00413 forceinline
00414 LqBin<Val,A,B>::LqBin(Space* home, bool share, LqBin<Val,A,B>& p)
00415 : LinBin<Val,A,B,PC_INT_BND>(home,share,p) {}
00416
00417 template <class Val, class A, class B>
00418 Actor*
00419 LqBin<Val,A,B>::copy(Space* home, bool share) {
00420 return new (home) LqBin<Val,A,B>(home,share,*this);
00421 }
00422
00423 template <class Val, class A, class B>
00424 forceinline
00425 LqBin<Val,A,B>::LqBin(Space* home, bool share, Propagator& p,
00426 A x0, B x1, Val c)
00427 : LinBin<Val,A,B,PC_INT_BND>(home,share,p,x0,x1,c) {}
00428
00429 template <class Val, class A, class B>
00430 inline Support::Symbol
00431 LqBin<Val,A,B>::ati(void) {
00432 return Reflection::mangle<Val,A,B>("Gecode::Int::Linear::LqBin");
00433 }
00434
00435 template <class Val, class A, class B>
00436 Reflection::ActorSpec
00437 LqBin<Val,A,B>::spec(const Space* home, Reflection::VarMap& m) const {
00438 return LinBin<Val,A,B,PC_INT_BND>::spec(home, m, ati());
00439 }
00440
00441 template <class Val, class A, class B>
00442 void
00443 LqBin<Val,A,B>::post(Space* home, Reflection::VarMap& vars,
00444 const Reflection::ActorSpec& spec) {
00445 spec.checkArity(3);
00446 A x(home, vars, spec[0]);
00447 B y(home, vars, spec[1]);
00448 Val c = spec[2]->toInt();
00449 (void) new (home) LqBin<Val,A,B>(home, x, y, c);
00450 }
00451
00452 template <class Val, class A, class B>
00453 ExecStatus
00454 LqBin<Val,A,B>::propagate(Space* home, ModEventDelta) {
00455 GECODE_ME_CHECK(x0.lq(home,c-x1.min()));
00456 GECODE_ME_CHECK(x1.lq(home,c-x0.min()));
00457 return (x0.max()+x1.max() <= c) ? ES_SUBSUMED(this,home) : ES_FIX;
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 template <class Val, class A, class B>
00469 forceinline
00470 GqBin<Val,A,B>::GqBin(Space* home, A x0, B x1, Val c)
00471 : LinBin<Val,A,B,PC_INT_BND>(home,x0,x1,c) {}
00472
00473 template <class Val, class A, class B>
00474 ExecStatus
00475 GqBin<Val,A,B>::post(Space* home, A x0, B x1, Val c) {
00476 (void) new (home) GqBin<Val,A,B>(home,x0,x1,c);
00477 return ES_OK;
00478 }
00479
00480
00481 template <class Val, class A, class B>
00482 forceinline
00483 GqBin<Val,A,B>::GqBin(Space* home, bool share, GqBin<Val,A,B>& p)
00484 : LinBin<Val,A,B,PC_INT_BND>(home,share,p) {}
00485
00486 template <class Val, class A, class B>
00487 Actor*
00488 GqBin<Val,A,B>::copy(Space* home, bool share) {
00489 return new (home) GqBin<Val,A,B>(home,share,*this);
00490 }
00491
00492 template <class Val, class A, class B>
00493 forceinline
00494 GqBin<Val,A,B>::GqBin(Space* home, bool share, Propagator& p,
00495 A x0, B x1, Val c)
00496 : LinBin<Val,A,B,PC_INT_BND>(home,share,p,x0,x1,c) {}
00497
00498 template <class Val, class A, class B>
00499 inline Support::Symbol
00500 GqBin<Val,A,B>::ati(void) {
00501 return Reflection::mangle<Val,A,B>("Gecode::Int::Linear::GqBin");
00502 }
00503
00504 template <class Val, class A, class B>
00505 Reflection::ActorSpec
00506 GqBin<Val,A,B>::spec(const Space* home, Reflection::VarMap& m) const {
00507 return LinBin<Val,A,B,PC_INT_BND>::spec(home, m, ati());
00508 }
00509
00510 template <class Val, class A, class B>
00511 void
00512 GqBin<Val,A,B>::post(Space* home, Reflection::VarMap& vars,
00513 const Reflection::ActorSpec& spec) {
00514 spec.checkArity(3);
00515 A x(home, vars, spec[0]);
00516 B y(home, vars, spec[1]);
00517 Val c = spec[2]->toInt();
00518 (void) new (home) GqBin<Val,A,B>(home, x, y, c);
00519 }
00520
00521 template <class Val, class A, class B>
00522 ExecStatus
00523 GqBin<Val,A,B>::propagate(Space* home, ModEventDelta) {
00524 GECODE_ME_CHECK(x0.gq(home,c-x1.max()));
00525 GECODE_ME_CHECK(x1.gq(home,c-x0.max()));
00526 return (x0.min()+x1.min() >= c) ? ES_SUBSUMED(this,home) : ES_FIX;
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 template <class Val, class A, class B>
00538 forceinline
00539 ReLqBin<Val,A,B>::ReLqBin(Space* home, A x0, B x1, Val c, BoolView b)
00540 : ReLinBin<Val,A,B,PC_INT_BND,BoolView>(home,x0,x1,c,b) {}
00541
00542 template <class Val, class A, class B>
00543 ExecStatus
00544 ReLqBin<Val,A,B>::post(Space* home, A x0, B x1, Val c, BoolView b) {
00545 (void) new (home) ReLqBin<Val,A,B>(home,x0,x1,c,b);
00546 return ES_OK;
00547 }
00548
00549
00550 template <class Val, class A, class B>
00551 forceinline
00552 ReLqBin<Val,A,B>::ReLqBin(Space* home, bool share, ReLqBin<Val,A,B>& p)
00553 : ReLinBin<Val,A,B,PC_INT_BND,BoolView>(home,share,p) {}
00554
00555 template <class Val, class A, class B>
00556 Actor*
00557 ReLqBin<Val,A,B>::copy(Space* home, bool share) {
00558 return new (home) ReLqBin<Val,A,B>(home,share,*this);
00559 }
00560
00561 template <class Val, class A, class B>
00562 Support::Symbol
00563 ReLqBin<Val,A,B>::ati(void) {
00564 return Reflection::mangle<Val,A,B>("Gecode::Int::Linear::ReLqBin");
00565 }
00566
00567 template <class Val, class A, class B>
00568 Reflection::ActorSpec
00569 ReLqBin<Val,A,B>::spec(const Space* home, Reflection::VarMap& m) const {
00570 return ReLinBin<Val,A,B,PC_INT_BND,BoolView>::spec(home, m, ati());
00571 }
00572
00573 template <class Val, class A, class B>
00574 void
00575 ReLqBin<Val,A,B>::post(Space* home, Reflection::VarMap& vars,
00576 const Reflection::ActorSpec& spec) {
00577 spec.checkArity(4);
00578 A x(home, vars, spec[0]);
00579 B y(home, vars, spec[1]);
00580 Val c = spec[2]->toInt();
00581 BoolView b(home, vars, spec[3]);
00582 (void) new (home) ReLqBin<Val,A,B>(home, x, y, c, b);
00583 }
00584
00585
00586 template <class Val, class A, class B>
00587 ExecStatus
00588 ReLqBin<Val,A,B>::propagate(Space* home, ModEventDelta) {
00589 if (b.one())
00590 GECODE_REWRITE(this,(LqBin<Val,A,B>::post(home,x0,x1,c)));
00591 if (b.zero())
00592 GECODE_REWRITE(this,(GqBin<Val,A,B>::post(home,x0,x1,c+1)));
00593 if (x0.max() + x1.max() <= c) {
00594 GECODE_ME_CHECK(b.one_none(home)); return ES_SUBSUMED(this,home);
00595 }
00596 if (x0.min() + x1.min() > c) {
00597 GECODE_ME_CHECK(b.zero_none(home)); return ES_SUBSUMED(this,home);
00598 }
00599 return ES_FIX;
00600 }
00601
00602 }}}
00603
00604
00605