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
00039
00040 #include <algorithm>
00041
00042 namespace Gecode { namespace Int { namespace Linear {
00043
00044
00045
00046
00047
00048 template <class VX>
00049 forceinline
00050 MemoryLinBoolInt<VX>::MemoryLinBoolInt(Space& home, ViewArray<VX>& x0,
00051 int n_s0, int c0)
00052 : Propagator(home), x(x0), n_s(n_s0), c(c0) {
00053 for (int i=n_s; i--; )
00054 x[i].subscribe(home,*this,PC_INT_VAL);
00055 }
00056
00057 template <class VX>
00058 forceinline size_t
00059 MemoryLinBoolInt<VX>::dispose(Space& home) {
00060 assert(!home.failed());
00061 for (int i=n_s; i--; )
00062 x[i].cancel(home,*this,PC_INT_VAL);
00063 (void) Propagator::dispose(home);
00064 return sizeof(*this);
00065 }
00066
00067 template <class VX>
00068 forceinline
00069 MemoryLinBoolInt<VX>::MemoryLinBoolInt(Space& home, bool share,
00070 MemoryLinBoolInt<VX>& p)
00071 : Propagator(home,share,p), x(home,p.x.size()), n_s(p.n_s) {
00072
00073 for (int i=n_s; i--; )
00074 x[i].update(home,share,p.x[i]);
00075
00076
00077 int n_x = p.x.size();
00078 int p_c = p.c;
00079 for (int i=n_x; i-- > n_s; )
00080 if (p.x[i].zero()) {
00081 n_x--;
00082 p.x[i]=p.x[n_x]; x[i]=x[n_x];
00083 } else if (p.x[i].one()) {
00084 n_x--; p_c--;
00085 p.x[i]=p.x[n_x]; x[i]=x[n_x];
00086 } else {
00087 x[i].update(home,share,p.x[i]);
00088 }
00089 p.c = p_c; c = p_c;
00090 p.x.size(n_x); x.size(n_x);
00091 }
00092
00093 template <class VX>
00094 PropCost
00095 MemoryLinBoolInt<VX>::cost(const Space&, const ModEventDelta&) const {
00096 return PropCost::linear(PropCost::LO, x.size());
00097 }
00098
00099
00100
00101
00102
00103 template <class VX>
00104 forceinline
00105 SpeedLinBoolInt<VX>::SpeedLinBoolInt(Space& home, ViewArray<VX>& x0,
00106 int n_s0, int c0)
00107 : Propagator(home), x(x0), n_s(n_s0), c(c0), co(home) {
00108 int n_x = x.size() - n_s;
00109 for (int i=n_x; i<x.size(); i++)
00110 (void) new (home) ViewAdvisor<VX>(home,*this,co,x[i]);
00111 x.size(n_x);
00112 }
00113
00114 template <class VX>
00115 forceinline size_t
00116 SpeedLinBoolInt<VX>::dispose(Space& home) {
00117 co.dispose(home);
00118 (void) Propagator::dispose(home);
00119 return sizeof(*this);
00120 }
00121
00122 template <class VX>
00123 forceinline
00124 SpeedLinBoolInt<VX>::SpeedLinBoolInt(Space& home, bool share,
00125 SpeedLinBoolInt<VX>& p)
00126 : Propagator(home,share,p), x(home,p.x.size()), n_s(p.n_s) {
00127
00128 int n_x = p.x.size();
00129 int p_c = p.c;
00130 for (int i=n_x; i--; )
00131 if (p.x[i].zero()) {
00132 n_x--;
00133 p.x[i]=p.x[n_x]; x[i]=x[n_x];
00134 } else if (p.x[i].one()) {
00135 n_x--; p_c--;
00136 p.x[i]=p.x[n_x]; x[i]=x[n_x];
00137 } else {
00138 x[i].update(home,share,p.x[i]);
00139 }
00140 p.c = p_c; c = p_c;
00141 p.x.size(n_x); x.size(n_x);
00142 co.update(home,share,p.co);
00143 }
00144
00145 template <class VX>
00146 PropCost
00147 SpeedLinBoolInt<VX>::cost(const Space&, const ModEventDelta&) const {
00148 return PropCost::unary(PropCost::HI);
00149 }
00150
00151
00152
00153
00154
00155
00156 template <class VX>
00157 forceinline
00158 GqBoolInt<VX>::Memory::Memory(Space& home, ViewArray<VX>& x, int c)
00159 : MemoryLinBoolInt<VX>(home,x,c+1,c) {}
00160
00161 template <class VX>
00162 forceinline
00163 GqBoolInt<VX>::Memory::Memory(Space& home, bool share,
00164 typename GqBoolInt<VX>::Memory& p)
00165 : MemoryLinBoolInt<VX>(home,share,p) {}
00166
00167 template <class VX>
00168 Actor*
00169 GqBoolInt<VX>::Memory::copy(Space& home, bool share) {
00170 return new (home) Memory(home,share,*this);
00171 }
00172
00173 template <class VX>
00174 ExecStatus
00175 GqBoolInt<VX>::Memory::propagate(Space& home, const ModEventDelta&) {
00176
00177 int n_x = x.size();
00178 for (int i=n_s; i--; )
00179 if (x[i].zero()) {
00180 x[i]=x[--n_s]; x[n_s]=x[--n_x];
00181 } else if (x[i].one()) {
00182 x[i]=x[--n_s]; x[n_s]=x[--n_x]; c--;
00183 }
00184 x.size(n_x);
00185 if (n_x < c)
00186 return ES_FAILED;
00187 if (c <= 0)
00188 return ES_SUBSUMED(*this,home);
00189
00190 while ((n_s < n_x) && (n_s <= c))
00191 if (x[n_s].zero()) {
00192 x[n_s]=x[--n_x];
00193 } else if (x[n_s].one()) {
00194 x[n_s]=x[--n_x]; c--;
00195 } else {
00196 x[n_s++].subscribe(home,*this,PC_INT_VAL,false);
00197 }
00198 x.size(n_x);
00199 if (n_x < c)
00200 return ES_FAILED;
00201 if (c <= 0)
00202 return ES_SUBSUMED(*this,home);
00203 if (c == n_x) {
00204
00205 for (int i=n_s; i--; )
00206 GECODE_ME_CHECK(x[i].one_none(home));
00207
00208 for (int i=n_s+1; i<n_x; i++)
00209 GECODE_ME_CHECK(x[i].one(home));
00210
00211 n_s = 0;
00212 return ES_SUBSUMED(*this,sizeof(*this));
00213 }
00214 return ES_FIX;
00215 }
00216
00217
00218 template <class VX>
00219 forceinline
00220 GqBoolInt<VX>::Speed::Speed(Space& home, ViewArray<VX>& x, int c)
00221 : SpeedLinBoolInt<VX>(home,x,c+1,c) {}
00222
00223 template <class VX>
00224 forceinline
00225 GqBoolInt<VX>::Speed::Speed(Space& home, bool share,
00226 typename GqBoolInt<VX>::Speed& p)
00227 : SpeedLinBoolInt<VX>(home,share,p) {}
00228
00229 template <class VX>
00230 Actor*
00231 GqBoolInt<VX>::Speed::copy(Space& home, bool share) {
00232 return new (home) Speed(home,share,*this);
00233 }
00234
00235 template <class VX>
00236 ExecStatus
00237 GqBoolInt<VX>::Speed::advise(Space& home, Advisor& _a, const Delta&) {
00238 ViewAdvisor<VX>& a = static_cast<ViewAdvisor<VX>&>(_a);
00239 if (n_s == 0)
00240 return ES_SUBSUMED_FIX(a,home,co);
00241 assert(!a.view().none());
00242 if (a.view().one()) {
00243 c--; goto subsume;
00244 }
00245 if (c+1 < n_s)
00246 goto subsume;
00247
00248 for (int i = x.size(); i--; )
00249 if (x[i].none()) {
00250 a.view(home,x[i]);
00251 x.size(i);
00252 return ES_FIX;
00253 } else if (x[i].one()) {
00254 c--;
00255 if (c+1 < n_s) {
00256 x.size(i);
00257 goto subsume;
00258 }
00259 }
00260
00261 x.size(0);
00262 subsume:
00263
00264 n_s--;
00265 int n = n_s+x.size();
00266 if (n < c)
00267 return ES_FAILED;
00268 if ((c <= 0) || (c == n))
00269 return ES_SUBSUMED_NOFIX(a,home,co);
00270 else
00271 return ES_SUBSUMED_FIX(a,home,co);
00272 }
00273
00274 template <class VX>
00275 ExecStatus
00276 GqBoolInt<VX>::Speed::propagate(Space& home, const ModEventDelta&) {
00277 if (c > 0) {
00278 assert((n_s == c) && (x.size() == 0));
00279
00280 n_s = 0;
00281
00282 for (Advisors<ViewAdvisor<VX> > as(co); as(); ++as)
00283 GECODE_ME_CHECK(as.advisor().view().one_none(home));
00284 }
00285 return ES_SUBSUMED(*this,home);
00286 }
00287
00288 template <class VX>
00289 ExecStatus
00290 GqBoolInt<VX>::post(Space& home, ViewArray<VX>& x, int c) {
00291
00292 int n_x = x.size();
00293 for (int i=n_x; i--; )
00294 if (x[i].zero()) {
00295 x[i] = x[--n_x];
00296 } else if (x[i].one()) {
00297 x[i] = x[--n_x]; c--;
00298 }
00299
00300 if (n_x < c)
00301 return ES_FAILED;
00302
00303 if (c <= 0)
00304 return ES_OK;
00305
00306 if (c == n_x) {
00307 for (int i=n_x; i--; )
00308 GECODE_ME_CHECK(x[i].one_none(home));
00309 return ES_OK;
00310 }
00311
00312 assert(n_x > c);
00313 x.size(n_x);
00314 if (x.size() > threshold)
00315 (void) new (home) Speed(home,x,c);
00316 else
00317 (void) new (home) Memory(home,x,c);
00318 return ES_OK;
00319 }
00320
00321
00322
00323
00324
00325
00326
00327 template <class VX>
00328 forceinline
00329 EqBoolInt<VX>::Memory::Memory(Space& home, ViewArray<VX>& x,
00330 int c)
00331 : MemoryLinBoolInt<VX>(home,x,std::max(c,x.size()-c)+1,c) {}
00332
00333 template <class VX>
00334 forceinline
00335 EqBoolInt<VX>::Memory::Memory(Space& home, bool share,
00336 typename EqBoolInt<VX>::Memory& p)
00337 : MemoryLinBoolInt<VX>(home,share,p) {}
00338
00339 template <class VX>
00340 Actor*
00341 EqBoolInt<VX>::Memory::copy(Space& home, bool share) {
00342 return new (home) Memory(home,share,*this);
00343 }
00344
00345 template <class VX>
00346 ExecStatus
00347 EqBoolInt<VX>::Memory::propagate(Space& home, const ModEventDelta&) {
00348
00349 int n_x = x.size();
00350 for (int i=n_s; i--; )
00351 if (x[i].zero()) {
00352 x[i]=x[--n_s]; x[n_s]=x[--n_x];
00353 } else if (x[i].one()) {
00354 x[i]=x[--n_s]; x[n_s]=x[--n_x]; c--;
00355 }
00356 x.size(n_x);
00357 if ((c < 0) || (c > n_x))
00358 return ES_FAILED;
00359
00360 while ((n_s < n_x) && ((n_s <= c) || (n_s <= n_x-c)))
00361 if (x[n_s].zero()) {
00362 x[n_s]=x[--n_x];
00363 } else if (x[n_s].one()) {
00364 x[n_s]=x[--n_x]; c--;
00365 } else {
00366 x[n_s++].subscribe(home,*this,PC_INT_VAL,false);
00367 }
00368 x.size(n_x);
00369 if ((c < 0) || (c > n_x))
00370 return ES_FAILED;
00371 if (c == 0) {
00372
00373 for (int i=n_s; i--; )
00374 GECODE_ME_CHECK(x[i].zero_none(home));
00375
00376 for (int i=n_s+1; i<n_x; i++)
00377 GECODE_ME_CHECK(x[i].zero(home));
00378
00379 n_s = 0;
00380 return ES_SUBSUMED(*this,sizeof(*this));
00381 }
00382 if (c == n_x) {
00383
00384 for (int i=n_s; i--; )
00385 GECODE_ME_CHECK(x[i].one_none(home));
00386
00387 for (int i=n_s+1; i<n_x; i++)
00388 GECODE_ME_CHECK(x[i].one(home));
00389
00390 n_s = 0;
00391 return ES_SUBSUMED(*this,sizeof(*this));
00392 }
00393 return ES_FIX;
00394 }
00395
00396
00397
00398 template <class VX>
00399 forceinline
00400 EqBoolInt<VX>::Speed::Speed(Space& home, ViewArray<VX>& x, int c)
00401 : SpeedLinBoolInt<VX>(home,x,std::max(c,x.size()-c)+1,c) {}
00402
00403 template <class VX>
00404 forceinline
00405 EqBoolInt<VX>::Speed::Speed(Space& home, bool share,
00406 typename EqBoolInt<VX>::Speed& p)
00407 : SpeedLinBoolInt<VX>(home,share,p) {}
00408
00409 template <class VX>
00410 Actor*
00411 EqBoolInt<VX>::Speed::copy(Space& home, bool share) {
00412 return new (home) Speed(home,share,*this);
00413 }
00414
00415 template <class VX>
00416 ExecStatus
00417 EqBoolInt<VX>::Speed::advise(Space& home, Advisor& _a, const Delta&) {
00418 ViewAdvisor<VX>& a = static_cast<ViewAdvisor<VX>&>(_a);
00419 if (n_s == 0)
00420 return ES_SUBSUMED_FIX(a,home,co);
00421 assert(!a.view().none());
00422 if (a.view().one())
00423 c--;
00424
00425 if ((c+1 < n_s) && (x.size() < c))
00426 goto subsume;
00427
00428 for (int i = x.size(); i--; )
00429 if (x[i].none()) {
00430 a.view(home,x[i]);
00431 x.size(i);
00432 return ES_FIX;
00433 } else if (x[i].one()) {
00434 c--;
00435 }
00436
00437 x.size(0);
00438 subsume:
00439
00440 n_s--;
00441 int n = n_s+x.size();
00442 if ((c<0) || (c > n))
00443 return ES_FAILED;
00444 if ((c == 0) || (c == n))
00445 return ES_SUBSUMED_NOFIX(a,home,co);
00446 else
00447 return ES_SUBSUMED_FIX(a,home,co);
00448 }
00449
00450 template <class VX>
00451 ExecStatus
00452 EqBoolInt<VX>::Speed::propagate(Space& home, const ModEventDelta&) {
00453
00454 assert(x.size() == 0);
00455 n_s = 0;
00456 if (c == 0) {
00457
00458 for (Advisors<ViewAdvisor<VX> > as(co); as(); ++as)
00459 GECODE_ME_CHECK(as.advisor().view().zero_none(home));
00460 } else {
00461
00462 for (Advisors<ViewAdvisor<VX> > as(co); as(); ++as)
00463 GECODE_ME_CHECK(as.advisor().view().one_none(home));
00464 }
00465 return ES_SUBSUMED(*this,home);
00466 }
00467
00468 template <class VX>
00469 ExecStatus
00470 EqBoolInt<VX>::post(Space& home, ViewArray<VX>& x, int c) {
00471
00472 int n_x = x.size();
00473 for (int i=n_x; i--; )
00474 if (x[i].zero()) {
00475 x[i] = x[--n_x];
00476 } else if (x[i].one()) {
00477 x[i] = x[--n_x]; c--;
00478 }
00479
00480 if ((c < 0) || (c > n_x))
00481 return ES_FAILED;
00482
00483 if (c == 0) {
00484 for (int i=n_x; i--; )
00485 GECODE_ME_CHECK(x[i].zero_none(home));
00486 return ES_OK;
00487 }
00488
00489 if (c == n_x) {
00490 for (int i=n_x; i--; )
00491 GECODE_ME_CHECK(x[i].one_none(home));
00492 return ES_OK;
00493 }
00494 x.size(n_x);
00495 if (x.size() > threshold)
00496 (void) new (home) Speed(home,x,c);
00497 else
00498 (void) new (home) Memory(home,x,c);
00499 return ES_OK;
00500 }
00501
00502 template <class VX>
00503 ExecStatus
00504 EqBoolInt<VX>::Memory::post(Space& home, ViewArray<VX>& x, int c) {
00505 return EqBoolInt<VX>::post(home,x,c);
00506 }
00507
00508
00509
00510
00511
00512
00513
00514 template<class VX>
00515 forceinline
00516 NqBoolInt<VX>::NqBoolInt(Space& home, ViewArray<VX>& b, int c0)
00517 : BinaryPropagator<VX,PC_INT_VAL>(home,
00518 b[b.size()-2],
00519 b[b.size()-1]), x(b), c(c0) {
00520 assert(x.size() >= 2);
00521 x.size(x.size()-2);
00522 }
00523
00524 template<class VX>
00525 forceinline
00526 NqBoolInt<VX>::NqBoolInt(Space& home, bool share, NqBoolInt<VX>& p)
00527 : BinaryPropagator<VX,PC_INT_VAL>(home,share,p), x(home,p.x.size()) {
00528
00529 int n = p.x.size();
00530 int p_c = p.c;
00531 for (int i=n; i--; )
00532 if (p.x[i].zero()) {
00533 n--; p.x[i]=p.x[n]; x[i]=x[n];
00534 } else if (p.x[i].one()) {
00535 n--; p_c--; p.x[i]=p.x[n]; x[i]=x[n];
00536 } else {
00537 x[i].update(home,share,p.x[i]);
00538 }
00539 c = p_c; p.c = p_c;
00540 x.size(n); p.x.size(n);
00541 }
00542
00543 template<class VX>
00544 forceinline ExecStatus
00545 NqBoolInt<VX>::post(Space& home, ViewArray<VX>& x, int c) {
00546 int n = x.size();
00547 for (int i=n; i--; )
00548 if (x[i].one()) {
00549 x[i]=x[--n]; c--;
00550 } else if (x[i].zero()) {
00551 x[i]=x[--n];
00552 }
00553 x.size(n);
00554 if ((n < c) || (c < 0))
00555 return ES_OK;
00556 if (n == 0)
00557 return (c == 0) ? ES_FAILED : ES_OK;
00558 if (n == 1) {
00559 if (c == 1) {
00560 GECODE_ME_CHECK(x[0].zero_none(home));
00561 } else {
00562 GECODE_ME_CHECK(x[0].one_none(home));
00563 }
00564 return ES_OK;
00565 }
00566 (void) new (home) NqBoolInt(home,x,c);
00567 return ES_OK;
00568 }
00569
00570 template<class VX>
00571 Actor*
00572 NqBoolInt<VX>::copy(Space& home, bool share) {
00573 return new (home) NqBoolInt<VX>(home,share,*this);
00574 }
00575
00576 template<class VX>
00577 PropCost
00578 NqBoolInt<VX>::cost(const Space&, const ModEventDelta&) const {
00579 return PropCost::linear(PropCost::LO, x.size());
00580 }
00581
00582 template<class VX>
00583 forceinline bool
00584 NqBoolInt<VX>::resubscribe(Space& home, VX& y) {
00585 if (y.one())
00586 c--;
00587 int n = x.size();
00588 for (int i=n; i--; )
00589 if (x[i].one()) {
00590 c--; x[i]=x[--n];
00591 } else if (x[i].zero()) {
00592 x[i] = x[--n];
00593 } else {
00594
00595 assert(!x[i].zero() && !x[i].one());
00596
00597 y=x[i]; x[i]=x[--n];
00598 x.size(n);
00599 y.subscribe(home,*this,PC_INT_VAL,false);
00600 return true;
00601 }
00602
00603 x.size(0);
00604 return false;
00605 }
00606
00607 template<class VX>
00608 ExecStatus
00609 NqBoolInt<VX>::propagate(Space& home, const ModEventDelta&) {
00610 bool s0 = true;
00611 if (x0.zero() || x0.one())
00612 s0 = resubscribe(home,x0);
00613 bool s1 = true;
00614 if (x1.zero() || x1.one())
00615 s1 = resubscribe(home,x1);
00616 int n = x.size() + s0 + s1;
00617 if ((n < c) || (c < 0))
00618 return ES_SUBSUMED(*this,home);
00619 if (n == 0)
00620 return (c == 0) ? ES_FAILED : ES_SUBSUMED(*this,sizeof(*this));
00621 if (n == 1) {
00622 if (s0) {
00623 if (c == 1) {
00624 GECODE_ME_CHECK(x0.zero_none(home));
00625 } else {
00626 GECODE_ME_CHECK(x0.one_none(home));
00627 }
00628 } else {
00629 assert(s1);
00630 if (c == 1) {
00631 GECODE_ME_CHECK(x1.zero_none(home));
00632 } else {
00633 GECODE_ME_CHECK(x1.one_none(home));
00634 }
00635 }
00636 return ES_SUBSUMED(*this,sizeof(*this));
00637 }
00638 return ES_FIX;
00639 }
00640
00641
00642
00643
00644
00645
00646
00647 template <class VX, class VB>
00648 forceinline
00649 MemoryReLinBoolInt<VX,VB>::MemoryReLinBoolInt(Space& home, ViewArray<VX>& x0,
00650 int n_s0, int c0, VB b0)
00651 : MemoryLinBoolInt<VX>(home,x0,n_s0,c0), b(b0) {
00652 b.subscribe(home,*this,PC_BOOL_VAL);
00653 }
00654
00655 template <class VX, class VB>
00656 forceinline size_t
00657 MemoryReLinBoolInt<VX,VB>::dispose(Space& home) {
00658 assert(!home.failed());
00659 b.cancel(home,*this,PC_BOOL_VAL);
00660 (void) MemoryLinBoolInt<VX>::dispose(home);
00661 return sizeof(*this);
00662 }
00663
00664 template <class VX, class VB>
00665 forceinline
00666 MemoryReLinBoolInt<VX,VB>::MemoryReLinBoolInt(Space& home, bool share,
00667 MemoryReLinBoolInt<VX,VB>& p)
00668 : MemoryLinBoolInt<VX>(home,share,p) {
00669 b.update(home,share,p.b);
00670 }
00671
00672
00673
00674
00675
00676 template <class VX, class VB>
00677 forceinline
00678 SpeedReLinBoolInt<VX,VB>::SpeedReLinBoolInt(Space& home, ViewArray<VX>& x0,
00679 int n_s0, int c0, VB b0)
00680 : SpeedLinBoolInt<VX>(home,x0,n_s0,c0), b(b0) {
00681 b.subscribe(home,*this,PC_BOOL_VAL);
00682 }
00683
00684 template <class VX, class VB>
00685 forceinline size_t
00686 SpeedReLinBoolInt<VX,VB>::dispose(Space& home) {
00687 assert(!home.failed());
00688 b.cancel(home,*this,PC_BOOL_VAL);
00689 (void) SpeedLinBoolInt<VX>::dispose(home);
00690 return sizeof(*this);
00691 }
00692
00693 template <class VX, class VB>
00694 forceinline
00695 SpeedReLinBoolInt<VX,VB>::SpeedReLinBoolInt(Space& home, bool share,
00696 SpeedReLinBoolInt<VX,VB>& p)
00697 : SpeedLinBoolInt<VX>(home,share,p) {
00698 b.update(home,share,p.b);
00699 }
00700
00701
00702
00703
00704
00705
00706
00707 template <class VX, class VB>
00708 forceinline
00709 ReGqBoolInt<VX,VB>::Memory::Memory(Space& home, ViewArray<VX>& x, int c, VB b)
00710
00711 : MemoryReLinBoolInt<VX,VB>
00712 (home,x,std::min(x.size(),std::max(c,x.size()-c)+1),c,b) {}
00713 template <class VX, class VB>
00714 forceinline
00715 ReEqBoolInt<VX,VB>::Memory::Memory(Space& home, ViewArray<VX>& x, int c, VB b)
00716
00717 : MemoryReLinBoolInt<VX,VB>
00718 (home,x,std::min(x.size(),std::max(c,x.size()-c)+1),c,b) {}
00719
00720 template <class VX, class VB>
00721 forceinline
00722 ReGqBoolInt<VX,VB>::Memory::Memory(Space& home, bool share,
00723 typename ReGqBoolInt<VX,VB>::Memory& p)
00724 : MemoryReLinBoolInt<VX,VB>(home,share,p) {}
00725 template <class VX, class VB>
00726 forceinline
00727 ReEqBoolInt<VX,VB>::Memory::Memory(Space& home, bool share,
00728 typename ReEqBoolInt<VX,VB>::Memory& p)
00729 : MemoryReLinBoolInt<VX,VB>(home,share,p) {}
00730
00731 template <class VX, class VB>
00732 Actor*
00733 ReGqBoolInt<VX,VB>::Memory::copy(Space& home, bool share) {
00734 return new (home) Memory(home,share,*this);
00735 }
00736 template <class VX, class VB>
00737 Actor*
00738 ReEqBoolInt<VX,VB>::Memory::copy(Space& home, bool share) {
00739 return new (home) Memory(home,share,*this);
00740 }
00741
00742 template <class VX, class VB>
00743 inline ExecStatus
00744 ReGqBoolInt<VX,VB>::Memory::rewrite_inverse(Space& home,
00745 ViewArray<BoolView>& x, int c) {
00746 ViewArray<NegBoolView> y(home,x.size());
00747 for (int i=x.size(); i--; )
00748 y[i]=x[i];
00749 GECODE_REWRITE(*this,(GqBoolInt<NegBoolView>::post(home,y,x.size()-c+1)));
00750 }
00751
00752 template <class VX, class VB>
00753 inline ExecStatus
00754 ReGqBoolInt<VX,VB>::Memory::rewrite_inverse(Space& home,
00755 ViewArray<NegBoolView>& x, int c) {
00756 ViewArray<BoolView> y(home,x.size());
00757 for (int i=x.size(); i--; )
00758 y[i]=x[i].base();
00759 GECODE_REWRITE(*this,(GqBoolInt<BoolView>::post(home,y,x.size()-c+1)));
00760 }
00761
00762
00763 template <class VX, class VB>
00764 ExecStatus
00765 ReGqBoolInt<VX,VB>::Memory::propagate(Space& home, const ModEventDelta&) {
00766
00767 int n_x = x.size();
00768 for (int i=n_s; i--; )
00769 if (x[i].zero()) {
00770 x[i]=x[--n_s]; x[n_s]=x[--n_x];
00771 } else if (x[i].one()) {
00772 x[i]=x[--n_s]; x[n_s]=x[--n_x]; c--;
00773 }
00774 x.size(n_x);
00775
00776
00777 if (b.one())
00778 GECODE_REWRITE(*this,(GqBoolInt<VX>::post(home,x,c)));
00779 if (b.zero())
00780 return rewrite_inverse(home, x, c);
00781
00782 if (n_x < c) {
00783 GECODE_ME_CHECK(b.zero_none(home));
00784 return ES_SUBSUMED(*this,home);
00785 }
00786 if (c <= 0) {
00787 GECODE_ME_CHECK(b.one_none(home));
00788 return ES_SUBSUMED(*this,home);
00789 }
00790
00791 int n_s0 = c;
00792
00793 n_s0 = std::min(x.size(),std::max(c,x.size()-c)+1);
00794
00795 while ((n_s < n_x) && (n_s <= n_s0))
00796 if (x[n_s].zero()) {
00797 x[n_s]=x[--n_x];
00798 } else if (x[n_s].one()) {
00799 x[n_s]=x[--n_x]; c--;
00800 } else {
00801 x[n_s++].subscribe(home,*this,PC_INT_VAL,false);
00802 }
00803 x.size(n_x);
00804 if (n_x < c) {
00805 GECODE_ME_CHECK(b.zero_none(home));
00806 return ES_SUBSUMED(*this,home);
00807 }
00808 if (c <= 0) {
00809 GECODE_ME_CHECK(b.one_none(home));
00810 return ES_SUBSUMED(*this,home);
00811 }
00812 return ES_FIX;
00813 }
00814
00815 template <class VX, class VB>
00816 ExecStatus
00817 ReEqBoolInt<VX,VB>::Memory::propagate(Space& home, const ModEventDelta&) {
00818
00819 int n_x = x.size();
00820 for (int i=n_s; i--; )
00821 if (x[i].zero()) {
00822 x[i]=x[--n_s]; x[n_s]=x[--n_x];
00823 } else if (x[i].one()) {
00824 x[i]=x[--n_s]; x[n_s]=x[--n_x]; c--;
00825 }
00826 x.size(n_x);
00827
00828
00829 if (b.one())
00830 GECODE_REWRITE(*this,(EqBoolInt<VX>::post(home,x,c)));
00831 if (b.zero())
00832 GECODE_REWRITE(*this,(NqBoolInt<VX>::post(home,x,c)));
00833
00834 if ((c < 0) || (c > n_x)) {
00835 GECODE_ME_CHECK(b.zero_none(home));
00836 return ES_SUBSUMED(*this,home);
00837 }
00838
00839 int n_s0 = c;
00840
00841 n_s0 = std::min(x.size(),std::max(c,x.size()-c)+1);
00842
00843 while ((n_s < n_x) && (n_s <= n_s0))
00844 if (x[n_s].zero()) {
00845 x[n_s]=x[--n_x];
00846 } else if (x[n_s].one()) {
00847 x[n_s]=x[--n_x]; c--;
00848 } else {
00849 x[n_s++].subscribe(home,*this,PC_INT_VAL,false);
00850 }
00851 x.size(n_x);
00852 if ((c < 0) || (c > n_x)) {
00853 GECODE_ME_CHECK(b.zero_none(home));
00854 return ES_SUBSUMED(*this,home);
00855 }
00856 if (c == 0 && n_x == 0) {
00857 GECODE_ME_CHECK(b.one_none(home));
00858 return ES_SUBSUMED(*this,home);
00859 }
00860 return ES_FIX;
00861 }
00862
00863
00864
00865 template <class VX, class VB>
00866 forceinline
00867 ReGqBoolInt<VX,VB>::Speed::Speed(Space& home, ViewArray<VX>& x, int c, VB b)
00868
00869 : SpeedReLinBoolInt<VX,VB>
00870 (home,x,std::min(x.size(),std::max(c,x.size()-c)+1),c,b) {}
00871 template <class VX, class VB>
00872 forceinline
00873 ReEqBoolInt<VX,VB>::Speed::Speed(Space& home, ViewArray<VX>& x, int c, VB b)
00874
00875 : SpeedReLinBoolInt<VX,VB>
00876 (home,x,std::min(x.size(),std::max(c,x.size()-c)+1),c,b) {}
00877
00878 template <class VX, class VB>
00879 forceinline
00880 ReGqBoolInt<VX,VB>::Speed::Speed(Space& home, bool share,
00881 typename ReGqBoolInt<VX,VB>::Speed& p)
00882 : SpeedReLinBoolInt<VX,VB>(home,share,p) {}
00883 template <class VX, class VB>
00884 forceinline
00885 ReEqBoolInt<VX,VB>::Speed::Speed(Space& home, bool share,
00886 typename ReEqBoolInt<VX,VB>::Speed& p)
00887 : SpeedReLinBoolInt<VX,VB>(home,share,p) {}
00888
00889 template <class VX, class VB>
00890 Actor*
00891 ReGqBoolInt<VX,VB>::Speed::copy(Space& home, bool share) {
00892 return new (home) Speed(home,share,*this);
00893 }
00894 template <class VX, class VB>
00895 Actor*
00896 ReEqBoolInt<VX,VB>::Speed::copy(Space& home, bool share) {
00897 return new (home) Speed(home,share,*this);
00898 }
00899
00900
00901 template <class VX, class VB>
00902 inline ExecStatus
00903 ReGqBoolInt<VX,VB>::Speed::rewrite_inverse(Space& home,
00904 ViewArray<BoolView>& x, int c) {
00905 ViewArray<NegBoolView> y(home,x.size());
00906 for (int i=x.size(); i--; )
00907 y[i]=x[i];
00908 GECODE_REWRITE(*this,(GqBoolInt<NegBoolView>::post(home,y,x.size()-c+1)));
00909 }
00910
00911 template <class VX, class VB>
00912 inline ExecStatus
00913 ReGqBoolInt<VX,VB>::Speed::rewrite_inverse(Space& home,
00914 ViewArray<NegBoolView>& x, int c) {
00915 ViewArray<BoolView> y(home,x.size());
00916 for (int i=x.size(); i--; )
00917 y[i]=x[i].base();
00918 GECODE_REWRITE(*this,(GqBoolInt<BoolView>::post(home,y,x.size()-c+1)));
00919 }
00920
00921
00922 template <class VX, class VB>
00923 ExecStatus
00924 ReGqBoolInt<VX,VB>::Speed::advise(Space& home, Advisor& _a, const Delta&) {
00925 ViewAdvisor<VX>& a = static_cast<ViewAdvisor<VX>&>(_a);
00926 if (n_s == 0)
00927 return ES_SUBSUMED_FIX(a,home,co);
00928
00929
00930 assert(!a.view().none());
00931 if (a.view().one())
00932 c--;
00933 n_s--;
00934 if ((n_s+x.size() < c) || (c <= 0))
00935 return ES_SUBSUMED_NOFIX(a,home,co);
00936
00937
00938 int n_s0 = std::min(x.size(),std::max(c,x.size()-c)+1);
00939 if (n_s < n_s0) {
00940 assert(n_s == n_s0-1);
00941 for (int i = x.size(); i--; ) {
00942
00943 if (x[i].one()) {
00944 c--;
00945 } else if (x[i].none()) {
00946
00947 if ((n_s+(i+1) < c) || (c < 0)) {
00948 x.size(i+1);
00949 return ES_SUBSUMED_NOFIX(a,home,co);
00950 }
00951 a.view(home,x[i]);
00952 n_s++;
00953 x.size(i);
00954 return ES_FIX;
00955 }
00956 }
00957
00958 x.size(0);
00959 if ((n_s+x.size() < c) || (c <= 0))
00960 return ES_SUBSUMED_NOFIX(a,home,co);
00961 }
00962
00963 return ES_SUBSUMED_FIX(a,home,co);
00964 }
00965
00966 template <class VX, class VB>
00967 ExecStatus
00968 ReEqBoolInt<VX,VB>::Speed::advise(Space& home, Advisor& _a, const Delta&) {
00969 ViewAdvisor<VX>& a = static_cast<ViewAdvisor<VX>&>(_a);
00970 if (n_s == 0)
00971 return ES_SUBSUMED_FIX(a,home,co);
00972
00973
00974 assert(!a.view().none());
00975 if (a.view().one())
00976 c--;
00977 n_s--;
00978 if ((c < 0) || (n_s+x.size() < c) || (n_s+x.size() == 0))
00979
00980 return ES_SUBSUMED_NOFIX(a,home,co);
00981
00982
00983 int n_s0 = std::min(x.size(),std::max(c,x.size()-c)+1);
00984 if (n_s < n_s0) {
00985 assert(n_s == n_s0-1);
00986 for (int i = x.size(); i--; ) {
00987
00988 if (x[i].one()) {
00989 c--;
00990 } else if (x[i].none()) {
00991
00992 if ((n_s+(i+1) < c) || (c < 0)) {
00993 x.size(i+1);
00994 return ES_SUBSUMED_NOFIX(a,home,co);
00995 }
00996 a.view(home,x[i]);
00997 n_s++;
00998 x.size(i);
00999 return ES_FIX;
01000 }
01001 }
01002
01003 x.size(0);
01004 if ((c < 0) || (n_s < c) || (n_s == 0))
01005 return ES_SUBSUMED_NOFIX(a,home,co);
01006 }
01007
01008 return ES_SUBSUMED_FIX(a,home,co);
01009 }
01010
01011
01012
01013 template <class VX, class VB>
01014 ExecStatus
01015 ReGqBoolInt<VX,VB>::Speed::propagate(Space& home, const ModEventDelta&) {
01016
01017 int real_n_s = n_s;
01018
01019 n_s = 0;
01020 if (b.none()) {
01021 if (c <= 0) {
01022 GECODE_ME_CHECK(b.one_none(home));
01023 } else {
01024 GECODE_ME_CHECK(b.zero_none(home));
01025 }
01026 } else {
01027
01028 int real_n = x.size();
01029 ViewArray<VX> real_x(home, real_n+real_n_s);
01030 for (int i=real_n; i--; )
01031 real_x[i] = x[i];
01032 x.size(0);
01033 for (Advisors<ViewAdvisor<VX> > as(co); as(); ++as)
01034 real_x[real_n++] = as.advisor().view();
01035
01036 if (b.one())
01037 GECODE_REWRITE(*this,(GqBoolInt<VX>::post(home,real_x,c)));
01038 if (b.zero())
01039 return rewrite_inverse(home, real_x, c);
01040 }
01041 return ES_SUBSUMED(*this,home);
01042 }
01043
01044 template <class VX, class VB>
01045 ExecStatus
01046 ReEqBoolInt<VX,VB>::Speed::propagate(Space& home, const ModEventDelta&) {
01047
01048 int real_n_s = n_s;
01049
01050 n_s = 0;
01051
01052 if (b.none()) {
01053 if (c == 0 && real_n_s+x.size() == 0) {
01054 GECODE_ME_CHECK(b.one_none(home));
01055 } else {
01056 GECODE_ME_CHECK(b.zero_none(home));
01057 }
01058 } else {
01059
01060 int real_n = x.size();
01061 ViewArray<VX> real_x(home, real_n+real_n_s);
01062 for (int i=real_n; i--; )
01063 real_x[i] = x[i];
01064 x.size(0);
01065 for (Advisors<ViewAdvisor<VX> > as(co); as(); ++as)
01066 real_x[real_n++] = as.advisor().view();
01067
01068 if (b.one())
01069 GECODE_REWRITE(*this,(EqBoolInt<VX>::post(home,real_x,c)));
01070 if (b.zero())
01071 GECODE_REWRITE(*this,(NqBoolInt<VX>::post(home,real_x,c)));
01072 }
01073 return ES_SUBSUMED(*this,home);
01074 }
01075
01076
01077
01078 template <class VX, class VB>
01079 ExecStatus
01080 ReGqBoolInt<VX,VB>::post(Space& home, ViewArray<VX>& x, int c, VB b) {
01081 assert(!b.assigned());
01082
01083
01084 int n_x = x.size();
01085 for (int i=n_x; i--; )
01086 if (x[i].zero()) {
01087 x[i] = x[--n_x];
01088 } else if (x[i].one()) {
01089 x[i] = x[--n_x]; c--;
01090 }
01091
01092 if (n_x < c) {
01093 GECODE_ME_CHECK(b.zero_none(home));
01094 return ES_OK;
01095 }
01096
01097 if (c <= 0) {
01098 GECODE_ME_CHECK(b.one_none(home));
01099 return ES_OK;
01100 }
01101
01102 assert(n_x >= c);
01103 x.size(n_x);
01104 #if 0
01105
01106 if (x.size() > threshold)
01107 (void) new (home) Speed(home,x,c,b);
01108 else
01109 (void) new (home) Memory(home,x,c,b);
01110 #else
01111 (void) new (home) Memory(home,x,c,b);
01112 #endif
01113 return ES_OK;
01114 }
01115
01116 template <class VX, class VB>
01117 ExecStatus
01118 ReEqBoolInt<VX,VB>::post(Space& home, ViewArray<VX>& x, int c, VB b) {
01119 assert(!b.assigned());
01120
01121
01122 int n_x = x.size();
01123 for (int i=n_x; i--; )
01124 if (x[i].zero()) {
01125 x[i] = x[--n_x];
01126 } else if (x[i].one()) {
01127 x[i] = x[--n_x]; c--;
01128 }
01129
01130 if ((n_x < c) || (c < 0)) {
01131 GECODE_ME_CHECK(b.zero_none(home));
01132 return ES_OK;
01133 }
01134
01135 if ((c == 0) && (n_x == 0)) {
01136 GECODE_ME_CHECK(b.one_none(home));
01137 return ES_OK;
01138 }
01139
01140 assert(n_x >= c);
01141 x.size(n_x);
01142 #if 0
01143
01144 if (x.size() > threshold)
01145 (void) new (home) Speed(home,x,c,b);
01146 else
01147 (void) new (home) Memory(home,x,c,b);
01148 #else
01149 (void) new (home) Memory(home,x,c,b);
01150 #endif
01151 return ES_OK;
01152 }
01153
01154
01155 }}}
01156
01157
01158