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
00041
00042 namespace Gecode { namespace Int {
00043
00044
00045
00046
00047
00048
00049 #define GECODE_INT_RL2PD(r) reinterpret_cast<ptrdiff_t>(r)
00050 #define GECODE_INT_PD2RL(p) reinterpret_cast<RangeList*>(p)
00051
00052 forceinline
00053 IntVarImp::RangeList::RangeList(void) {}
00054
00055 forceinline
00056 IntVarImp::RangeList::RangeList(int min, int max)
00057 : _min(min), _max(max) {}
00058
00059 forceinline
00060 IntVarImp::RangeList::RangeList(int min, int max, RangeList* p, RangeList* n)
00061 : _min(min), _max(max) {
00062 _next = GECODE_INT_PD2RL(GECODE_INT_RL2PD(p)^GECODE_INT_RL2PD(n));
00063 }
00064
00065 forceinline IntVarImp::RangeList*
00066 IntVarImp::RangeList::next(const RangeList* p) const {
00067 return GECODE_INT_PD2RL(GECODE_INT_RL2PD(_next)^GECODE_INT_RL2PD(p));
00068 }
00069 forceinline IntVarImp::RangeList*
00070 IntVarImp::RangeList::prev(const RangeList* n) const {
00071 return GECODE_INT_PD2RL(GECODE_INT_RL2PD(_next)^GECODE_INT_RL2PD(n));
00072 }
00073 forceinline void
00074 IntVarImp::RangeList::prevnext(RangeList* p, RangeList* n) {
00075 _next = GECODE_INT_PD2RL(GECODE_INT_RL2PD(p)^GECODE_INT_RL2PD(n));
00076 }
00077 forceinline void
00078 IntVarImp::RangeList::next(RangeList* o, RangeList* n) {
00079 _next = GECODE_INT_PD2RL(GECODE_INT_RL2PD(_next)^
00080 (GECODE_INT_RL2PD(o)^GECODE_INT_RL2PD(n)));
00081 }
00082 forceinline void
00083 IntVarImp::RangeList::prev(RangeList* o, RangeList* n) {
00084 _next = GECODE_INT_PD2RL(GECODE_INT_RL2PD(_next)^
00085 (GECODE_INT_RL2PD(o)^GECODE_INT_RL2PD(n)));
00086 }
00087 forceinline void
00088 IntVarImp::RangeList::fix(RangeList* n) {
00089 _next = n;
00090 }
00091
00092 forceinline void
00093 IntVarImp::RangeList::min(int n) {
00094 _min = n;
00095 }
00096 forceinline void
00097 IntVarImp::RangeList::max(int n) {
00098 _max = n;
00099 }
00100
00101 forceinline int
00102 IntVarImp::RangeList::min(void) const {
00103 return _min;
00104 }
00105 forceinline int
00106 IntVarImp::RangeList::max(void) const {
00107 return _max;
00108 }
00109 forceinline unsigned int
00110 IntVarImp::RangeList::width(void) const {
00111 return static_cast<unsigned int>(_max - _min) + 1;
00112 }
00113
00114
00115 forceinline void
00116 IntVarImp::RangeList::operator delete(void*) {}
00117
00118 forceinline void
00119 IntVarImp::RangeList::operator delete(void*, Space*) {
00120 GECODE_NEVER;
00121 }
00122
00123 forceinline void*
00124 IntVarImp::RangeList::operator new(size_t, Space* home) {
00125 return home->fl_alloc<sizeof(RangeList)>();
00126 }
00127
00128 forceinline void
00129 IntVarImp::RangeList::dispose(Space* home, RangeList* p, RangeList* l) {
00130 RangeList* c = this;
00131 while (c != l) {
00132 RangeList* n = c->next(p);
00133 c->fix(n);
00134 p=c; c=n;
00135 }
00136 home->fl_dispose<sizeof(RangeList)>(this,l);
00137 }
00138
00139 forceinline void
00140 IntVarImp::RangeList::dispose(Space* home, RangeList* l) {
00141 home->fl_dispose<sizeof(RangeList)>(this,l);
00142 }
00143
00144 forceinline void
00145 IntVarImp::RangeList::dispose(Space* home) {
00146 home->fl_dispose<sizeof(RangeList)>(this,this);
00147 }
00148
00149 #undef GECODE_INT_RL2PD
00150 #undef GECODE_INT_PD2RL
00151
00152
00153
00154
00155
00156
00157 forceinline IntVarImp::RangeList*
00158 IntVarImp::fst(void) const {
00159 return dom.next(NULL);
00160 }
00161
00162 forceinline void
00163 IntVarImp::fst(IntVarImp::RangeList* f) {
00164 dom.prevnext(NULL,f);
00165 }
00166
00167 forceinline IntVarImp::RangeList*
00168 IntVarImp::lst(void) const {
00169 return _lst;
00170 }
00171
00172 forceinline void
00173 IntVarImp::lst(IntVarImp::RangeList* l) {
00174 _lst = l;
00175 }
00176
00177
00178
00179
00180
00181
00182 forceinline
00183 IntVarImp::IntVarImp(Space* home, int min, int max)
00184 : IntVarImpBase(home), dom(min,max,NULL,NULL), holes(0) {}
00185
00186 forceinline
00187 IntVarImp::IntVarImp(Space* home, const IntSet& d)
00188 : IntVarImpBase(home), dom(d.min(),d.max()) {
00189 if (d.size() > 1) {
00190 int n = d.size();
00191 RangeList* r = static_cast<RangeList*>(home->alloc(sizeof(RangeList)*n));
00192 fst(r); lst(r+n-1);
00193 unsigned int h = static_cast<unsigned int>(d.max()-d.min())+1;
00194 for (int i = n; i--; ) {
00195 h -= d.width(i);
00196 r[i].min(d.min(i)); r[i].max(d.max(i));
00197 r[i].prevnext(&r[i-1],&r[i+1]);
00198 }
00199 r[0].prev(&r[-1],NULL);
00200 r[n-1].next(&r[n],NULL);
00201 holes = h;
00202 } else {
00203 fst(NULL); holes = 0;
00204 }
00205 }
00206
00207
00208
00209
00210
00211
00212
00213 forceinline int
00214 IntVarImp::min(void) const {
00215 return dom.min();
00216 }
00217 forceinline int
00218 IntVarImp::max(void) const {
00219 return dom.max();
00220 }
00221 forceinline int
00222 IntVarImp::val(void) const {
00223 assert(dom.min() == dom.max());
00224 return dom.min();
00225 }
00226
00227 forceinline bool
00228 IntVarImp::range(void) const {
00229 return fst() == NULL;
00230 }
00231 forceinline bool
00232 IntVarImp::assigned(void) const {
00233 return dom.min() == dom.max();
00234 }
00235
00236
00237 forceinline unsigned int
00238 IntVarImp::width(void) const {
00239 return dom.width();
00240 }
00241
00242 forceinline unsigned int
00243 IntVarImp::size(void) const {
00244 return dom.width() - holes;
00245 }
00246
00247 forceinline unsigned int
00248 IntVarImp::regret_min(void) const {
00249 if (fst() == NULL) {
00250 return (dom.min() == dom.max()) ? 0U : 1U;
00251 } else if (dom.min() == fst()->max()) {
00252 return static_cast<unsigned int>(fst()->next(NULL)->min()-dom.min());
00253 } else {
00254 return 1U;
00255 }
00256 }
00257 forceinline unsigned int
00258 IntVarImp::regret_max(void) const {
00259 if (fst() == NULL) {
00260 return (dom.min() == dom.max()) ? 0U : 1U;
00261 } else if (dom.max() == lst()->min()) {
00262 return static_cast<unsigned int>(dom.max()-lst()->prev(NULL)->max());
00263 } else {
00264 return 1U;
00265 }
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275 forceinline bool
00276 IntVarImp::in(int n) const {
00277 if ((n < dom.min()) || (n > dom.max()))
00278 return false;
00279 return (fst() == NULL) || in_full(n);
00280 }
00281 forceinline bool
00282 IntVarImp::in(double n) const {
00283 if ((n < dom.min()) || (n > dom.max()))
00284 return false;
00285 return (fst() == NULL) || in_full(static_cast<int>(n));
00286 }
00287
00288
00289
00290
00291
00292
00293
00294 forceinline const IntVarImp::RangeList*
00295 IntVarImp::ranges_fwd(void) const {
00296 return (fst() == NULL) ? &dom : fst();
00297 }
00298
00299 forceinline const IntVarImp::RangeList*
00300 IntVarImp::ranges_bwd(void) const {
00301 return (fst() == NULL) ? &dom : lst();
00302 }
00303
00304
00305
00306
00307
00308
00309
00310 forceinline ModEvent
00311 IntVarImp::modevent(const Delta* d) {
00312 return d->modevent();
00313 }
00314 forceinline int
00315 IntVarImp::min(const Delta* d) const {
00316 return static_cast<const IntDelta*>(d)->min();
00317 }
00318 forceinline int
00319 IntVarImp::max(const Delta* d) const {
00320 return static_cast<const IntDelta*>(d)->max();
00321 }
00322 forceinline bool
00323 IntVarImp::any(const Delta* d) const {
00324 return static_cast<const IntDelta*>(d)->any();
00325 }
00326
00327
00328
00329
00330
00331
00332
00333 forceinline ModEvent
00334 IntVarImp::gq(Space* home, int n) {
00335 if (n <= dom.min()) return ME_INT_NONE;
00336 if (n > dom.max()) return ME_INT_FAILED;
00337 ModEvent me = gq_full(home,n);
00338 GECODE_ASSUME((me == ME_INT_FAILED) |
00339 (me == ME_INT_VAL) |
00340 (me == ME_INT_BND));
00341 return me;
00342 }
00343 forceinline ModEvent
00344 IntVarImp::gq(Space* home, double n) {
00345 if (n <= dom.min()) return ME_INT_NONE;
00346 if (n > dom.max()) return ME_INT_FAILED;
00347 ModEvent me = gq_full(home,static_cast<int>(n));
00348 GECODE_ASSUME((me == ME_INT_FAILED) |
00349 (me == ME_INT_VAL) |
00350 (me == ME_INT_BND));
00351 return me;
00352 }
00353
00354
00355 forceinline ModEvent
00356 IntVarImp::lq(Space* home, int n) {
00357 if (n >= dom.max()) return ME_INT_NONE;
00358 if (n < dom.min()) return ME_INT_FAILED;
00359 ModEvent me = lq_full(home,n);
00360 GECODE_ASSUME((me == ME_INT_FAILED) |
00361 (me == ME_INT_VAL) |
00362 (me == ME_INT_BND));
00363 return me;
00364 }
00365 forceinline ModEvent
00366 IntVarImp::lq(Space* home, double n) {
00367 if (n >= dom.max()) return ME_INT_NONE;
00368 if (n < dom.min()) return ME_INT_FAILED;
00369 ModEvent me = lq_full(home,static_cast<int>(n));
00370 GECODE_ASSUME((me == ME_INT_FAILED) |
00371 (me == ME_INT_VAL) |
00372 (me == ME_INT_BND));
00373 return me;
00374 }
00375
00376
00377 forceinline ModEvent
00378 IntVarImp::eq(Space* home, int n) {
00379 if ((n < dom.min()) || (n > dom.max()))
00380 return ME_INT_FAILED;
00381 if ((n == dom.min()) && (n == dom.max()))
00382 return ME_INT_NONE;
00383 ModEvent me = eq_full(home,n);
00384 GECODE_ASSUME((me == ME_INT_FAILED) | (me == ME_INT_VAL));
00385 return me;
00386 }
00387 forceinline ModEvent
00388 IntVarImp::eq(Space* home, double m) {
00389 if ((m < dom.min()) || (m > dom.max()))
00390 return ME_INT_FAILED;
00391 int n = static_cast<int>(m);
00392 if ((n == dom.min()) && (n == dom.max()))
00393 return ME_INT_NONE;
00394 ModEvent me = eq_full(home,n);
00395 GECODE_ASSUME((me == ME_INT_FAILED) | (me == ME_INT_VAL));
00396 return me;
00397 }
00398
00399
00400 forceinline ModEvent
00401 IntVarImp::nq(Space* home, int n) {
00402 if ((n < dom.min()) || (n > dom.max()))
00403 return ME_INT_NONE;
00404 return nq_full(home,n);
00405 }
00406 forceinline ModEvent
00407 IntVarImp::nq(Space* home, double d) {
00408 if ((d < dom.min()) || (d > dom.max()))
00409 return ME_INT_NONE;
00410 return nq_full(home,static_cast<int>(d));
00411 }
00412
00413
00414
00415
00416
00417
00418
00419 forceinline
00420 IntVarImpFwd::IntVarImpFwd(void) {}
00421 forceinline
00422 IntVarImpFwd::IntVarImpFwd(const IntVarImp* x)
00423 : p(NULL), c(x->ranges_fwd()) {}
00424 forceinline void
00425 IntVarImpFwd::init(const IntVarImp* x) {
00426 p=NULL; c=x->ranges_fwd();
00427 }
00428
00429 forceinline bool
00430 IntVarImpFwd::operator()(void) const {
00431 return c != NULL;
00432 }
00433 forceinline void
00434 IntVarImpFwd::operator++(void) {
00435 const IntVarImp::RangeList* n=c->next(p); p=c; c=n;
00436 }
00437
00438 forceinline int
00439 IntVarImpFwd::min(void) const {
00440 return c->min();
00441 }
00442 forceinline int
00443 IntVarImpFwd::max(void) const {
00444 return c->max();
00445 }
00446 forceinline unsigned int
00447 IntVarImpFwd::width(void) const {
00448 return c->width();
00449 }
00450
00451
00452
00453
00454
00455
00456
00457 forceinline
00458 IntVarImpBwd::IntVarImpBwd(void) {}
00459 forceinline
00460 IntVarImpBwd::IntVarImpBwd(const IntVarImp* x)
00461 : n(NULL), c(x->ranges_bwd()) {}
00462 forceinline void
00463 IntVarImpBwd::init(const IntVarImp* x) {
00464 n=NULL; c=x->ranges_bwd();
00465 }
00466
00467 forceinline bool
00468 IntVarImpBwd::operator()(void) const {
00469 return c != NULL;
00470 }
00471 forceinline void
00472 IntVarImpBwd::operator++(void) {
00473 const IntVarImp::RangeList* p=c->prev(n); n=c; c=p;
00474 }
00475
00476 forceinline int
00477 IntVarImpBwd::min(void) const {
00478 return c->min();
00479 }
00480 forceinline int
00481 IntVarImpBwd::max(void) const {
00482 return c->max();
00483 }
00484 forceinline unsigned int
00485 IntVarImpBwd::width(void) const {
00486 return c->width();
00487 }
00488
00489
00490
00491
00492
00493
00494 template <class I>
00495 forceinline ModEvent
00496 IntVarImp::narrow_r(Space* home, I& ri, bool depends) {
00497
00498 if (!ri())
00499 return ME_INT_FAILED;
00500
00501 int min0 = ri.min();
00502 int max0 = ri.max();
00503 ++ri;
00504
00505 ModEvent me;
00506
00507
00508 if (!ri()) {
00509
00510
00511 if (fst()) {
00512 fst()->dispose(home,NULL,lst());
00513 fst(NULL); holes = 0;
00514 }
00515 const int min1 = dom.min(); dom.min(min0);
00516 const int max1 = dom.max(); dom.max(max0);
00517 if ((min0 == min1) && (max0 == max1))
00518 return ME_INT_NONE;
00519 me = (min0 == max0) ? ME_INT_VAL : ME_INT_BND;
00520 goto notify;
00521 }
00522
00523 if (depends || range()) {
00524
00525 RangeList* f = new (home) RangeList(min0,max0,NULL,NULL);
00526 RangeList* l = f;
00527 unsigned int s = static_cast<unsigned int>(max0-min0+1);
00528 do {
00529 RangeList* n = new (home) RangeList(ri.min(),ri.max(),l,NULL);
00530 l->next(NULL,n);
00531 l = n;
00532 s += ri.width();
00533 ++ri;
00534 } while (ri());
00535 if (fst() != NULL)
00536 fst()->dispose(home,NULL,lst());
00537 fst(f); lst(l);
00538
00539
00540 if (size() == s)
00541 return ME_INT_NONE;
00542
00543 const int min1 = dom.min(); min0 = f->min(); dom.min(min0);
00544 const int max1 = dom.max(); max0 = l->max(); dom.max(max0);
00545 holes = width() - s;
00546
00547 me = ((min0 == min1) && (max0 == max1)) ? ME_INT_DOM : ME_INT_BND;
00548 goto notify;
00549 } else {
00550
00551 RangeList f, l;
00552
00553 f.prevnext(NULL,fst()); l.prevnext(lst(),NULL);
00554 fst()->prev(NULL,&f); lst()->next(NULL,&l);
00555
00556
00557 unsigned int h = 0;
00558
00559 RangeList* p = &f;
00560
00561 RangeList* r = f.next(NULL);
00562
00563 while (true) {
00564 assert((r != &f) && (r != &l));
00565 if (r->max() < min0) {
00566
00567 h += r->width();
00568 RangeList* n=r->next(p);
00569 p->next(r,n); n->prev(r,p);
00570 r->dispose(home);
00571 r=n;
00572 if (r == &l)
00573 goto done;
00574 } else if ((r->min() == min0) && (r->max() == max0)) {
00575
00576 RangeList* n=r->next(p); p=r; r=n;
00577 if (r == &l)
00578 goto done;
00579 if (!ri())
00580 goto done;
00581 min0=ri.min(); max0=ri.max(); ++ri;
00582 } else {
00583
00584 assert((r->min() <= min0) && (max0 <= r->max()));
00585 h += r->width();
00586 int end = r->max();
00587
00588 r->min(min0); r->max(max0);
00589 assert(h > r->width());
00590 h -= r->width();
00591 {
00592 RangeList* n=r->next(p); p=r; r=n;
00593 }
00594 while (true) {
00595 if (!ri())
00596 goto done;
00597 min0=ri.min(); max0=ri.max(); ++ri;
00598 if (max0 > end)
00599 break;
00600 assert(h > static_cast<unsigned int>(max0-min0+1));
00601 h -= max0-min0+1;
00602 RangeList* n = new (home) RangeList(min0,max0,p,r);
00603 p->next(r,n); r->prev(p,n);
00604 p=n;
00605 }
00606 if (r == &l)
00607 goto done;
00608 }
00609 }
00610 done:
00611
00612
00613 while (r != &l) {
00614 h += r->width();
00615 RangeList* n=r->next(p);
00616 p->next(r,n); n->prev(r,p);
00617 r->dispose(home);
00618 r=n;
00619 }
00620
00621 assert((r == &l) && !ri());
00622
00623
00624 RangeList* fn = f.next(NULL);
00625 RangeList* ln = l.prev(NULL);
00626
00627
00628 assert(fn != &l);
00629
00630
00631 assert(fn != ln);
00632
00633
00634 holes += h;
00635
00636 fn->prev(&f,NULL); ln->next(&l,NULL);
00637
00638 unsigned int b = (static_cast<unsigned int>(fn->min()-dom.min()) +
00639 static_cast<unsigned int>(dom.max()-ln->max()));
00640
00641 fst(fn); lst(ln);
00642
00643 if (b > 0) {
00644 assert((dom.min() != fn->min()) || (dom.max() != ln->max()));
00645 dom.min(fn->min()); dom.max(ln->max());
00646 holes -= b;
00647 me = ME_INT_BND; goto notify;
00648 }
00649
00650 if (h > 0) {
00651 assert((dom.min() == fn->min()) && (dom.max() == ln->max()));
00652 me = ME_INT_DOM; goto notify;
00653 }
00654 return ME_INT_NONE;
00655 }
00656 notify:
00657 IntDelta d;
00658 return notify(home,me,&d);
00659 }
00660
00661 template <class I>
00662 forceinline ModEvent
00663 IntVarImp::inter_r(Space* home, I& i, bool) {
00664 IntVarImpFwd j(this);
00665 Iter::Ranges::Inter<I,IntVarImpFwd> ij(i,j);
00666 return narrow_r(home,ij,true);
00667 }
00668
00669 template <class I>
00670 forceinline ModEvent
00671 IntVarImp::minus_r(Space* home, I& i, bool depends) {
00672 if (depends) {
00673 IntVarImpFwd j(this);
00674 Iter::Ranges::Diff<IntVarImpFwd,I> ij(j,i);
00675 return narrow_r(home,ij,true);
00676 }
00677
00678
00679 while (i() && (i.max() < dom.min()))
00680 ++i;
00681
00682
00683 if (!i() || (i.min() > dom.max()))
00684 return ME_INT_NONE;
00685
00686 if ((i.min() <= dom.min()) && (i.max() >= dom.max()))
00687 return ME_INT_FAILED;
00688
00689
00690 RangeList f, l;
00691
00692 if (range()) {
00693
00694 RangeList* n = new (home) RangeList(min(),max(),&f,&l);
00695 f.prevnext(NULL,n); l.prevnext(n,NULL);
00696 } else {
00697
00698 f.prevnext(NULL,fst()); l.prevnext(lst(),NULL);
00699 fst()->prev(NULL,&f); lst()->next(NULL,&l);
00700 }
00701
00702
00703 unsigned int h = 0;
00704
00705 RangeList* p = &f;
00706
00707 RangeList* r = f.next(NULL);
00708
00709 while (true) {
00710 assert((r != &f) && (r != &l) && i());
00711 if (i.min() > r->max()) {
00712 RangeList* n=r->next(p); p=r; r=n;
00713 if (r == &l)
00714 break;
00715 } else if (i.max() < r->min()) {
00716 ++i;
00717 if (!i())
00718 break;
00719 } else if ((i.min() <= r->min()) && (r->max() <= i.max())) {
00720
00721 h += r->width();
00722 RangeList* n=r->next(p);
00723 p->next(r,n); n->prev(r,p);
00724 r->dispose(home);
00725 r=n;
00726 if (r == &l)
00727 break;
00728 } else if ((i.min() > r->min()) && (i.max() < r->max())) {
00729
00730 h += i.width();
00731 RangeList* n = new (home) RangeList(r->min(),i.min()-1,p,r);
00732 r->min(i.max()+1);
00733 p->next(r,n); r->prev(p,n);
00734 p=n;
00735 ++i;
00736 if (!i())
00737 break;
00738 } else if (i.max() < r->max()) {
00739 assert(i.min() <= r->min());
00740
00741 h += i.max()-r->min()+1;
00742 r->min(i.max()+1);
00743 ++i;
00744 if (!i())
00745 break;
00746 } else {
00747 assert((i.max() >= r->max()) && (r->min() < i.min()));
00748
00749 h += r->max()-i.min()+1;
00750 r->max(i.min()-1);
00751 RangeList* n=r->next(p); p=r; r=n;
00752 if (r == &l)
00753 break;
00754 }
00755 }
00756
00757 assert((r == &l) || !i());
00758
00759
00760 RangeList* fn = f.next(NULL);
00761 RangeList* ln = l.prev(NULL);
00762
00763
00764 if (fn == &l) {
00765 fst(NULL); lst(NULL); holes=0;
00766 return ME_INT_FAILED;
00767 }
00768
00769 ModEvent me;
00770 unsigned int b;
00771
00772
00773 if (fn == ln) {
00774 assert(h > 0);
00775 dom.min(fn->min()); dom.max(fn->max());
00776 fn->dispose(home);
00777 fst(NULL); lst(NULL);
00778 holes = 0;
00779 me = assigned() ? ME_INT_VAL : ME_INT_BND;
00780 goto notify;
00781 }
00782
00783
00784 holes += h;
00785
00786 fn->prev(&f,NULL); ln->next(&l,NULL);
00787
00788 b = (static_cast<unsigned int>(fn->min()-dom.min()) +
00789 static_cast<unsigned int>(dom.max()-ln->max()));
00790
00791 fst(fn); lst(ln);
00792
00793 if (b > 0) {
00794 assert((dom.min() != fn->min()) || (dom.max() != ln->max()));
00795 dom.min(fn->min()); dom.max(ln->max());
00796 holes -= b;
00797 me = ME_INT_BND; goto notify;
00798 }
00799
00800 if (h > 0) {
00801 assert((dom.min() == fn->min()) && (dom.max() == ln->max()));
00802 me = ME_INT_DOM; goto notify;
00803 }
00804
00805 return ME_INT_NONE;
00806 notify:
00807 IntDelta d;
00808 return notify(home,me,&d);
00809 }
00810
00811 template <class I>
00812 forceinline ModEvent
00813 IntVarImp::narrow_v(Space* home, I& i, bool depends) {
00814 Iter::Values::ToRanges<I> r(i);
00815 return narrow_r(home,r,depends);
00816 }
00817
00818 template <class I>
00819 forceinline ModEvent
00820 IntVarImp::inter_v(Space* home, I& i, bool depends) {
00821 Iter::Values::ToRanges<I> r(i);
00822 return inter_r(home,r,depends);
00823 }
00824
00825 template <class I>
00826 forceinline ModEvent
00827 IntVarImp::minus_v(Space* home, I& i, bool depends) {
00828 if (depends) {
00829 Iter::Values::ToRanges<I> r(i);
00830 return minus_r(home, r, true);
00831 }
00832
00833
00834 while (i() && (i.val() < dom.min()))
00835 ++i;
00836
00837
00838 if (!i() || (i.val() > dom.max()))
00839 return ME_INT_NONE;
00840
00841 int v = i.val();
00842
00843 do {
00844 ++i;
00845 } while (i() && (i.val() == v));
00846
00847
00848 if (!i() || (i.val() > dom.max()))
00849 return nq_full(home,v);
00850
00851
00852 RangeList f, l;
00853
00854 if (range()) {
00855
00856 RangeList* n = new (home) RangeList(min(),max(),&f,&l);
00857 f.prevnext(NULL,n); l.prevnext(n,NULL);
00858 } else {
00859
00860 f.prevnext(NULL,fst()); l.prevnext(lst(),NULL);
00861 fst()->prev(NULL,&f); lst()->next(NULL,&l);
00862 }
00863
00864
00865 unsigned int h = 0;
00866
00867 RangeList* p = &f;
00868
00869 RangeList* r = f.next(NULL);
00870
00871 while (true) {
00872 assert((r != &f) && (r != &l));
00873 if (v > r->max()) {
00874
00875 RangeList* n=r->next(p); p=r; r=n;
00876 if (r == &l)
00877 break;
00878 } else {
00879 if ((v == r->min()) && (v == r->max())) {
00880
00881 h++;
00882 RangeList* n=r->next(p);
00883 p->next(r,n); n->prev(r,p);
00884 r->dispose(home);
00885 r=n;
00886 if (r == &l)
00887 break;
00888 } else if (v == r->min()) {
00889 h++; r->min(v+1);
00890 } else if (v == r->max()) {
00891 h++; r->max(v-1);
00892 RangeList* n=r->next(p); p=r; r=n;
00893 if (r == &l)
00894 break;
00895 } else if (v > r->min()) {
00896
00897 assert(v < r->max());
00898 h++;
00899 RangeList* n = new (home) RangeList(r->min(),v-1,p,r);
00900 r->min(v+1);
00901 p->next(r,n); r->prev(p,n);
00902 p=n;
00903 }
00904 if (!i())
00905 break;
00906
00907 v = i.val(); ++i;
00908 }
00909 }
00910 assert((r == &l) || !i());
00911
00912
00913 RangeList* fn = f.next(NULL);
00914 RangeList* ln = l.prev(NULL);
00915
00916
00917 if (fn == &l) {
00918 fst(NULL); lst(NULL); holes=0;
00919 return ME_INT_FAILED;
00920 }
00921
00922 IntDelta d;
00923
00924
00925 if (fn == ln) {
00926 assert(h > 0);
00927 dom.min(fn->min()); dom.max(fn->max());
00928 fn->dispose(home);
00929 fst(NULL); lst(NULL);
00930 holes = 0;
00931 if (assigned())
00932 return notify(home,ME_INT_VAL,&d);
00933 else
00934 return notify(home,ME_INT_BND,&d);
00935 }
00936
00937
00938 holes += h;
00939
00940 fn->prev(&f,NULL); ln->next(&l,NULL);
00941
00942 unsigned int b = (static_cast<unsigned int>(fn->min()-dom.min()) +
00943 static_cast<unsigned int>(dom.max()-ln->max()));
00944
00945 fst(fn); lst(ln);
00946
00947 if (b > 0) {
00948 assert((dom.min() != fn->min()) || (dom.max() != ln->max()));
00949 dom.min(fn->min()); dom.max(ln->max());
00950 holes -= b;
00951 return notify(home,ME_INT_BND,&d);
00952 }
00953
00954 if (h > 0) {
00955 assert((dom.min() == fn->min()) && (dom.max() == ln->max()));
00956 return notify(home,ME_INT_DOM,&d);
00957 }
00958
00959 return ME_INT_NONE;
00960 }
00961
00962
00963
00964
00965
00966
00967
00968 forceinline IntVarImp*
00969 IntVarImp::copy(Space* home, bool share) {
00970 return copied() ? static_cast<IntVarImp*>(forward())
00971 : perform_copy(home,share);
00972 }
00973
00974
00975
00976
00977
00978
00979 forceinline void
00980 IntVarImp::subscribe(Space* home, Propagator* p, PropCond pc, bool process) {
00981 IntVarImpBase::subscribe(home,p,pc,dom.min()==dom.max(),process);
00982 }
00983 forceinline void
00984 IntVarImp::cancel(Space* home, Propagator* p, PropCond pc) {
00985 IntVarImpBase::cancel(home,p,pc,dom.min()==dom.max());
00986 }
00987
00988 forceinline void
00989 IntVarImp::subscribe(Space* home, Advisor* a) {
00990 IntVarImpBase::subscribe(home,a,dom.min()==dom.max());
00991 }
00992 forceinline void
00993 IntVarImp::cancel(Space* home, Advisor* a) {
00994 IntVarImpBase::cancel(home,a,dom.min()==dom.max());
00995 }
00996
00997 forceinline ModEventDelta
00998 IntVarImp::med(ModEvent me) {
00999 return IntVarImpBase::med(me);
01000 }
01001
01002 }}
01003
01004