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

set.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *     Gabor Szokoli <szokoli@gecode.org>
00006  *
00007  *  Contributing authors:
00008  *     Christian Schulte <schulte@gecode.org>
00009  *
00010  *  Copyright:
00011  *     Guido Tack, 2004
00012  *     Christian Schulte, 2004
00013  *     Gabor Szokoli, 2004
00014  *
00015  *  Last modified:
00016  *     $Date: 2008-02-06 18:48:22 +0100 (Wed, 06 Feb 2008) $ by $Author: schulte $
00017  *     $Revision: 6102 $
00018  *
00019  *  This file is part of Gecode, the generic constraint
00020  *  development environment:
00021  *     http://www.gecode.org
00022  *
00023  *  Permission is hereby granted, free of charge, to any person obtaining
00024  *  a copy of this software and associated documentation files (the
00025  *  "Software"), to deal in the Software without restriction, including
00026  *  without limitation the rights to use, copy, modify, merge, publish,
00027  *  distribute, sublicense, and/or sell copies of the Software, and to
00028  *  permit persons to whom the Software is furnished to do so, subject to
00029  *  the following conditions:
00030  *
00031  *  The above copyright notice and this permission notice shall be
00032  *  included in all copies or substantial portions of the Software.
00033  *
00034  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00035  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00036  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00037  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00038  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00039  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00040  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00041  *
00042  */
00043 
00044 namespace Gecode { namespace Set {
00045 
00046   /*
00047    * Creation of new variable implementations
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    * Support for delta information
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    * Copying a variable
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    * Iterator specializations
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    * Dependencies
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 // STATISTICS: set-var