Generated on Wed Nov 1 15:04:40 2006 for Gecode by doxygen 1.4.5

imp.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Guido Tack <tack@gecode.org>
00004  *     Gabor Szokoli <szokoli@gecode.org>
00005  *
00006  *  Contributing authors:
00007  *     Christian Schulte <schulte@gecode.org>
00008  *
00009  *  Copyright:
00010  *     Guido Tack, 2004
00011  *     Christian Schulte, 2004
00012  *     Gabor Szokoli, 2004
00013  *
00014  *  Last modified:
00015  *     $Date: 2006-08-25 10:43:21 +0200 (Fri, 25 Aug 2006) $ by $Author: schulte $
00016  *     $Revision: 3568 $
00017  *
00018  *  This file is part of Gecode, the generic constraint
00019  *  development environment:
00020  *     http://www.gecode.org
00021  *
00022  *  See the file "LICENSE" for information on usage and
00023  *  redistribution of this file, and for a
00024  *     DISCLAIMER OF ALL WARRANTIES.
00025  *
00026  */
00027 
00028 namespace Gecode { namespace Set {
00029 
00030   /*
00031    * Creation of new variable implementations
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   //Determines consistency of lower and upper bounds, signals fail
00136   forceinline bool
00137   SetVarImp::boundsConsistent() const {
00138     //Don't optimise fail at a cost to the common case!
00139     //  if (lubSize()<glbSize()){ return false; }
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    * Copying a variable
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    * Iterator specializations
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    * Subscribing to variables
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 // STATISTICS: set-var
00355 
00356