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

cpltset.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Patrick Pekczynski <pekczynski@ps.uni-sb.de>
00005  *
00006  *  Copyright:
00007  *     Patrick Pekczynski, 2006
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-02-06 18:48:22 +0100 (Wed, 06 Feb 2008) $ by $Author: schulte $
00011  *     $Revision: 6102 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 namespace Gecode { namespace CpltSet {
00039 
00040   inline void 
00041   CpltSetVarImp::printdom(void) const {
00042     manager.print_set(domain);
00043   }
00044 
00045   forceinline unsigned int 
00046   CpltSetVarImp::tableWidth(void) const { return max - min + 1; }
00047 
00048   inline bdd
00049   CpltSetVarImp::element(int i) const { 
00050     return manager.bddpos(_offset + i); 
00051   }
00052 
00053   inline bdd
00054   CpltSetVarImp::elementNeg(int i) const {
00055     return manager.negbddpos(_offset + i);
00056   }
00057 
00058 
00059   inline bdd 
00060   CpltSetVarImp::dom(void) const {
00061     return domain;
00062   }
00063 
00064   forceinline unsigned int
00065   CpltSetVarImp::offset(void) const { return _offset; }
00066 
00067   forceinline int
00068   CpltSetVarImp::initialLubMin(void) const { return min; }
00069 
00070   forceinline int
00071   CpltSetVarImp::initialLubMax(void) const { return max; }
00072 
00073   inline unsigned int 
00074   CpltSetVarImp::cardMin(void) const {
00075     if (manager.ctrue(domain)) { return 0; }
00076     bdd d = domain;
00077     int l = 0;
00078     int u = 0;
00079     getcardbounds(d, l, u);
00080     return l;
00081   }
00082 
00083   inline unsigned int 
00084   CpltSetVarImp::cardMax(void) const {
00085     if (manager.ctrue(domain)) { return tableWidth(); }
00086     bdd d = domain;
00087     int l = 0;
00088     int u = 0;
00089     getcardbounds(d, l, u);
00090     return u;
00091   }
00092 
00093   template <class I> 
00094   ModEvent 
00095   CpltSetVarImp::excludeI(Space* home, I& i) {
00096     // we can only exclude what intersects the min and max element of the variable
00097     Iter::Ranges::Singleton s(min, max);
00098     Iter::Ranges::Inter<Iter::Ranges::Singleton, I> inter(s, i);
00099   
00100     if (!inter()) 
00101       return ME_CPLTSET_NONE;
00102   
00103     bdd not_lub = bdd_true();
00104     Iter::Ranges::ToValues<
00105       Iter::Ranges::Inter<Iter::Ranges::Singleton, I>
00106       > val(inter);
00107 
00108     Iter::Ranges::ValCache<
00109       Iter::Ranges::ToValues<
00110       Iter::Ranges::Inter<Iter::Ranges::Singleton, I> >
00111       > cache(val);
00112   
00113     for (cache.last(); cache(); --cache) {
00114       int v = cache.min();
00115       not_lub &= elementNeg(v - min);
00116     }
00117     return intersect(home, not_lub);
00118   }
00119 
00120   inline ModEvent 
00121   CpltSetVarImp::include(Space* home, int v) {
00122     return include(home, v, v);
00123   }
00124 
00125   inline ModEvent 
00126   CpltSetVarImp::exclude(Space* home, int v) {
00127     return exclude(home, v, v);
00128   }
00129 
00130   template <class I> 
00131   ModEvent 
00132   CpltSetVarImp::includeI(Space* home, I& i) {
00133     if (!i()) 
00134       return ME_CPLTSET_NONE;
00135 
00136     bdd in_glb  = bdd_true();
00137     Iter::Ranges::ToValues<I> val(i);
00138     Iter::Ranges::ValCache<Iter::Ranges::ToValues<I> > cache(val);
00139 
00140     for (cache.last(); cache(); --cache) {
00141       int v = cache.min();
00142       if (v < min || max < v) 
00143         return ME_CPLTSET_FAILED;
00144       in_glb &= element(v - min);
00145     }
00146     return intersect(home, in_glb);  
00147   }
00148 
00149   inline ModEvent
00150   CpltSetVarImp::nq(Space* home, int v) { return nq(home, v, v); }
00151 
00152   template <class I>
00153   ModEvent
00154   CpltSetVarImp::nqI(Space* home, I& i) {
00155     bdd ass = !(iterToBdd(i));
00156     return intersect(home, ass);
00157   }
00158 
00159   inline ModEvent
00160   CpltSetVarImp::eq(Space* home, int v) { return eq(home, v, v); }
00161 
00162   // gen _assigned needs a test in case
00163   // we try to build an _assigned
00164   // that is not allowed by the variable domain
00165   template <class I>
00166   ModEvent
00167   CpltSetVarImp::eqI(Space* home, I& i) {
00168     if (i()) {
00169       if (i.min() < min || i.min() > max) 
00170         return ME_CPLTSET_FAILED;
00171     }
00172     bdd ass = iterToBdd(i);
00173     return intersect(home, ass);
00174   }
00175 
00176   inline ModEvent 
00177   CpltSetVarImp::intersect(Space* home, int i) {
00178     return intersect(home, i, i);
00179   }
00180 
00181   template <class I> 
00182   ModEvent 
00183   CpltSetVarImp::intersectI(Space* home, I& i) {
00184     Iter::Ranges::Compl<Set::Limits::min, Set::Limits::max, I> 
00185       compI(i);
00186     return excludeI(home, compI); 
00187   }
00188 
00189   inline ModEvent 
00190   CpltSetVarImp::cardMin(Space* home, unsigned int newMin) {
00191     return cardinality(home, newMin, tableWidth());
00192   }
00193 
00194   inline ModEvent 
00195   CpltSetVarImp::cardMax(Space* home, unsigned int newMax) {
00196     return cardinality(home, 0, newMax);
00197   }
00198 
00199   // given the empty iterator we should produce an 
00200   // _assigned for the empty set.
00201   template <class I>
00202   bdd
00203   CpltSetVarImp::iterToBdd(I& i) {
00204 
00205     Iter::Ranges::ToValues<I> vali(i);
00206     Iter::Ranges::ValCache<Iter::Ranges::ToValues<I> > vc(vali);
00207 
00208     bdd ass = bdd_true();
00209     // start at the end for backwards iteration
00210     vc.last();
00211     for (int v = max; v >= min; v--) {
00212       if (vc()) {
00213         if (vc.val() == v) {
00214           ass &= element(v - min);
00215           --vc;
00216         } else {
00217           ass &= elementNeg(v - min);
00218         }
00219       } else {
00220         ass &= elementNeg(v - min);
00221       }
00222     }
00223 
00224     return ass;
00225   }
00226 
00227   inline bool
00228   CpltSetVarImp::range(void) const { return manager.ctrue(domain); }
00229 
00230   /*
00231    * Copying a variable
00232    *
00233    */
00234 
00235   forceinline CpltSetVarImp*
00236   CpltSetVarImp::copy(Space* home, bool share) {
00237     return copied() ? static_cast<CpltSetVarImp*>(forward())
00238       : perform_copy(home,share);
00239   }
00240 
00241   /*
00242    * Subscribing to variables
00243    *
00244    */
00245   forceinline void
00246   CpltSetVarImp::subscribe(Space* home, Propagator* p, PropCond pc,
00247                            bool process) {
00248     CpltSetVarImpBase::subscribe(home,p,pc,assigned(), process);
00249   }
00250 
00251   forceinline void
00252   CpltSetVarImp::cancel(Space* home, Propagator* p, PropCond pc) {
00253     CpltSetVarImpBase::cancel(home,p,pc,assigned());
00254   }
00255 
00256   /*
00257    * Support for delta information
00258    *
00259    */
00260   forceinline ModEvent
00261   CpltSetVarImp::modevent(const Delta* d) {
00262     return d->modevent();
00263   }
00264 
00266   template <> 
00267   class GlbValues<CpltSetVarImp*> : public DomBddIterator {
00268   private:
00269     int mi;
00270     int ma;
00271   public:
00273 
00274 
00275     GlbValues(void);
00277     GlbValues(const CpltSetVarImp* x);
00279     void init(const CpltSetVarImp* x);
00281 
00282 
00283 
00284     void operator++(void);
00286     int val(void) const;
00287   };
00288 
00290   template <> 
00291   class LubValues<CpltSetVarImp*> : public DomBddIterator {
00292   private:
00293     int mi;
00294     int ma;
00295   public:
00297 
00298 
00299     LubValues(void);
00301     LubValues(const CpltSetVarImp* x);
00303     void init(const CpltSetVarImp* x);
00305 
00306 
00307 
00308     void operator++(void);
00310     bool operator()(void) const;
00312     int val(void) const;
00313   };
00314 
00316   template <> 
00317   class UnknownValues<CpltSetVarImp*> : public DomBddIterator {
00318   private:
00319     int mi;
00320     int ma;
00321   public:
00323 
00324 
00325     UnknownValues(void);
00327     UnknownValues(const CpltSetVarImp* x);
00329     UnknownValues(const CpltSetVarImp* x, bdd& remain);
00331     void init(const CpltSetVarImp* x);
00333     void init(const CpltSetVarImp* x, bdd& remain);
00335 
00336 
00337 
00338     void operator++(void);
00340     int val(void) const;
00341   };
00342 
00343   /*
00344    * BddIterator
00345    *
00346    */
00347 
00348   forceinline
00349   BddIterator::BddIterator(void) {}
00350 
00351   forceinline
00352   BddIterator::BddIterator(const bdd& b) {
00353     init(b);
00354   }
00355 
00356   forceinline NodeStatus 
00357   BddIterator::status(void) const { return flag; }
00358 
00359   forceinline int 
00360   BddIterator::level(void) const { return _level; }
00361 
00362   forceinline bool
00363   BddIterator::empty(void) const { return (l == 0) && (r == n - 1); }
00364 
00365   inline bool
00366   BddIterator::operator()(void) const {
00367     bool valid = (!empty() || singleton );
00368     return valid;
00369   }
00370 
00371   inline int 
00372   BddIterator::label(void) const { 
00373     if (!operator()()) { 
00374       return -1; 
00375     } else {
00376       return manager.bddidx(cur); 
00377     }
00378   }
00379 
00380   forceinline int
00381   BddIterator::size(void) const { return n; }
00382   
00383   /*
00384    * DomBddIterator
00385    *
00386    */
00387 
00388   inline void
00389   DomBddIterator::init(const CpltSetVarImp* x, bdd& remain) {
00390     vector_level = 0;
00391     mi    = x->min;
00392     ma    = x->max;
00393     off   = x->_offset;
00394 
00395     bdd dom = x->dom();
00396     if (dom != remain)
00397       dom &= remain;
00398     
00399     BddIterator::init(dom);
00400     bdd_level   = BddIterator::label() - off;
00401   }
00402 
00403   inline void
00404   DomBddIterator::init(const CpltSetVarImp* x) {
00405     bdd dom = x->dom();
00406     init(x, dom);
00407   }
00408 
00409   forceinline   
00410   DomBddIterator::DomBddIterator(void) {}
00411 
00412   forceinline
00413   DomBddIterator::DomBddIterator(const CpltSetVarImp* x) {
00414     bdd dom = x->dom();
00415     DomBddIterator::init(x, dom);
00416   }
00417 
00418   inline
00419   DomBddIterator::DomBddIterator(const CpltSetVarImp* x, bdd& remain) {
00420     vector_level = 0;
00421     mi    = x->min;
00422     ma    = x->max;
00423     off   = x->_offset;
00424     bdd dom = x->dom();
00425     if (dom != remain) {
00426       dom &= remain;
00427     }
00428     BddIterator::init(dom);
00429     bdd_level = BddIterator::label() - off;
00430   }
00431 
00432   forceinline bool
00433   DomBddIterator::same(void) const { return bdd_level == vector_level; }
00434 
00435   forceinline bool
00436   DomBddIterator::operator()(void) const {
00437     return vector_level < (ma-mi+1);
00438   }
00439 
00440   inline void
00441   DomBddIterator::operator++(void) {
00442     if (same()) {
00443       BddIterator::operator++();
00444       bdd_level   = BddIterator::label() - off;
00445     } 
00446     vector_level++;
00447   }
00448 
00449   inline NodeStatus
00450   DomBddIterator::status(void) const{
00451     return same() ? BddIterator::status() : FIX_UNKNOWN;
00452   }
00453 
00454   inline int
00455   DomBddIterator::val(void) const {
00456     return same() ? mi + BddIterator::label() - off : mi + vector_level;
00457   }
00458 
00459   forceinline
00460   GlbValues<CpltSetVarImp*>::GlbValues(void) {}
00461 
00462   inline
00463   GlbValues<CpltSetVarImp*>::GlbValues(const CpltSetVarImp* x) 
00464     : mi(x->min), ma(x->max) {
00465     DomBddIterator::init(x);
00466     while (operator()() && status() != FIX_GLB) {
00467       DomBddIterator::operator++();
00468     }
00469 
00470   }
00471 
00472   inline void 
00473   GlbValues<CpltSetVarImp*>::init(const CpltSetVarImp* x) {
00474     mi = x->min;  
00475     ma = x->max;
00476     DomBddIterator::init(x);
00477     while (operator()() && status() != FIX_GLB) {
00478       DomBddIterator::operator++();
00479     }
00480   }
00481 
00482   inline void 
00483   GlbValues<CpltSetVarImp*>::operator++(void) {
00484     DomBddIterator::operator++();
00485     while (operator()() && status() != FIX_GLB) {
00486       DomBddIterator::operator++();
00487     }
00488   }
00489 
00490   forceinline int
00491   GlbValues<CpltSetVarImp*>::val(void) const {
00492     return DomBddIterator::val();
00493   }
00494   
00495   forceinline
00496   LubValues<CpltSetVarImp*>::LubValues(void) {}
00497 
00498   inline
00499   LubValues<CpltSetVarImp*>::LubValues(const CpltSetVarImp* x) 
00500     : mi(x->min), ma(x->max) {
00501     DomBddIterator::init(x);
00502     while (DomBddIterator::operator()() && status() == FIX_NOT_LUB) {
00503       DomBddIterator::operator++();
00504     }
00505   }
00506 
00507   inline void 
00508   LubValues<CpltSetVarImp*>::init(const CpltSetVarImp* x) {
00509     mi = x->min;  
00510     ma = x->max;
00511 
00512     DomBddIterator::init(x);
00513     while (DomBddIterator::operator()() && status() == FIX_NOT_LUB) {
00514       DomBddIterator::operator++();
00515     }
00516   }
00517 
00518   inline void 
00519   LubValues<CpltSetVarImp*>::operator++(void) {
00520     DomBddIterator::operator++();
00521     while (DomBddIterator::operator()() && status() == FIX_NOT_LUB) {
00522       DomBddIterator::operator++();
00523     }
00524   }
00525 
00526   inline bool
00527   LubValues<CpltSetVarImp*>::operator()(void) const {
00528     return DomBddIterator::operator()() && status() != FIX_NOT_LUB;
00529   }
00530 
00531   inline int
00532   LubValues<CpltSetVarImp*>::val(void) const {
00533     return DomBddIterator::val();
00534   }
00535 
00536   forceinline
00537   UnknownValues<CpltSetVarImp*>::UnknownValues(void) {}
00538 
00539   inline
00540   UnknownValues<CpltSetVarImp*>::UnknownValues(const CpltSetVarImp* x) 
00541     : mi(x->min), ma(x->max) {
00542     DomBddIterator::init(x);
00543     while (operator()() && 
00544            !(status() == FIX_UNKNOWN || status() == UNDET)) {
00545       DomBddIterator::operator++();
00546     }
00547   }
00548 
00549   inline void 
00550   UnknownValues<CpltSetVarImp*>::init(const CpltSetVarImp* x) {
00551     mi = x->min;  
00552     ma = x->max;
00553 
00554     DomBddIterator::init(x);
00555     while (operator()() && 
00556            !(status() == FIX_UNKNOWN || status() == UNDET)) {
00557       DomBddIterator::operator++();
00558     }
00559   }
00560 
00561   inline void 
00562   UnknownValues<CpltSetVarImp*>::operator++(void) {
00563     DomBddIterator::operator++();
00564     while (operator()() && 
00565            !(status() == FIX_UNKNOWN || status() == UNDET)) {
00566       DomBddIterator::operator++();
00567     }
00568   }
00569 
00570   inline int
00571   UnknownValues<CpltSetVarImp*>::val(void) const {
00572     return DomBddIterator::val();
00573   }
00574   
00575 }
00576 
00577 namespace Set {
00578 
00581   template <> 
00582   class GlbRanges<CpltSet::CpltSetVarImp*> 
00583     : public Iter::Values::ToRanges<CpltSet::GlbValues<CpltSet::CpltSetVarImp*> > {
00584   public:
00586 
00587 
00588     GlbRanges(void);
00590     GlbRanges(const CpltSet::CpltSetVarImp* x);
00592     void init(const CpltSet::CpltSetVarImp* x);
00594   };
00595 
00596   forceinline
00597   GlbRanges<CpltSet::CpltSetVarImp*>::GlbRanges(void) {}
00598 
00599   inline
00600   GlbRanges<CpltSet::CpltSetVarImp*>
00601   ::GlbRanges(const CpltSet::CpltSetVarImp* x) {
00602     CpltSet::GlbValues<CpltSet::CpltSetVarImp*> v(x);
00603     Iter::Values::ToRanges<CpltSet::GlbValues<CpltSet::CpltSetVarImp*> >::init(v);
00604   }
00605 
00606   inline void 
00607   GlbRanges<CpltSet::CpltSetVarImp*>
00608   ::init(const CpltSet::CpltSetVarImp* x) {
00609     CpltSet::GlbValues<CpltSet::CpltSetVarImp*> v(x);
00610     Iter::Values::ToRanges<
00611       CpltSet::GlbValues<CpltSet::CpltSetVarImp*> >::init(v);
00612   }
00613 
00616   template <> 
00617   class LubRanges<CpltSet::CpltSetVarImp*> 
00618   : public 
00619     Iter::Values::ToRanges<CpltSet::LubValues<CpltSet::CpltSetVarImp*> > {
00620   public:
00622 
00623 
00624     LubRanges(void);
00626     LubRanges(const CpltSet::CpltSetVarImp* x);
00628     void init(const CpltSet::CpltSetVarImp* x);
00630   };
00631 
00632   forceinline
00633   LubRanges<CpltSet::CpltSetVarImp*>::LubRanges(void) {}
00634 
00635   inline
00636   LubRanges<CpltSet::CpltSetVarImp*>
00637   ::LubRanges(const CpltSet::CpltSetVarImp* x) {
00638     CpltSet::LubValues<CpltSet::CpltSetVarImp*> v(x);
00639     Iter::Values::ToRanges<
00640       CpltSet::LubValues<CpltSet::CpltSetVarImp*> >::init(v);
00641   }
00642 
00643   inline void 
00644   LubRanges<CpltSet::CpltSetVarImp*>::init(const CpltSet::CpltSetVarImp* x) {
00645     CpltSet::LubValues<CpltSet::CpltSetVarImp*> v(x);
00646     Iter::Values::ToRanges<
00647       CpltSet::LubValues<CpltSet::CpltSetVarImp*> >::init(v);
00648   }
00649   
00651   template <> 
00652   class UnknownRanges<CpltSet::CpltSetVarImp*> 
00653     : public Iter::Values::ToRanges<CpltSet::UnknownValues<CpltSet::CpltSetVarImp*> > {
00654   public:
00656 
00657 
00658     UnknownRanges(void);
00660     UnknownRanges(const CpltSet::CpltSetVarImp* x);
00662     void init(const CpltSet::CpltSetVarImp* x);
00664   };
00665 
00666   forceinline
00667   UnknownRanges<CpltSet::CpltSetVarImp*>::UnknownRanges(void) {}
00668 
00669   inline
00670   UnknownRanges<CpltSet::CpltSetVarImp*>
00671   ::UnknownRanges(const CpltSet::CpltSetVarImp* x) {
00672     CpltSet::UnknownValues<CpltSet::CpltSetVarImp*> v(x);
00673     Iter::Values::ToRanges<CpltSet::UnknownValues<
00674       CpltSet::CpltSetVarImp*> >::init(v);
00675   }
00676 
00677   inline void 
00678   UnknownRanges<CpltSet::CpltSetVarImp*>
00679   ::init(const CpltSet::CpltSetVarImp* x) {
00680     CpltSet::UnknownValues<CpltSet::CpltSetVarImp*> v(x);
00681     Iter::Values::ToRanges<CpltSet::UnknownValues<
00682       CpltSet::CpltSetVarImp*> >::init(v);
00683   }
00684 
00685 }}
00686 
00687 // STATISTICS: cpltset-var