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 namespace Gecode { namespace Int {
00027
00028
00029
00030
00031
00032
00033 #define GECODE_INT_RL2PD(r) reinterpret_cast<ptrdiff_t>(r)
00034 #define GECODE_INT_PD2RL(p) reinterpret_cast<RangeList*>(p)
00035
00036 forceinline
00037 IntVarImp::RangeList::RangeList(void) {}
00038
00039 forceinline
00040 IntVarImp::RangeList::RangeList(int min, int max)
00041 : _min(min), _max(max) {}
00042
00043 forceinline
00044 IntVarImp::RangeList::RangeList(int min, int max, RangeList* p, RangeList* n)
00045 : _min(min), _max(max) {
00046 _next = GECODE_INT_PD2RL(GECODE_INT_RL2PD(p)^GECODE_INT_RL2PD(n));
00047 }
00048
00049 forceinline IntVarImp::RangeList*
00050 IntVarImp::RangeList::next(const RangeList* p) const {
00051 return GECODE_INT_PD2RL(GECODE_INT_RL2PD(_next)^GECODE_INT_RL2PD(p));
00052 }
00053 forceinline IntVarImp::RangeList*
00054 IntVarImp::RangeList::prev(const RangeList* n) const {
00055 return GECODE_INT_PD2RL(GECODE_INT_RL2PD(_next)^GECODE_INT_RL2PD(n));
00056 }
00057 forceinline void
00058 IntVarImp::RangeList::prevnext(RangeList* p, RangeList* n) {
00059 _next = GECODE_INT_PD2RL(GECODE_INT_RL2PD(p)^GECODE_INT_RL2PD(n));
00060 }
00061 forceinline void
00062 IntVarImp::RangeList::next(RangeList* o, RangeList* n) {
00063 _next = GECODE_INT_PD2RL(GECODE_INT_RL2PD(_next)^
00064 (GECODE_INT_RL2PD(o)^GECODE_INT_RL2PD(n)));
00065 }
00066 forceinline void
00067 IntVarImp::RangeList::prev(RangeList* o, RangeList* n) {
00068 _next = GECODE_INT_PD2RL(GECODE_INT_RL2PD(_next)^
00069 (GECODE_INT_RL2PD(o)^GECODE_INT_RL2PD(n)));
00070 }
00071 forceinline void
00072 IntVarImp::RangeList::fix(RangeList* n) {
00073 _next = n;
00074 }
00075
00076 forceinline void
00077 IntVarImp::RangeList::min(int n) {
00078 _min = n;
00079 }
00080 forceinline void
00081 IntVarImp::RangeList::max(int n) {
00082 _max = n;
00083 }
00084
00085 forceinline int
00086 IntVarImp::RangeList::min(void) const {
00087 return _min;
00088 }
00089 forceinline int
00090 IntVarImp::RangeList::max(void) const {
00091 return _max;
00092 }
00093 forceinline unsigned int
00094 IntVarImp::RangeList::width(void) const {
00095 return _max - _min + 1;
00096 }
00097
00098
00099 forceinline void
00100 IntVarImp::RangeList::operator delete(void*) {}
00101
00102 forceinline void
00103 IntVarImp::RangeList::operator delete(void*, Space*) {
00104 GECODE_NEVER;
00105 }
00106
00107 forceinline void*
00108 IntVarImp::RangeList::operator new(size_t s, Space* home) {
00109 assert(s == sizeof(RangeList));
00110 return home->fl_alloc<sizeof(RangeList)>();
00111 }
00112
00113 forceinline void
00114 IntVarImp::RangeList::dispose(Space* home, RangeList* p, RangeList* l) {
00115 RangeList* c = this;
00116 while (c != l) {
00117 RangeList* n = c->next(p);
00118 c->fix(n);
00119 p=c; c=n;
00120 }
00121 home->fl_dispose<sizeof(RangeList)>(this,l);
00122 }
00123
00124 forceinline void
00125 IntVarImp::RangeList::dispose(Space* home, RangeList* l) {
00126 home->fl_dispose<sizeof(RangeList)>(this,l);
00127 }
00128
00129 forceinline void
00130 IntVarImp::RangeList::dispose(Space* home) {
00131 home->fl_dispose<sizeof(RangeList)>(this,this);
00132 }
00133
00134 #undef GECODE_INT_RL2PD
00135 #undef GECODE_INT_PD2RL
00136
00137
00138
00139
00140
00141
00142 forceinline IntVarImp::RangeList*
00143 IntVarImp::fst(void) const {
00144 return dom.next(NULL);
00145 }
00146
00147 forceinline void
00148 IntVarImp::fst(IntVarImp::RangeList* f) {
00149 dom.prevnext(NULL,f);
00150 }
00151
00152 forceinline IntVarImp::RangeList*
00153 IntVarImp::lst(void) const {
00154 return _lst;
00155 }
00156
00157 forceinline void
00158 IntVarImp::lst(IntVarImp::RangeList* l) {
00159 _lst = l;
00160 }
00161
00162
00163
00164
00165
00166
00167 forceinline
00168 IntVarImp::IntVarImp(Space* home, int min, int max)
00169 : IntVarImpBase(home), dom(min,max,NULL,NULL), holes(0) {}
00170
00171 forceinline
00172 IntVarImp::IntVarImp(Space* home, const IntSet& d)
00173 : IntVarImpBase(home), dom(d.min(),d.max()) {
00174 if (d.size() > 1) {
00175 int n = d.size();
00176 RangeList* r = reinterpret_cast<RangeList*>
00177 (home->alloc(sizeof(RangeList)*n));
00178 fst(r); lst(r+n-1);
00179 unsigned int h = d.max()-d.min()+1;
00180 for (int i = n; i--; ) {
00181 h -= d.width(i);
00182 r[i].min(d.min(i)); r[i].max(d.max(i));
00183 r[i].prevnext(&r[i-1],&r[i+1]);
00184 }
00185 r[0].prev(&r[-1],NULL);
00186 r[n-1].next(&r[n],NULL);
00187 holes = h;
00188 } else {
00189 fst(NULL); holes = 0;
00190 }
00191 }
00192
00193
00194
00195
00196
00197
00198
00199 forceinline int
00200 IntVarImp::min(void) const {
00201 return dom.min();
00202 }
00203 forceinline int
00204 IntVarImp::max(void) const {
00205 return dom.max();
00206 }
00207 forceinline int
00208 IntVarImp::val(void) const {
00209 assert(dom.min() == dom.max());
00210 return dom.min();
00211 }
00212
00213 forceinline bool
00214 IntVarImp::range(void) const {
00215 return fst() == NULL;
00216 }
00217 forceinline bool
00218 IntVarImp::assigned(void) const {
00219 return dom.min() == dom.max();
00220 }
00221
00222
00223 forceinline unsigned int
00224 IntVarImp::width(void) const {
00225 return dom.width();
00226 }
00227
00228 forceinline unsigned int
00229 IntVarImp::size(void) const {
00230 return dom.width() - holes;
00231 }
00232
00233 forceinline unsigned int
00234 IntVarImp::regret_min(void) const {
00235 if (fst() == NULL) {
00236 return (dom.min() == dom.max()) ? 0 : 1;
00237 } else if (dom.min() == fst()->max()) {
00238 return fst()->next(NULL)->min()-dom.min();
00239 } else {
00240 return 1;
00241 }
00242 }
00243 forceinline unsigned int
00244 IntVarImp::regret_max(void) const {
00245 if (lst() == NULL) {
00246 return (dom.min() == dom.max()) ? 0 : 1;
00247 } else if (dom.max() == lst()->min()) {
00248 return dom.max()-lst()->prev(NULL)->max();
00249 } else {
00250 return 1;
00251 }
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261 forceinline bool
00262 IntVarImp::in(int n) const {
00263 if ((n < dom.min()) || (n > dom.max()))
00264 return false;
00265 return (fst() == NULL) || in_full(n);
00266 }
00267 forceinline bool
00268 IntVarImp::in(double n) const {
00269 if ((n < dom.min()) || (n > dom.max()))
00270 return false;
00271 return (fst() == NULL) || in_full(static_cast<int>(n));
00272 }
00273
00274
00275
00276
00277
00278
00279
00280 forceinline const IntVarImp::RangeList*
00281 IntVarImp::ranges_fwd(void) const {
00282 return (fst() == NULL) ? &dom : fst();
00283 }
00284
00285 forceinline const IntVarImp::RangeList*
00286 IntVarImp::ranges_bwd(void) const {
00287 return (fst() == NULL) ? &dom : lst();
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297 forceinline ModEvent
00298 IntVarImp::gq(Space* home, int n) {
00299 if (n <= dom.min()) return ME_INT_NONE;
00300 if (n > dom.max()) return ME_INT_FAILED;
00301 gq_full(home,n);
00302 if (assigned())
00303 return ME_INT_VAL;
00304 return ME_INT_BND;
00305 }
00306 forceinline ModEvent
00307 IntVarImp::gq(Space* home, double n) {
00308 if (n <= dom.min()) return ME_INT_NONE;
00309 if (n > dom.max()) return ME_INT_FAILED;
00310 gq_full(home,static_cast<int>(n));
00311 if (assigned())
00312 return ME_INT_VAL;
00313 return ME_INT_BND;
00314 }
00315
00316
00317 forceinline ModEvent
00318 IntVarImp::lq(Space* home, int n) {
00319 if (n >= dom.max()) return ME_INT_NONE;
00320 if (n < dom.min()) return ME_INT_FAILED;
00321 lq_full(home,n);
00322 if (dom.min() == n)
00323 return ME_INT_VAL;
00324 return ME_INT_BND;
00325 }
00326 forceinline ModEvent
00327 IntVarImp::lq(Space* home, double n) {
00328 if (n >= dom.max()) return ME_INT_NONE;
00329 if (n < dom.min()) return ME_INT_FAILED;
00330 lq_full(home,static_cast<int>(n));
00331 if (dom.max() == n)
00332 return ME_INT_VAL;
00333 return ME_INT_BND;
00334 }
00335
00336
00337 forceinline ModEvent
00338 IntVarImp::eq(Space* home, int n) {
00339 if ((n < dom.min()) || (n > dom.max()))
00340 return ME_INT_FAILED;
00341 if ((n == dom.min()) && (n == dom.max()))
00342 return ME_INT_NONE;
00343 eq_full(home,n);
00344 if (dom.min() == Limits::Int::int_max+1)
00345 return ME_INT_FAILED;
00346 return ME_INT_VAL;
00347 }
00348 forceinline ModEvent
00349 IntVarImp::eq(Space* home, double n) {
00350 if ((n < dom.min()) || (n > dom.max()))
00351 return ME_INT_FAILED;
00352 if ((n == dom.min()) && (n == dom.max()))
00353 return ME_INT_NONE;
00354 eq_full(home,static_cast<int>(n));
00355 if (dom.min() == Limits::Int::int_max+1)
00356 return ME_INT_FAILED;
00357 return ME_INT_VAL;
00358 }
00359
00360
00361 forceinline ModEvent
00362 IntVarImp::nq(Space* home, int n) {
00363 if ((n < dom.min()) || (n > dom.max())) return ME_INT_NONE;
00364 return nq_full(home,n);
00365 }
00366 forceinline ModEvent
00367 IntVarImp::nq(Space* home, double d) {
00368 if ((d < dom.min()) || (d > dom.max())) return ME_INT_NONE;
00369 return nq_full(home,static_cast<int>(d));
00370 }
00371
00372
00373
00374
00375
00376
00377
00378 template <class I>
00379 forceinline ModEvent
00380 IntVarImp::narrow(Space* home, I& ri) {
00381
00382 if (!ri())
00383 return ME_INT_FAILED;
00384 int min0 = ri.min();
00385 int max0 = ri.max();
00386 ++ri;
00387
00388 if (!ri()) {
00389
00390
00391 if (fst()) {
00392 fst()->dispose(home,NULL,lst());
00393 fst(NULL); holes = 0;
00394 }
00395 const int min1 = dom.min(); dom.min(min0);
00396 const int max1 = dom.max(); dom.max(max0);
00397 if ((min0 == min1) && (max0 == max1))
00398 return ME_INT_NONE;
00399 if (min0 == max0) {
00400 notify(home,ME_INT_VAL);
00401 return ME_INT_VAL;
00402 }
00403 } else {
00404
00405 RangeList* f = new (home) RangeList(min0,max0,NULL,NULL);
00406 RangeList* l = f;
00407 unsigned int s = max0-min0+1;
00408 do {
00409 RangeList* n = new (home) RangeList(ri.min(),ri.max(),l,NULL);
00410 l->next(NULL,n);
00411 l = n;
00412 s += ri.width();
00413 ++ri;
00414 } while (ri());
00415 if (fst() != NULL)
00416 fst()->dispose(home,NULL,lst());
00417 fst(f); lst(l);
00418
00419 if (size() == s)
00420 return ME_INT_NONE;
00421 const int min1 = dom.min(); min0 = f->min(); dom.min(min0);
00422 const int max1 = dom.max(); max0 = l->max(); dom.max(max0);
00423 holes = width() - s;
00424 if ((min0 == min1) && (max0 == max1)) {
00425 notify(home,ME_INT_DOM);
00426 return ME_INT_DOM;
00427 }
00428 }
00429 notify(home,ME_INT_BND);
00430 return ME_INT_BND;
00431 }
00432
00433
00434
00435
00436
00437
00438 forceinline IntVarImp*
00439 IntVarImp::copy(Space* home, bool share) {
00440 return copied() ? static_cast<IntVarImp*>(forward())
00441 : perform_copy(home,share);
00442 }
00443 forceinline IntVarImp*
00444 IntVarImp::copy_bool(Space* home, bool share) {
00445 return copied() ? static_cast<IntVarImp*>(forward())
00446 : perform_copy_bool(home,share);
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456 forceinline void
00457 IntVarImp::t_zero_none(Space* home) {
00458 assert((dom.min() == 0) && (dom.max() == 1));
00459 dom.max(0);
00460 notify(home,ME_INT_VAL);
00461 }
00462
00463 forceinline void
00464 IntVarImp::t_one_none(Space* home) {
00465 assert((dom.min() == 0) && (dom.max() == 1));
00466 dom.min(1);
00467 notify(home,ME_INT_VAL);
00468 }
00469
00470
00471
00472
00473
00474
00475
00476 forceinline
00477 IntVarImpFwd::IntVarImpFwd(void) {}
00478 forceinline
00479 IntVarImpFwd::IntVarImpFwd(const IntVarImp* x)
00480 : p(NULL), c(x->ranges_fwd()) {}
00481 forceinline void
00482 IntVarImpFwd::init(const IntVarImp* x) {
00483 p=NULL; c=x->ranges_fwd();
00484 }
00485
00486 forceinline bool
00487 IntVarImpFwd::operator()(void) const {
00488 return c != NULL;
00489 }
00490 forceinline void
00491 IntVarImpFwd::operator++(void) {
00492 const IntVarImp::RangeList* n=c->next(p); p=c; c=n;
00493 }
00494
00495 forceinline int
00496 IntVarImpFwd::min(void) const {
00497 return c->min();
00498 }
00499 forceinline int
00500 IntVarImpFwd::max(void) const {
00501 return c->max();
00502 }
00503 forceinline unsigned int
00504 IntVarImpFwd::width(void) const {
00505 return c->width();
00506 }
00507
00508
00509
00510
00511
00512
00513
00514 forceinline
00515 IntVarImpBwd::IntVarImpBwd(void) {}
00516 forceinline
00517 IntVarImpBwd::IntVarImpBwd(const IntVarImp* x)
00518 : n(NULL), c(x->ranges_bwd()) {}
00519 forceinline void
00520 IntVarImpBwd::init(const IntVarImp* x) {
00521 n=NULL; c=x->ranges_bwd();
00522 }
00523
00524 forceinline bool
00525 IntVarImpBwd::operator()(void) const {
00526 return c != NULL;
00527 }
00528 forceinline void
00529 IntVarImpBwd::operator++(void) {
00530 const IntVarImp::RangeList* p=c->prev(n); n=c; c=p;
00531 }
00532
00533 forceinline int
00534 IntVarImpBwd::min(void) const {
00535 return c->min();
00536 }
00537 forceinline int
00538 IntVarImpBwd::max(void) const {
00539 return c->max();
00540 }
00541 forceinline unsigned int
00542 IntVarImpBwd::width(void) const {
00543 return c->width();
00544 }
00545
00546
00547
00548
00549
00550
00551 template <class I>
00552 forceinline ModEvent
00553 IntVarImp::inter(Space* home, I& i) {
00554 IntVarImpFwd j(this);
00555 Iter::Ranges::Inter<I,IntVarImpFwd> ij(i,j);
00556 return narrow(home,ij);
00557 }
00558
00559 template <class I>
00560 forceinline ModEvent
00561 IntVarImp::minus(Space* home, I& i) {
00562 IntVarImpFwd j(this);
00563 Iter::Ranges::Diff<IntVarImpFwd,I> ij(j,i);
00564 return narrow(home,ij);
00565 }
00566
00567
00568
00569
00570
00571 forceinline void
00572 IntVarImp::subscribe(Space* home, Propagator* p, PropCond pc, bool process) {
00573 IntVarImpBase::subscribe(home,p,pc,dom.min()==dom.max(),process);
00574 }
00575
00576 }}
00577
00578
00579