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

bddmanager.icc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Patrick Pekczynski <pekczynski@ps.uni-sb.de>
00004  *
00005  *  Copyright:
00006  *     Patrick Pekczynski, 2006
00007  *
00008  *  Last modified:
00009  *     $Date: 2007-12-06 14:09:40 +0100 (Thu, 06 Dec 2007) $ by $Author: tack $
00010  *     $Revision: 5608 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  Permission is hereby granted, free of charge, to any person obtaining
00017  *  a copy of this software and associated documentation files (the
00018  *  "Software"), to deal in the Software without restriction, including
00019  *  without limitation the rights to use, copy, modify, merge, publish,
00020  *  distribute, sublicense, and/or sell copies of the Software, and to
00021  *  permit persons to whom the Software is furnished to do so, subject to
00022  *  the following conditions:
00023  *
00024  *  The above copyright notice and this permission notice shall be
00025  *  included in all copies or substantial portions of the Software.
00026  *
00027  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00028  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00029  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00030  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00031  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00032  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00033  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00034  *
00035  */
00036 
00037 #include "gecode/support/buddy/bdd.h"
00038 
00039 namespace Gecode {
00040   
00042   class GECODE_VTABLE_EXPORT BddMgrException : public Exception {
00043   public:
00045     BddMgrException(const char* l);
00046   };
00047 
00048   inline
00049   BddMgrException::BddMgrException(const char* l)
00050     : Exception(l,"Error in ROBDD Manager") {}
00051   
00052   namespace CpltSet {
00053 
00061   class BddMgr {
00062   private:
00063     bddStat info;
00065     int _size;
00067     int _offset;
00068     int dummy_offset;
00069     int dummy_range;
00070   public:
00072     BddMgr(void);
00074     GECODE_CPLTSET_EXPORT ~BddMgr(void);
00075     
00077     void init(int n, int c);
00078 
00080     bool leaf(const bdd& b) const;
00082     bool cfalse(const bdd& b) const;
00084     bool ctrue(const bdd& b) const;
00086     void setorder(int* hls);
00088     unsigned int bddsize(const bdd& b) const;
00090     unsigned int bddpath(const bdd& b) const;
00092     GECODE_CPLTSET_EXPORT unsigned int numberOfPaths(bdd& b);
00094     bdd bddpos(int i) const;
00096     bdd negbddpos(int i) const;
00097 
00099     int lbCard(const bdd& b);
00101     int ubCard(const bdd& b);
00102 
00104     void lbCard(const bdd& b, int l);
00106     void ubCard(const bdd& b, int r);
00107 
00109     bdd ite(const bdd& v, const bdd& t, const bdd& f);
00111     void mark(const bdd& b);
00113     void unmark(const bdd& b);
00115     bool marked(const bdd& b) const;
00116 
00117     int node_level(const bdd& b) const;
00119     int bdd2var(int i);
00121     int var2bdd(int i);
00123     int dummy(void);
00125     bdd iftrue(bdd& b);
00127     bdd iffalse(bdd& b);
00129     const unsigned int bddidx(const bdd& b);
00130     
00132     void existquant(bdd& dom, bdd& d, int* var, int s);
00134     void existquant(bdd& dom, bdd& d, int a, int b);
00136     void existquant(bdd& dom, bdd& d, bdd& pr);
00138     bdd eliminate(bdd& d, int a, int b);
00140     bdd eliminate(bdd& d, bdd& e);
00142     bdd eliminate(bdd& d, int* var, int s);
00144     void markdummy(int a, int b);
00145 
00147     void dispose(void);
00149     void dispose(int offset, int range, int freenodes = 0);
00151     void dispose(bdd& d);
00156     int allocate(int r);
00158     int varnum(void);
00160     void bddntf(std::ostream&, bdd& b);
00162     void bdd2dot(const bdd& b) const;
00164     unsigned int allocated(void);
00166     void print_set(const bdd& b);
00168     int offset(void) const;
00170     void setmaxinc(int max);
00172     bool available(void);
00173   };
00174 
00175   forceinline bool
00176   BddMgr::available(void) { return bdd_isrunning(); }
00177 
00178   forceinline bool 
00179   BddMgr::leaf(const bdd& b) const{ return b == bdd_true() || b == bdd_false(); }
00180 
00181   forceinline bool 
00182   BddMgr::cfalse(const bdd& b) const{ return b == bdd_false(); }
00183 
00184   forceinline bool 
00185   BddMgr::ctrue(const bdd& b) const{ return b == bdd_true(); }
00186 
00187   forceinline
00188   BddMgr::BddMgr(void)
00189   : _size(0), _offset(0), dummy_offset( -1), dummy_range(-1) {}
00190 
00191   forceinline void
00192   BddMgr::dispose(void) {
00193     if (available()) { 
00194       bdd_done(); 
00195     }
00196     _size = 0;
00197     _offset = 0;
00198     dummy_offset = -1; 
00199     dummy_range = -1;
00200   }
00201    
00202   forceinline void
00203   BddMgr::init(int n, int c) {  
00204     _size = 0;
00205     _offset = 0;
00206     dummy_offset = -1; 
00207     dummy_range = -1;
00208     bdd_init(n, c);
00209     
00210     info.produced = -1;
00211     info.nodenum = -1;
00212     info.maxnodenum = -1;
00213     info.freenodes= -1;
00214     info.minfreenodes= -1;
00215     info.varnum= -1;
00216     info.cachesize= -1;
00217     info.gbcnum= -1;
00218   }
00219 
00220   forceinline void
00221   BddMgr::print_set(const bdd& b) {
00222     bdd_printset(b);
00223   }
00224 
00225   forceinline bdd
00226   BddMgr::bddpos(int i) const{ return bdd_ithvarpp(i); }
00227 
00228   forceinline int 
00229   BddMgr::allocate(int r) {
00230     assert(available());
00231     _size++;
00232     bdd_stats(&info);
00233     if (dummy_offset > - 1) {
00234       if (dummy_range < r) {
00235         for (int i = dummy_range; i < r; i++) { bdd v = bddpos(i); }
00236       } else {
00237         int initoffset = dummy_offset;
00238         if (dummy_range > r) {
00239           _offset = dummy_offset;
00240           _offset += r;
00241         } else {
00242           dummy_offset = -1;
00243         }
00244         return initoffset;
00245       }
00246     }
00247 
00248     // increase on number of allocated bdd variables
00249     bdd_extvarnum(r);
00250 
00251     for (int i = _offset; i < _offset + r; i++) { bdd v = bddpos(i); }
00252 
00253     int initoffset = _offset;
00254     _offset += r;
00255     return initoffset;
00256   }
00257 
00258   forceinline unsigned int
00259   BddMgr::allocated(void) {
00260     bdd_stats(&info);
00261     return info.varnum;
00262   }
00263 
00264 
00265   forceinline bdd
00266   BddMgr::negbddpos(int i) const{ return bdd_nithvarpp(i); }
00267 
00268   forceinline void 
00269   BddMgr::mark(const bdd& b) { bdd_mark_node(b); }
00270 
00271   forceinline void
00272   BddMgr::unmark(const bdd& b) { bdd_unmark_node(b); }
00273 
00274   forceinline bool
00275   BddMgr::marked(const bdd& b) const { return bdd_marked_node(b); }
00276 
00277   forceinline int
00278   BddMgr::node_level(const bdd& b) const{ return bdd_level_node(b); }
00279 
00280   forceinline int
00281   BddMgr::lbCard(const bdd& b) { return bdd_card_lo(b); }
00282 
00283   forceinline int
00284   BddMgr::ubCard(const bdd& b) { return bdd_card_hi(b); }
00285 
00286   forceinline void
00287   BddMgr::lbCard(const bdd& b, int l) {  bdd_set_card_lo(b, l); }
00288 
00289   forceinline void
00290   BddMgr::ubCard(const bdd& b, int r) {  bdd_set_card_hi(b, r); }
00291   
00292   forceinline bdd
00293   BddMgr::ite(const bdd& v, const bdd& t, const bdd& f) {
00294     return bdd_ite(v, t, f);
00295   }
00296 
00297   forceinline int
00298   BddMgr::bdd2var(int i){ return bdd_level2var(i); }
00299 
00300   forceinline int
00301   BddMgr::var2bdd(int i){ return bdd_var2level(i); }
00302 
00303   forceinline int
00304   BddMgr::dummy(void){ return dummy_offset; }
00305 
00306   forceinline void
00307   BddMgr::setorder(int* hls) {
00308     bdd_setvarorder(hls);
00309     bdd_disable_reorder();
00310   }
00311 
00312   forceinline unsigned int
00313   BddMgr::bddsize(const bdd& b) const{ return bdd_nodecount(b); }
00314 
00315   forceinline unsigned int
00316   BddMgr::bddpath(const bdd& b) const{
00317     return static_cast<unsigned int> (bdd_pathcount(b));
00318   }
00319 
00320   forceinline bdd 
00321   BddMgr::iftrue(bdd& b) { return bdd_high(b); }
00322 
00323   forceinline bdd 
00324   BddMgr::iffalse(bdd& b) { return bdd_low(b); }
00325 
00326   forceinline const unsigned int
00327   BddMgr::bddidx(const bdd& b) {
00328     if (marked(b)) {
00329       unmark(b);
00330       int i = bdd_var(b);
00331       mark(b);
00332       return i;
00333     } else {
00334       return bdd_var(b);
00335     }
00336   }
00337 
00338   forceinline void
00339   BddMgr::bdd2dot(const bdd& b) const{ bdd_printdot(b); }
00340 
00341   forceinline void
00342   BddMgr::existquant(bdd& dom, bdd& d, int* var, int s) {
00343     bdd outvar = bdd_makeset(var, s);
00344     bdd newdom = bdd_appex(dom, d, bddop_and, outvar);
00345     dom        = newdom;
00346   }
00347 
00348   forceinline void
00349   BddMgr::existquant(bdd& dom, bdd& d, int a, int b) {
00350     bdd outvar = bdd_true();
00351     for (int i = a; i <= b; i++) {
00352       bdd cur = bddpos(i);
00353       assert(!marked(cur));
00354       assert(!leaf(cur));
00355       outvar &= cur;
00356     }
00357     bdd newdom = bdd_appex(dom, d, bddop_and, outvar);
00358     dom = newdom;
00359   }
00360 
00361   forceinline void 
00362   BddMgr::existquant(bdd& dom, bdd& d, bdd& pr) {
00363     dom = bdd_appex(dom, d, bddop_and, pr);
00364   }
00365 
00366   forceinline bdd
00367   BddMgr::eliminate(bdd& d, int a, int b) {
00368     bdd outvar = bdd_true();
00369     for (int i = a; i <= b; i++) {
00370       bdd cur = bddpos(i);
00371       assert(!marked(cur));
00372       outvar &= cur;
00373     }
00374     return bdd_exist(d, outvar);
00375   }
00376 
00377   forceinline bdd
00378   BddMgr::eliminate(bdd& d, bdd& e) {
00379     return bdd_exist(d, e);
00380   }
00381 
00382   forceinline bdd
00383   BddMgr::eliminate(bdd& d, int* var, int s) {
00384     bdd outvar = bdd_makeset(var, s);
00385     return bdd_exist(d, outvar);
00386   }
00387 
00388   forceinline void
00389   BddMgr::markdummy(int a, int b) {
00390     dummy_offset = a;
00391     dummy_range  = b;
00392     _size--;
00393   }
00394 
00395   forceinline void
00396   BddMgr::dispose(int offset, int range, int freenodes) {
00397     if (available()) {
00398       for (int i = 0; i < range; i++) {  bddpos(offset + i).dispose(); }
00399       if (_offset == offset + range) { _offset -= range; }
00400       // this is done in dipose(bdd d)
00401       info.freenodes += freenodes;
00402       if (offset == dummy_offset && dummy_offset > -1) {
00403         dummy_offset = -1;
00404         dummy_range  = -1;
00405       }
00406     }
00407   }
00408 
00409   forceinline void
00410   BddMgr::dispose(bdd& d) {
00411     if (available()) {
00412       int freenodes = bddsize(d);
00413       d = bdd_false();
00414       info.freenodes += freenodes;
00415     }
00416   }
00417 
00418   forceinline void
00419   BddMgr::bddntf(std::ostream& os, bdd& b) {
00420     os << "(N" << b;
00421     os <<", T"<< iftrue(b);
00422     os << ", F" << iffalse(b) << ")";
00423     os << "[" << bddidx(b) << "]\n";
00424   }
00425 
00426   forceinline int
00427   BddMgr::varnum(void) {
00428     bdd_stats(&info);
00429     return info.varnum;
00430   }
00431   
00432   forceinline int
00433   BddMgr::offset(void) const{
00434     assert(_offset <= bdd_varnum());
00435     return _offset;
00436   }
00437 
00438   forceinline void
00439   BddMgr::setmaxinc(int max) {
00440     int o = -1;
00441     o = bdd_setmaxincrease(max);
00442   }
00443 
00444   GECODE_CPLTSET_EXPORT extern BddMgr manager;
00445 
00446 }}
00447 
00448 // STATISTICS: cpltset-var