Generated on Mon Aug 25 11:35:36 2008 for Gecode by doxygen 1.5.6

int.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Contributing authors:
00007  *     Guido Tack <tack@gecode.org>
00008  *
00009  *  Copyright:
00010  *     Christian Schulte, 2003
00011  *     Guido Tack, 2004
00012  *
00013  *  Last modified:
00014  *     $Date: 2008-01-23 09:24:50 +0100 (Wed, 23 Jan 2008) $ by $Author: tack $
00015  *     $Revision: 5946 $
00016  *
00017  *  This file is part of Gecode, the generic constraint
00018  *  development environment:
00019  *     http://www.gecode.org
00020  *
00021  *  Permission is hereby granted, free of charge, to any person obtaining
00022  *  a copy of this software and associated documentation files (the
00023  *  "Software"), to deal in the Software without restriction, including
00024  *  without limitation the rights to use, copy, modify, merge, publish,
00025  *  distribute, sublicense, and/or sell copies of the Software, and to
00026  *  permit persons to whom the Software is furnished to do so, subject to
00027  *  the following conditions:
00028  *
00029  *  The above copyright notice and this permission notice shall be
00030  *  included in all copies or substantial portions of the Software.
00031  *
00032  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00033  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00034  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00035  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00036  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00037  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00038  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00039  *
00040  */
00041 
00042 namespace Gecode { namespace Int {
00043 
00044   /*
00045    * Range lists
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    * Mainitaining range lists for variable domain
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    * Creation of new variable implementations
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    * Operations on integer variable implementations
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    * Tests
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    * Accessing rangelists for iteration
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    * Support for delta information
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    * Tell operations (to be inlined: performing bounds checks first)
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    * Forward range iterator for rangelists
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    * Backward range iterator for rangelists
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    * Iterator-based domain operations
00492    *
00493    */
00494   template <class I>
00495   forceinline ModEvent
00496   IntVarImp::narrow_r(Space* home, I& ri, bool depends) {
00497     // Is new domain empty?
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     // Is new domain range?
00508     if (!ri()) {
00509       // Remove possible rangelist (if it was not a range, the domain
00510       // must have been narrowed!)
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       // Construct new rangelist
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       // Check for modification
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       // Set up two sentinel elements
00551       RangeList f, l;
00552       // Put all ranges between sentinels
00553       f.prevnext(NULL,fst()); l.prevnext(lst(),NULL);
00554       fst()->prev(NULL,&f);   lst()->next(NULL,&l);
00555 
00556       // Number of values removed (potential holes)
00557       unsigned int h = 0;
00558       // The previous range
00559       RangeList* p = &f;
00560       // The current range
00561       RangeList* r = f.next(NULL);
00562 
00563       while (true) {
00564         assert((r != &f) && (r != &l));
00565         if (r->max() < min0) {
00566           // Entire range removed
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           // Range unchanged
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           // Range might have been split into many small ranges
00584           assert((r->min() <= min0) && (max0 <= r->max()));
00585           h += r->width();
00586           int end = r->max();
00587           // Copy first range
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       // Remove remaining ranges
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       // New first and last ranges
00624       RangeList* fn = f.next(NULL);
00625       RangeList* ln = l.prev(NULL);
00626 
00627       // All ranges pruned?
00628       assert(fn != &l);
00629 
00630       // Only a single range left?
00631       assert(fn != ln);
00632 
00633       // The number of removed values
00634       holes += h;
00635       // Unlink sentinel ranges
00636       fn->prev(&f,NULL); ln->next(&l,NULL);
00637       // How many values where removed at the bounds
00638       unsigned int b = (static_cast<unsigned int>(fn->min()-dom.min()) +
00639                         static_cast<unsigned int>(dom.max()-ln->max()));
00640       // Set new first and last ranges
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     // Skip all ranges that are too small
00679     while (i() && (i.max() < dom.min())) 
00680       ++i;
00681 
00682     // Is there no range left or all are too large?
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     // Set up two sentinel elements
00690     RangeList f, l;
00691     // Put all ranges between sentinels
00692     if (range()) {
00693       // Create a new rangelist just for simplicity
00694       RangeList* n = new (home) RangeList(min(),max(),&f,&l);
00695       f.prevnext(NULL,n); l.prevnext(n,NULL);
00696     } else {
00697       // Link the two sentinel elements
00698       f.prevnext(NULL,fst()); l.prevnext(lst(),NULL);
00699       fst()->prev(NULL,&f);   lst()->next(NULL,&l);
00700     }
00701 
00702     // Number of values removed (potential holes)
00703     unsigned int h = 0;
00704     // The previous range
00705     RangeList* p = &f;
00706     // The current range
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         // r is included in i: remove entire range r
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         // i is included in r: create new range before the current one
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         // i ends before r: adjust minimum of r
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         // r ends before i: adjust maximum of r
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     // New first and last ranges
00760     RangeList* fn = f.next(NULL);
00761     RangeList* ln = l.prev(NULL);
00762 
00763     // All ranges pruned?
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     // Only a single range left?
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     // The number of removed values
00784     holes += h;
00785     // Unlink sentinel ranges
00786     fn->prev(&f,NULL); ln->next(&l,NULL);
00787     // How many values where removed at the bounds
00788     b = (static_cast<unsigned int>(fn->min()-dom.min()) +
00789          static_cast<unsigned int>(dom.max()-ln->max()));
00790     // Set new first and last ranges
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     // Skip all values that are too small
00834     while (i() && (i.val() < dom.min())) 
00835       ++i;
00836 
00837     // Is there no value left or all are too large?
00838     if (!i() || (i.val() > dom.max()))
00839       return ME_INT_NONE;
00840 
00841     int v = i.val();
00842     // Skip values that are the same
00843     do {
00844       ++i;
00845     } while (i() && (i.val() == v));
00846 
00847     // Is there only a single value to be pruned?
00848     if (!i() || (i.val() > dom.max()))
00849       return nq_full(home,v);
00850 
00851     // Set up two sentinel elements
00852     RangeList f, l;
00853     // Put all ranges between sentinels
00854     if (range()) {
00855       // Create a new rangelist just for simplicity
00856       RangeList* n = new (home) RangeList(min(),max(),&f,&l);
00857       f.prevnext(NULL,n); l.prevnext(n,NULL);
00858     } else {
00859       // Link the two sentinel elements
00860       f.prevnext(NULL,fst()); l.prevnext(lst(),NULL);
00861       fst()->prev(NULL,&f);   lst()->next(NULL,&l);
00862     }
00863 
00864     // Number of values removed (potential holes)
00865     unsigned int h = 0;
00866     // The previous range
00867     RangeList* p = &f;
00868     // The current range
00869     RangeList* r = f.next(NULL);
00870 
00871     while (true) {
00872       assert((r != &f) && (r != &l));
00873       if (v > r->max()) {
00874         // Move to next range
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           // Remove range
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           // Create new range before the current one
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         // Move to next value
00907         v = i.val(); ++i;
00908       }
00909     }
00910     assert((r == &l) || !i());
00911 
00912     // New first and last ranges
00913     RangeList* fn = f.next(NULL);
00914     RangeList* ln = l.prev(NULL);
00915 
00916     // All ranges pruned?
00917     if (fn == &l) {
00918       fst(NULL); lst(NULL); holes=0;
00919       return ME_INT_FAILED;
00920     }
00921 
00922     IntDelta d;
00923 
00924     // Only a single range left?
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     // The number of removed values
00938     holes += h;
00939     // Unlink sentinel ranges
00940     fn->prev(&f,NULL); ln->next(&l,NULL);
00941     // How many values where removed at the bounds
00942     unsigned int b = (static_cast<unsigned int>(fn->min()-dom.min()) +
00943                       static_cast<unsigned int>(dom.max()-ln->max()));
00944     // Set new first and last ranges
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    * Copying a variable
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    * Dependencies
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 // STATISTICS: int-var