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