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
00043
00044 namespace Gecode { namespace Set {
00045
00046
00047
00048
00049
00050
00051 forceinline
00052 SetVarImp::SetVarImp(Space* home)
00053 : SetVarImpBase(home), lub(home), glb(home) {
00054 _cardMin = 0;
00055 _cardMax = Limits::card;
00056 assert(_cardMax==lub.size());
00057 }
00058
00059 forceinline
00060 SetVarImp::SetVarImp(Space* home,int lbMin,int lbMax,int ubMin,int ubMax,
00061 unsigned int cardMin, unsigned int cardMax)
00062 : SetVarImpBase(home),
00063 lub(home,ubMin,ubMax), glb(home,lbMin,lbMax) {
00064 _cardMin = std::max(cardMin, glb.size() );
00065 _cardMax = std::min(cardMax, lub.size() );
00066 }
00067
00068 forceinline
00069 SetVarImp::SetVarImp(Space* home,
00070 const IntSet& theGlb,int ubMin,int ubMax,
00071 unsigned int cardMin, unsigned int cardMax)
00072 : SetVarImpBase(home),
00073 lub(home,ubMin,ubMax), glb(home,theGlb) {
00074 _cardMin = std::max(cardMin, glb.size() );
00075 _cardMax = std::min(cardMax, lub.size() );
00076 }
00077
00078 forceinline
00079 SetVarImp::SetVarImp(Space* home,
00080 int lbMin,int lbMax,const IntSet& theLub,
00081 unsigned int cardMin, unsigned int cardMax)
00082 : SetVarImpBase(home),
00083 lub(home,theLub), glb(home,lbMin,lbMax) {
00084 _cardMin = std::max(cardMin, glb.size() );
00085 _cardMax = std::min(cardMax, lub.size() );
00086 }
00087
00088 forceinline
00089 SetVarImp::SetVarImp(Space* home,
00090 const IntSet& theGlb,const IntSet& theLub,
00091 unsigned int cardMin, unsigned int cardMax)
00092 : SetVarImpBase(home), lub(home,theLub), glb(home,theGlb) {
00093 _cardMin = std::max(cardMin, glb.size() );
00094 _cardMax = std::min(cardMax, lub.size() );
00095 }
00096
00097
00098 forceinline bool
00099 SetVarImp::assigned(void) const {
00100 return ( glb.size() == lub.size() );
00101 }
00102
00103 forceinline unsigned int
00104 SetVarImp::cardMin(void) const { return _cardMin; }
00105
00106 forceinline unsigned int
00107 SetVarImp::cardMax(void) const { return _cardMax; }
00108
00109 forceinline bool
00110 SetVarImp::knownIn(int i) const { return (glb.in(i)); }
00111
00112 forceinline bool
00113 SetVarImp::knownOut(int i) const { return !(lub.in(i)); }
00114
00115 forceinline int
00116 SetVarImp::lubMin(void) const { return lub.min(); }
00117
00118 forceinline int
00119 SetVarImp::lubMax(void) const { return lub.max(); }
00120
00121 forceinline int
00122 SetVarImp::lubMinN(int n) const { return lub.minN(n); }
00123
00124 forceinline int
00125 SetVarImp::glbMin(void) const { return glb.min(); }
00126
00127 forceinline int
00128 SetVarImp::glbMax(void) const { return glb.max(); }
00129
00130 forceinline unsigned int
00131 SetVarImp::glbSize() const { return glb.size(); }
00132
00133 forceinline unsigned int
00134 SetVarImp::lubSize() const { return lub.size(); }
00135
00136
00137
00138
00139
00140 forceinline ModEvent
00141 SetVarImp::modevent(const Delta* d) {
00142 return d->modevent();
00143 }
00144 forceinline int
00145 SetVarImp::glbMin(const Delta* d) const {
00146 return static_cast<const SetDelta*>(d)->glbMin();
00147 }
00148 forceinline int
00149 SetVarImp::glbMax(const Delta* d) const {
00150 return static_cast<const SetDelta*>(d)->glbMax();
00151 }
00152 forceinline bool
00153 SetVarImp::glbAny(const Delta* d) const {
00154 return static_cast<const SetDelta*>(d)->glbAny();
00155 }
00156 forceinline int
00157 SetVarImp::lubMin(const Delta* d) const {
00158 return static_cast<const SetDelta*>(d)->lubMin();
00159 }
00160 forceinline int
00161 SetVarImp::lubMax(const Delta* d) const {
00162 return static_cast<const SetDelta*>(d)->lubMax();
00163 }
00164 forceinline bool
00165 SetVarImp::lubAny(const Delta* d) const {
00166 return static_cast<const SetDelta*>(d)->lubAny();
00167 }
00168
00169 forceinline ModEvent
00170 SetVarImp::cardMin(Space* home,unsigned int newMin) {
00171 if (_cardMin >= newMin)
00172 return ME_SET_NONE;
00173 if (newMin > _cardMax)
00174 return ME_SET_FAILED;
00175 _cardMin=newMin;
00176 return cardMin_full(home);
00177 }
00178
00179 forceinline ModEvent
00180 SetVarImp::cardMax(Space* home,unsigned int newMax) {
00181 if (_cardMax <= newMax)
00182 return ME_SET_NONE;
00183 if (_cardMin > newMax)
00184 return ME_SET_FAILED;
00185 _cardMax=newMax;
00186 return cardMax_full(home);
00187 }
00188
00189 forceinline ModEvent
00190 SetVarImp::intersect(Space* home,int i, int j) {
00191 BndSetRanges lb(glb);
00192 Iter::Ranges::Singleton s(i,j);
00193 Iter::Ranges::Diff<BndSetRanges, Iter::Ranges::Singleton> probe(lb, s);
00194 if (probe())
00195 return ME_SET_FAILED;
00196 if (assigned())
00197 return ME_SET_NONE;
00198 int oldMin = lub.min();
00199 int oldMax = lub.max();
00200 if (lub.intersect(home, i, j)) {
00201 SetDelta d;
00202 if (i == oldMin) {
00203 d._lubMin = lub.max()+1;
00204 d._lubMax = oldMax;
00205 } else if (j == oldMax) {
00206 d._lubMin = oldMin;
00207 d._lubMax = lub.min()-1;
00208 }
00209 return processLubChange(home, d);
00210 }
00211 return ME_SET_NONE;
00212 }
00213
00214 forceinline ModEvent
00215 SetVarImp::intersect(Space* home,int i) {
00216 return intersect(home, i, i);
00217 }
00218
00219 template <class I>
00220 inline ModEvent
00221 SetVarImp::intersectI(Space* home, I& iterator) {
00222 if (assigned()) {
00223 BndSetRanges lbi(glb);
00224 Iter::Ranges::Diff<BndSetRanges,I> probe(lbi,iterator);
00225 if (probe())
00226 return ME_SET_FAILED;
00227 return ME_SET_NONE;
00228 }
00229 if (!iterator()) {
00230 if (_cardMin > 0)
00231 return ME_SET_FAILED;
00232 _cardMax = 0;
00233 SetDelta d(1, 0, lub.min(), lub.max());
00234 lub.excludeAll(home);
00235 return notify(home, ME_SET_VAL, &d);
00236 }
00237 int mi=iterator.min();
00238 int ma=iterator.max();
00239 ++iterator;
00240 if (iterator())
00241 return intersectI_full(home, mi, ma, iterator);
00242 else
00243 return intersect(home, mi, ma);
00244 }
00245
00246 template <class I>
00247 ModEvent
00248 SetVarImp::intersectI_full(Space* home, int mi, int ma, I& iterator) {
00249 Iter::Ranges::SingletonAppend<I> si(mi,ma,iterator);
00250 if (lub.intersectI(home, si)) {
00251 BndSetRanges ub(lub);
00252 BndSetRanges lb(glb);
00253 if (!Iter::Ranges::subset(lb,ub)) {
00254 glb.become(home, lub);
00255 _cardMin = glb.size();
00256 _cardMax = glb.size();
00257 return ME_SET_FAILED;
00258 }
00259 ModEvent me = ME_SET_LUB;
00260 if (_cardMax > lub.size()) {
00261 _cardMax = lub.size();
00262 if (_cardMin > _cardMax) {
00263 glb.become(home, lub);
00264 _cardMin = glb.size();
00265 _cardMax = glb.size();
00266 return ME_SET_FAILED;
00267 }
00268 me = ME_SET_CLUB;
00269 }
00270 if (_cardMax == lub.size() && _cardMin == _cardMax) {
00271 glb.become(home, lub);
00272 me = ME_SET_VAL;
00273 }
00274 SetDelta d;
00275 return notify(home, me, &d);
00276 }
00277 return ME_SET_NONE;
00278 }
00279
00280 forceinline ModEvent
00281 SetVarImp::include(Space* home, int i, int j) {
00282 BndSetRanges ub(lub);
00283 Iter::Ranges::Singleton sij(i,j);
00284 if (!Iter::Ranges::subset(sij,ub)) {
00285 return ME_SET_FAILED;
00286 }
00287 SetDelta d;
00288 if (glb.include(home, i, j, d))
00289 return processGlbChange(home, d);
00290 return ME_SET_NONE;
00291 }
00292
00293 forceinline ModEvent
00294 SetVarImp::include(Space* home, int i) {
00295 return include(home, i, i);
00296 }
00297
00298 template <class I> forceinline ModEvent
00299 SetVarImp::includeI(Space* home, I& iterator) {
00300 if (!iterator()) {
00301 return ME_SET_NONE;
00302 }
00303 if (assigned()) {
00304 BndSetRanges lbi(glb);
00305 Iter::Ranges::Diff<I,BndSetRanges>
00306 probe(iterator,lbi);
00307 return probe() ? ME_SET_FAILED : ME_SET_NONE;
00308 }
00309 int mi=iterator.min();
00310 int ma=iterator.max();
00311 ++iterator;
00312 if (iterator())
00313 return includeI_full(home, mi, ma, iterator);
00314 else
00315 return include(home, mi, ma);
00316 }
00317
00318 template <class I>
00319 ModEvent
00320 SetVarImp::includeI_full(Space* home, int mi, int ma, I& iterator) {
00321 Iter::Ranges::SingletonAppend<I> si(mi,ma,iterator);
00322 if (glb.includeI(home, si)) {
00323 BndSetRanges ub(lub);
00324 BndSetRanges lb(glb);
00325 if (!Iter::Ranges::subset(lb,ub)) {
00326 glb.become(home, lub);
00327 _cardMin = glb.size();
00328 _cardMax = glb.size();
00329 return ME_SET_FAILED;
00330 }
00331 ModEvent me = ME_SET_GLB;
00332 if (_cardMin < glb.size()) {
00333 _cardMin = glb.size();
00334 if (_cardMin > _cardMax) {
00335 glb.become(home, lub);
00336 _cardMin = glb.size();
00337 _cardMax = glb.size();
00338 return ME_SET_FAILED;
00339 }
00340 me = ME_SET_CGLB;
00341 }
00342 if (_cardMin == glb.size() && _cardMin == _cardMax) {
00343 lub.become(home, glb);
00344 me = ME_SET_VAL;
00345 }
00346 SetDelta d;
00347 return notify(home, me, &d);
00348 }
00349 return ME_SET_NONE;
00350 }
00351
00352 forceinline ModEvent
00353 SetVarImp::exclude(Space* home, int i, int j) {
00354 Iter::Ranges::Singleton sij(i,j);
00355 BndSetRanges lb(glb);
00356 Iter::Ranges::Inter<Iter::Ranges::Singleton,BndSetRanges> probe(sij,lb);
00357 if (probe())
00358 return ME_SET_FAILED;
00359 SetDelta d;
00360 if (lub.exclude(home, i, j, d))
00361 return processLubChange(home, d);
00362 return ME_SET_NONE;
00363 }
00364
00365 forceinline ModEvent
00366 SetVarImp::exclude(Space* home, int i) {
00367 return exclude(home, i, i);
00368 }
00369
00370 template <class I>
00371 inline ModEvent
00372 SetVarImp::excludeI(Space* home, I& iterator) {
00373 if (!iterator())
00374 return ME_SET_NONE;
00375 if (assigned()) {
00376 BndSetRanges ubi(lub);
00377 Iter::Ranges::Inter<BndSetRanges,I> probe(ubi,iterator);
00378 return probe() ? ME_SET_FAILED : ME_SET_NONE;
00379 }
00380 int mi=iterator.min();
00381 int ma=iterator.max();
00382 ++iterator;
00383 if (iterator())
00384 return excludeI_full(home, mi, ma, iterator);
00385 else
00386 return exclude(home, mi, ma);
00387 }
00388
00389 template <class I>
00390 ModEvent
00391 SetVarImp::excludeI_full(Space* home, int mi, int ma, I& iterator) {
00392 Iter::Ranges::SingletonAppend<I> si(mi,ma,iterator);
00393 if (lub.excludeI(home, si)) {
00394 BndSetRanges ub(lub);
00395 BndSetRanges lb(glb);
00396 if (!Iter::Ranges::subset(lb,ub)) {
00397 glb.become(home, lub);
00398 _cardMin = glb.size();
00399 _cardMax = glb.size();
00400 return ME_SET_FAILED;
00401 }
00402 ModEvent me = ME_SET_LUB;
00403 if (_cardMax > lub.size()) {
00404 _cardMax = lub.size();
00405 if (_cardMin > _cardMax) {
00406 glb.become(home, lub);
00407 _cardMin = glb.size();
00408 _cardMax = glb.size();
00409 return ME_SET_FAILED;
00410 }
00411 me = ME_SET_CLUB;
00412 }
00413 if (_cardMax == lub.size() && _cardMin == _cardMax) {
00414 glb.become(home, lub);
00415 me = ME_SET_VAL;
00416 }
00417 SetDelta d;
00418 return notify(home, me, &d);
00419 }
00420 return ME_SET_NONE;
00421 }
00422
00423
00424
00425
00426
00427
00428 forceinline SetVarImp*
00429 SetVarImp::copy(Space* home, bool share) {
00430 return copied() ?
00431 static_cast<SetVarImp*>(forward()) :
00432 perform_copy(home,share);
00433 }
00434
00435
00436
00437
00438
00439
00448 template <>
00449 class LubRanges<SetVarImp*> : public BndSetRanges {
00450 public:
00452
00453
00454 LubRanges(void);
00456 LubRanges(const SetVarImp*);
00458 void init(const SetVarImp*);
00460 };
00461
00462 forceinline
00463 LubRanges<SetVarImp*>::LubRanges(void) {}
00464
00465 forceinline
00466 LubRanges<SetVarImp*>::LubRanges(const SetVarImp* x)
00467 : BndSetRanges(x->lub) {}
00468
00469 forceinline void
00470 LubRanges<SetVarImp*>::init(const SetVarImp* x) {
00471 BndSetRanges::init(x->lub);
00472 }
00473
00482 template <>
00483 class GlbRanges<SetVarImp*> : public BndSetRanges {
00484 public:
00486
00487
00488 GlbRanges(void);
00490 GlbRanges(const SetVarImp* x);
00492 void init(const SetVarImp*);
00494 };
00495
00496 forceinline
00497 GlbRanges<SetVarImp*>::GlbRanges(void) {}
00498
00499 forceinline
00500 GlbRanges<SetVarImp*>::GlbRanges(const SetVarImp* x)
00501 : BndSetRanges(x->glb) {}
00502
00503 forceinline void
00504 GlbRanges<SetVarImp*>::init(const SetVarImp* x) {
00505 BndSetRanges::init(x->glb);
00506 }
00507
00508
00509
00510
00511
00512
00513 forceinline void
00514 SetVarImp::subscribe(Space* home, Propagator* p, PropCond pc, bool process) {
00515 SetVarImpBase::subscribe(home,p,pc,assigned(),process);
00516 }
00517 forceinline void
00518 SetVarImp::cancel(Space* home, Propagator* p, PropCond pc) {
00519 SetVarImpBase::cancel(home,p,pc,assigned());
00520 }
00521 forceinline void
00522 SetVarImp::subscribe(Space* home, Advisor* a) {
00523 SetVarImpBase::subscribe(home,a,assigned());
00524 }
00525 forceinline void
00526 SetVarImp::cancel(Space* home, Advisor* a) {
00527 SetVarImpBase::cancel(home,a,assigned());
00528 }
00529
00530 }}
00531
00532