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 Set {
00043
00044
00045
00046
00047
00048
00049 forceinline
00050 BndSet::BndSet(void) :
00051 first(NULL), last(NULL), _size(0), _card(0) {}
00052
00053 forceinline RangeList*
00054 BndSet::fst(void) const {
00055 return first;
00056 }
00057
00058 forceinline RangeList*
00059 BndSet::lst(void) const {
00060 return last;
00061 }
00062
00063 forceinline void
00064 BndSet::dispose(Space& home) {
00065 if (fst()!=NULL)
00066 fst()->dispose(home,lst());
00067 }
00068
00069 forceinline void
00070 BndSet::fst(RangeList* f) {
00071 first = f;
00072 }
00073
00074 forceinline void
00075 BndSet::lst(RangeList* l) {
00076 last = l;
00077 }
00078
00079 forceinline
00080 BndSet::BndSet(Space& home, int mn, int mx) {
00081 if (mn>mx) {
00082 fst(NULL); lst(NULL); _size = 0;
00083 } else {
00084 RangeList* p =
00085 new (home) RangeList(mn,mx,NULL);
00086 fst(p); lst(p);
00087 _size = static_cast<unsigned int>(mx-mn+1);
00088 }
00089 }
00090
00091 forceinline RangeList*
00092 BndSet::ranges(void) const {
00093 return fst();
00094 }
00095
00096 forceinline unsigned int
00097 BndSet::size(void) const {
00098 return _size;
00099 }
00100
00101 forceinline bool
00102 BndSet::empty(void) const {
00103 return (_size==0);
00104 }
00105
00106 forceinline int
00107 BndSet::min(void) const {
00108 if (fst()==NULL)
00109 return MIN_OF_EMPTY;
00110 else
00111 return fst()->min();
00112 }
00113
00114 forceinline int
00115 BndSet::max(void) const {
00116 if (lst()==NULL)
00117 return MAX_OF_EMPTY;
00118 else
00119 return lst()->max();
00120 }
00121
00122
00123 forceinline int
00124 BndSet::minN(unsigned int n) const {
00125 for (RangeList* c = fst(); c != NULL; c = c->next()) {
00126 if (c->width() > n)
00127 return static_cast<int>(c->min() + n);
00128 n -= c->width();
00129 }
00130 return MIN_OF_EMPTY;
00131 }
00132
00133 forceinline unsigned int
00134 BndSet::card(void) const {
00135 return _card;
00136 }
00137
00138 forceinline void
00139 BndSet::card(unsigned int c) {
00140 _card = c;
00141 }
00142
00143 forceinline void
00144 BndSet::update(Space& home, BndSet& d) {
00145 if (d.fst() == fst())
00146 return;
00147 if (fst() != NULL)
00148 fst()->dispose(home,lst());
00149 _size = d.size();
00150 if (_size == 0) {
00151 fst(NULL); lst(NULL);
00152 return;
00153 }
00154
00155 int n=0;
00156 for (RangeList* c = d.fst(); c != NULL; c = c->next())
00157 n++;
00158
00159 RangeList* r = home.alloc<RangeList>(n);
00160 fst(r); lst(r+n-1);
00161
00162 {
00163 RangeList* c = d.fst();
00164 for (int i=0; i<n; i++) {
00165 r[i].min(c->min());
00166 r[i].max(c->max());
00167 r[i].next(&r[i+1]);
00168 c = c->next();
00169 }
00170 }
00171 r[n-1].next(NULL);
00172 }
00173
00174 template<class I> forceinline bool
00175 BndSet::overwrite(Space& home, I& ri) {
00176
00177 if (!ri()) {
00178
00179 if (fst()==NULL)
00180 return false;
00181 fst()->dispose(home,lst());
00182 _size=0; fst(NULL); lst(NULL);
00183 return true;
00184 }
00185
00186 RangeList* f =
00187 new (home) RangeList(ri.min(),ri.max(),NULL);
00188 RangeList* l = f;
00189 unsigned int s = ri.width();
00190
00191 ++ri;
00192
00193 while (ri()){
00194 RangeList *n = new (home) RangeList(ri.min(),ri.max(),NULL);
00195 l->next(n);
00196 l=n;
00197 s += ri.width();
00198 ++ri;
00199 }
00200
00201 if (fst() != NULL)
00202 fst()->dispose(home,lst());
00203 fst(f); lst(l);
00204
00205
00206
00207 if (size() == s)
00208 return false;
00209
00210 _size = s;
00211 return true;
00212 }
00213
00214 forceinline void
00215 BndSet::become(Space& home, const BndSet& that){
00216 if (fst()!=NULL){
00217 assert(lst()!=NULL);
00218 assert(fst()!= that.fst());
00219 fst()->dispose(home,lst());
00220 }
00221 fst(that.fst());
00222 lst(that.lst());
00223 _size = that.size();
00224 assert(isConsistent());
00225 }
00226
00227 forceinline bool
00228 BndSet::in(int i) const {
00229 for (RangeList* c = fst(); c != NULL; c = c->next()) {
00230 if (c->min() <= i && c->max() >= i)
00231 return true;
00232 if (c->min() > i)
00233 return false;
00234 }
00235 return false;
00236 }
00237
00238
00239
00240
00241
00242
00243 forceinline
00244 BndSetRanges::BndSetRanges(void) {}
00245
00246 forceinline
00247 BndSetRanges::BndSetRanges(const BndSet& s)
00248 : Iter::Ranges::RangeList(s.ranges()) {}
00249
00250 forceinline void
00251 BndSetRanges::init(const BndSet& s) {
00252 Iter::Ranges::RangeList::init(s.ranges());
00253 }
00254
00255
00256
00257
00258
00259
00260 forceinline
00261 GLBndSet::GLBndSet(void) {}
00262
00263 forceinline
00264 GLBndSet::GLBndSet(Space&) {}
00265
00266 forceinline
00267 GLBndSet::GLBndSet(Space& home, int mi, int ma)
00268 : BndSet(home,mi,ma) {}
00269
00270 forceinline
00271 GLBndSet::GLBndSet(Space& home, const IntSet& s)
00272 : BndSet(home,s) {}
00273
00274 forceinline void
00275 GLBndSet::init(Space& home) {
00276 dispose(home);
00277 fst(NULL);
00278 lst(NULL);
00279 _size = 0;
00280 }
00281
00282 forceinline bool
00283 GLBndSet::include(Space& home, int mi, int ma, SetDelta& d) {
00284 assert(ma >= mi);
00285 if (fst()==NULL) {
00286 RangeList* p = new (home) RangeList(mi,ma,NULL);
00287 fst(p);
00288 lst(p);
00289 _size=static_cast<unsigned int>(ma-mi+1);
00290 d._glbMin = mi;
00291 d._glbMax = ma;
00292 return true;
00293 }
00294 bool ret = include_full(home, mi, ma, d);
00295 assert(isConsistent());
00296 return ret;
00297 }
00298
00299 template<class I> bool
00300 GLBndSet::includeI(Space& home, I& i) {
00301 if (!i())
00302 return false;
00303 BndSetRanges j(*this);
00304 Iter::Ranges::Union<BndSetRanges,I> ij(j,i);
00305 bool me = overwrite(home, ij);
00306 assert(isConsistent());
00307 return me;
00308 }
00309
00310
00311
00312
00313
00314
00315
00316 forceinline
00317 LUBndSet::LUBndSet(void) {}
00318
00319 forceinline
00320 LUBndSet::LUBndSet(Space& home)
00321 : BndSet(home,Limits::min,Limits::max) {}
00322
00323 forceinline
00324 LUBndSet::LUBndSet(Space& home, int mi, int ma)
00325 : BndSet(home,mi,ma) {}
00326
00327 forceinline
00328 LUBndSet::LUBndSet(Space& home, const IntSet& s)
00329 : BndSet(home,s) {}
00330
00331 forceinline void
00332 LUBndSet::init(Space& home) {
00333 RangeList *p =
00334 new (home) RangeList(Limits::min,
00335 Limits::max,
00336 NULL);
00337 fst(p);
00338 lst(p);
00339 _size = Limits::card;
00340 }
00341
00342 forceinline bool
00343 LUBndSet::exclude(Space& home, int mi, int ma, SetDelta& d) {
00344 assert(ma >= mi);
00345 if ((mi > max()) || (ma < min())) { return false; }
00346 if (mi <= min() && ma >= max() ) {
00347 d._lubMin = min();
00348 d._lubMax = max();
00349 fst()->dispose(home,lst()); fst(NULL); lst(NULL);
00350 _size=0;
00351 return true;
00352 }
00353 bool ret = exclude_full(home, mi, ma, d);
00354 assert(isConsistent());
00355 return ret;
00356 }
00357
00358 forceinline bool
00359 LUBndSet::intersect(Space& home, int mi, int ma) {
00360 assert(ma >= mi);
00361 if ((mi <= min()) && (ma >= max())) { return false; }
00362 if (_size == 0) return false;
00363 if (ma < min() || mi > max() ) {
00364 fst()->dispose(home,lst()); fst(NULL); lst(NULL);
00365 _size=0;
00366 return true;
00367 }
00368 bool ret = intersect_full(home, mi, ma);
00369 assert(isConsistent());
00370 return ret;
00371 }
00372
00373 template<class I> bool
00374 LUBndSet::intersectI(Space& home, I& i) {
00375 if (fst()==NULL) { return false; }
00376 if (!i()) {
00377 fst()->dispose(home,lst()); fst(NULL); lst(NULL);
00378 _size=0;
00379 return true;
00380 }
00381 BndSetRanges j(*this);
00382 Iter::Ranges::Inter<BndSetRanges,I> ij(j,i);
00383 bool ret = overwrite(home, ij);
00384 assert(isConsistent());
00385 return ret;
00386 }
00387
00388 template<class I> bool
00389 LUBndSet::excludeI(Space& home, I& i) {
00390 if (!i()) { return false; }
00391 BndSetRanges j(*this);
00392 Iter::Ranges::Diff<BndSetRanges,I> ij(j,i);
00393 bool ret = overwrite(home, ij);
00394 assert(isConsistent());
00395 return ret;
00396 }
00397
00398 forceinline void
00399 LUBndSet::excludeAll(Space& home) {
00400 fst()->dispose(home,lst()); fst(NULL); lst(NULL);
00401 _size=0;
00402 }
00403
00404
00405
00406
00407
00408 template<class I>
00409 RangesCompl<I>::RangesCompl(void) {}
00410
00411 template<class I>
00412 RangesCompl<I>::RangesCompl(I& i)
00413 : Iter::Ranges::Compl<Limits::min,
00414 Limits::max,
00415 I>(i) {}
00416
00417 template<class I> void
00418 RangesCompl<I>::init(I& i) {
00419 Iter::Ranges::Compl<Limits::min,
00420 Limits::max,I>::init(i);
00421 }
00422
00423 }}
00424
00425
00426