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
00029
00030
00031
00032
00033
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
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
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