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 namespace Gecode { namespace Set {
00029
00030
00031
00032
00033
00034
00035 forceinline
00036 SetVarImp::SetVarImp(Space* home)
00037 : SetVarImpBase(home), lub(home), glb(home) {
00038 _cardMin = 0;
00039 _cardMax = Limits::Set::card_max;
00040 assert(_cardMax==lub.size());
00041 }
00042
00043 forceinline
00044 SetVarImp::SetVarImp(Space* home,int lbMin,int lbMax,int ubMin,int ubMax,
00045 unsigned int cardMin, unsigned int cardMax)
00046 : SetVarImpBase(home),
00047 lub(home,ubMin,ubMax), glb(home,lbMin,lbMax) {
00048 _cardMin = std::max(cardMin, glb.size() );
00049 _cardMax = std::min(cardMax, lub.size() );
00050 }
00051
00052 forceinline
00053 SetVarImp::SetVarImp(Space* home,
00054 const IntSet& theGlb,int ubMin,int ubMax,
00055 unsigned int cardMin, unsigned int cardMax)
00056 : SetVarImpBase(home),
00057 lub(home,ubMin,ubMax), glb(home,theGlb) {
00058 _cardMin = std::max(cardMin, glb.size() );
00059 _cardMax = std::min(cardMax, lub.size() );
00060 }
00061
00062 forceinline
00063 SetVarImp::SetVarImp(Space* home,
00064 int lbMin,int lbMax,const IntSet& theLub,
00065 unsigned int cardMin, unsigned int cardMax)
00066 : SetVarImpBase(home),
00067 lub(home,theLub), glb(home,lbMin,lbMax) {
00068 _cardMin = std::max(cardMin, glb.size() );
00069 _cardMax = std::min(cardMax, lub.size() );
00070 }
00071
00072 forceinline
00073 SetVarImp::SetVarImp(Space* home,
00074 const IntSet& theGlb,const IntSet& theLub,
00075 unsigned int cardMin, unsigned int cardMax)
00076 : SetVarImpBase(home), lub(home,theLub), glb(home,theGlb) {
00077 _cardMin = std::max(cardMin, glb.size() );
00078 _cardMax = std::min(cardMax, lub.size() );
00079 }
00080
00081
00082 #define GECODE_SET_CHECK_LUB(home,changed) { \
00083 if (changed) \
00084 return processLubChange(home); \
00085 return ME_SET_NONE; \
00086 }
00087
00088 #define GECODE_SET_CHECK_GLB(home,changed) { \
00089 if (changed) \
00090 return processGlbChange(home); \
00091 return ME_SET_NONE; \
00092 }
00093
00094 forceinline bool
00095 SetVarImp::assigned(void) const {
00096 return ( glb.size() == lub.size() );
00097 }
00098
00099 forceinline unsigned int
00100 SetVarImp::cardMin(void) const { return _cardMin; }
00101
00102 forceinline unsigned int
00103 SetVarImp::cardMax(void) const { return _cardMax; }
00104
00105 forceinline bool
00106 SetVarImp::knownIn(int i) const { return (glb.in(i)); }
00107
00108 forceinline bool
00109 SetVarImp::knownOut(int i) const { return !(lub.in(i)); }
00110
00111 forceinline int
00112 SetVarImp::lubMin(void) const { return lub.min(); }
00113
00114 forceinline int
00115 SetVarImp::lubMax(void) const { return lub.max(); }
00116
00117 forceinline int
00118 SetVarImp::lubMinN(int n) const { return lub.minN(n); }
00119
00120 forceinline int
00121 SetVarImp::lubMaxN(int n) const { return lub.maxN(n); }
00122
00123 forceinline int
00124 SetVarImp::glbMin(void) const { return glb.min(); }
00125
00126 forceinline int
00127 SetVarImp::glbMax(void) const { return glb.max(); }
00128
00129 forceinline unsigned int
00130 SetVarImp::glbSize() const { return glb.size(); }
00131
00132 forceinline unsigned int
00133 SetVarImp::lubSize() const { return lub.size(); }
00134
00135
00136 forceinline bool
00137 SetVarImp::boundsConsistent() const {
00138
00139
00140 BndSetRanges ub(lub);
00141 BndSetRanges lb(glb);
00142 return (Iter::Ranges::subset(lb,ub)) ;
00143 }
00144
00145 forceinline ModEvent
00146 SetVarImp::cardMin(Space* home,unsigned int newMin) {
00147 if (_cardMin >= newMin)
00148 return ME_SET_NONE;
00149 _cardMin=newMin;
00150 if (_cardMin > _cardMax)
00151 return ME_SET_FAILED;
00152 return cardMin_full(home, newMin);
00153 }
00154
00155 forceinline ModEvent
00156 SetVarImp::cardMax(Space* home,unsigned int newMax) {
00157 if (_cardMax <= newMax)
00158 return ME_SET_NONE;
00159 _cardMax=newMax;
00160 if (_cardMin > _cardMax)
00161 return ME_SET_FAILED;
00162 return cardMax_full(home, newMax);
00163 }
00164
00165 template <class I> ModEvent
00166 SetVarImp::excludeI(Space* home, I& iterator) {
00167 if (assigned()) {
00168 BndSetRanges ubi(lub);
00169 Iter::Ranges::Inter<BndSetRanges,I> probe(ubi,iterator);
00170 return probe() ? ME_SET_FAILED : ME_SET_NONE;
00171 }
00172 GECODE_SET_CHECK_LUB(home, lub.excludeI(home, iterator));
00173 }
00174
00175 template <class I> forceinline ModEvent
00176 SetVarImp::intersectI(Space* home, I& iterator) {
00177 if (assigned()) {
00178 BndSetRanges ubi(lub);
00179 Iter::Ranges::Diff<BndSetRanges,I> probe(ubi,iterator);
00180 return probe() ? ME_SET_FAILED : ME_SET_NONE;
00181 }
00182 GECODE_SET_CHECK_LUB(home, lub.intersectI(home, iterator));
00183 }
00184
00185 forceinline ModEvent
00186 SetVarImp::intersect(Space* home,int i, int j) {
00187 bool changed =
00188 lub.exclude(home, Limits::Set::int_min, i-1);
00189 changed |=
00190 lub.exclude(home, j+1, Limits::Set::int_max);
00191 if (changed)
00192 return processLubChange(home);
00193 return ME_SET_NONE;
00194 }
00195
00196 forceinline ModEvent
00197 SetVarImp::intersect(Space* home,int i) {
00198 return intersect(home, i, i);
00199 }
00200
00201 template <class I> forceinline ModEvent
00202 SetVarImp::includeI(Space* home, I& iterator) {
00203 if (assigned()) {
00204 BndSetRanges lbi(glb);
00205 Iter::Ranges::Diff<I,BndSetRanges>
00206 probe(iterator,lbi);
00207 return probe() ? ME_SET_FAILED : ME_SET_NONE;
00208 }
00209 GECODE_SET_CHECK_GLB(home, glb.includeI(home, iterator));
00210 }
00211
00212 forceinline ModEvent
00213 SetVarImp::include(Space* home, int i) {
00214 GECODE_SET_CHECK_GLB(home,glb.include(home, i, i)) ;
00215 }
00216
00217 forceinline ModEvent
00218 SetVarImp::include(Space* home, int i, int j) {
00219 GECODE_SET_CHECK_GLB(home,glb.include(home,i,j)) ;
00220 }
00221
00222 forceinline ModEvent
00223 SetVarImp::exclude(Space* home,int i) {
00224 GECODE_SET_CHECK_LUB(home,lub.exclude(home,i,i));
00225 }
00226
00227 forceinline ModEvent
00228 SetVarImp::exclude(Space* home,int i, int j) {
00229 GECODE_SET_CHECK_LUB(home,lub.exclude(home,i,j)) ;
00230 }
00231
00232 forceinline ModEvent
00233 SetVarImp::checkGlbCardAssigned(Space* home,ModEvent me){
00234 if (_cardMax > glb.size())
00235 return me;
00236 if (_cardMax == glb.size()) {
00237 lub.linkTo(home,glb);
00238 _cardMin=_cardMax;
00239 return ME_SET_VAL;
00240 }
00241 return ME_SET_FAILED;
00242 }
00243
00244 forceinline ModEvent
00245 SetVarImp::checkLubCardAssigned(Space* home,ModEvent me){
00246 if (_cardMin < lub.size())
00247 return me;
00248 if (_cardMin == lub.size()) {
00249 glb.linkTo(home,lub);
00250 _cardMax=_cardMin;
00251 return ME_SET_VAL;
00252 }
00253 return ME_SET_FAILED;
00254 }
00255
00256
00257
00258
00259
00260
00261 forceinline SetVarImp*
00262 SetVarImp::copy(Space* home, bool share) {
00263 return copied() ?
00264 static_cast<SetVarImp*>(forward()) :
00265 perform_copy(home,share);
00266 }
00267
00268
00269
00270
00271
00272
00281 template <>
00282 class LubRanges<SetVarImp*> : public BndSetRanges {
00283 public:
00285
00286
00287 LubRanges(void);
00289 LubRanges(const SetVarImp*);
00291 void init(const SetVarImp*);
00293 };
00294
00295 forceinline
00296 LubRanges<SetVarImp*>::LubRanges(void) {}
00297
00298 forceinline
00299 LubRanges<SetVarImp*>::LubRanges(const SetVarImp* x)
00300 : BndSetRanges(x->lub) {}
00301
00302 forceinline void
00303 LubRanges<SetVarImp*>::init(const SetVarImp* x) {
00304 BndSetRanges::init(x->lub);
00305 }
00306
00315 template <>
00316 class GlbRanges<SetVarImp*> : public BndSetRanges {
00317 public:
00319
00320
00321 GlbRanges(void);
00323 GlbRanges(const SetVarImp* x);
00325 void init(const SetVarImp*);
00327 };
00328
00329 forceinline
00330 GlbRanges<SetVarImp*>::GlbRanges(void) {}
00331
00332 forceinline
00333 GlbRanges<SetVarImp*>::GlbRanges(const SetVarImp* x)
00334 : BndSetRanges(x->glb) {}
00335
00336 forceinline void
00337 GlbRanges<SetVarImp*>::init(const SetVarImp* x) {
00338 BndSetRanges::init(x->glb);
00339 }
00340
00341
00342
00343
00344
00345
00346
00347 forceinline void
00348 SetVarImp::subscribe(Space* home, Propagator* p, PropCond pc, bool process) {
00349 SetVarImpBase::subscribe(home,p,pc,assigned(),process);
00350 }
00351
00352 }}
00353
00354
00355
00356