00001
00055 #include "util.h"
00056 #include "cuddInt.h"
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 #ifndef lint
00079 static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.19 2004/08/13 18:04:46 fabio Exp $";
00080 #endif
00081
00082
00083
00084
00085
00086
00087
00090
00091
00092
00093
00094
00098
00099
00100
00101
00102
00119 DdNode *
00120 Cudd_bddAndAbstract(
00121 DdManager * manager,
00122 DdNode * f,
00123 DdNode * g,
00124 DdNode * cube)
00125 {
00126 DdNode *res;
00127
00128 do {
00129 manager->reordered = 0;
00130 res = cuddBddAndAbstractRecur(manager, f, g, cube);
00131 } while (manager->reordered == 1);
00132 return(res);
00133
00134 }
00135
00136
00153 DdNode *
00154 Cudd_bddAndAbstractLimit(
00155 DdManager * manager,
00156 DdNode * f,
00157 DdNode * g,
00158 DdNode * cube,
00159 unsigned int limit)
00160 {
00161 DdNode *res;
00162 unsigned int saveLimit = manager->maxLive;
00163
00164 manager->maxLive = (manager->keys - manager->dead) +
00165 (manager->keysZ - manager->deadZ) + limit;
00166 do {
00167 manager->reordered = 0;
00168 res = cuddBddAndAbstractRecur(manager, f, g, cube);
00169 } while (manager->reordered == 1);
00170 manager->maxLive = saveLimit;
00171 return(res);
00172
00173 }
00174
00175
00176
00177
00178
00179
00180
00195 DdNode *
00196 cuddBddAndAbstractRecur(
00197 DdManager * manager,
00198 DdNode * f,
00199 DdNode * g,
00200 DdNode * cube)
00201 {
00202 DdNode *F, *ft, *fe, *G, *gt, *ge;
00203 DdNode *one, *zero, *r, *t, *e;
00204 unsigned int topf, topg, topcube, top, index;
00205
00206 statLine(manager);
00207 one = DD_ONE(manager);
00208 zero = Cudd_Not(one);
00209
00210
00211 if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
00212 if (f == one && g == one) return(one);
00213
00214 if (cube == one) {
00215 return(cuddBddAndRecur(manager, f, g));
00216 }
00217 if (f == one || f == g) {
00218 return(cuddBddExistAbstractRecur(manager, g, cube));
00219 }
00220 if (g == one) {
00221 return(cuddBddExistAbstractRecur(manager, f, cube));
00222 }
00223
00224
00225 if (f > g) {
00226 DdNode *tmp = f;
00227 f = g;
00228 g = tmp;
00229 }
00230
00231
00232
00233
00234 F = Cudd_Regular(f);
00235 G = Cudd_Regular(g);
00236 topf = manager->perm[F->index];
00237 topg = manager->perm[G->index];
00238 top = ddMin(topf, topg);
00239 topcube = manager->perm[cube->index];
00240
00241 while (topcube < top) {
00242 cube = cuddT(cube);
00243 if (cube == one) {
00244 return(cuddBddAndRecur(manager, f, g));
00245 }
00246 topcube = manager->perm[cube->index];
00247 }
00248
00249
00250
00251 if (F->ref != 1 || G->ref != 1) {
00252 r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube);
00253 if (r != NULL) {
00254 return(r);
00255 }
00256 }
00257
00258 if (topf == top) {
00259 index = F->index;
00260 ft = cuddT(F);
00261 fe = cuddE(F);
00262 if (Cudd_IsComplement(f)) {
00263 ft = Cudd_Not(ft);
00264 fe = Cudd_Not(fe);
00265 }
00266 } else {
00267 index = G->index;
00268 ft = fe = f;
00269 }
00270
00271 if (topg == top) {
00272 gt = cuddT(G);
00273 ge = cuddE(G);
00274 if (Cudd_IsComplement(g)) {
00275 gt = Cudd_Not(gt);
00276 ge = Cudd_Not(ge);
00277 }
00278 } else {
00279 gt = ge = g;
00280 }
00281
00282 if (topcube == top) {
00283 DdNode *Cube = cuddT(cube);
00284 t = cuddBddAndAbstractRecur(manager, ft, gt, Cube);
00285 if (t == NULL) return(NULL);
00286
00287
00288
00289
00290
00291 if (t == one || t == fe || t == ge) {
00292 if (F->ref != 1 || G->ref != 1)
00293 cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG,
00294 f, g, cube, t);
00295 return(t);
00296 }
00297 cuddRef(t);
00298
00299 if (t == Cudd_Not(fe)) {
00300 e = cuddBddExistAbstractRecur(manager, ge, Cube);
00301 } else if (t == Cudd_Not(ge)) {
00302 e = cuddBddExistAbstractRecur(manager, fe, Cube);
00303 } else {
00304 e = cuddBddAndAbstractRecur(manager, fe, ge, Cube);
00305 }
00306 if (e == NULL) {
00307 Cudd_IterDerefBdd(manager, t);
00308 return(NULL);
00309 }
00310 if (t == e) {
00311 r = t;
00312 cuddDeref(t);
00313 } else {
00314 cuddRef(e);
00315 r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e));
00316 if (r == NULL) {
00317 Cudd_IterDerefBdd(manager, t);
00318 Cudd_IterDerefBdd(manager, e);
00319 return(NULL);
00320 }
00321 r = Cudd_Not(r);
00322 cuddRef(r);
00323 Cudd_DelayedDerefBdd(manager, t);
00324 Cudd_DelayedDerefBdd(manager, e);
00325 cuddDeref(r);
00326 }
00327 } else {
00328 t = cuddBddAndAbstractRecur(manager, ft, gt, cube);
00329 if (t == NULL) return(NULL);
00330 cuddRef(t);
00331 e = cuddBddAndAbstractRecur(manager, fe, ge, cube);
00332 if (e == NULL) {
00333 Cudd_IterDerefBdd(manager, t);
00334 return(NULL);
00335 }
00336 if (t == e) {
00337 r = t;
00338 cuddDeref(t);
00339 } else {
00340 cuddRef(e);
00341 if (Cudd_IsComplement(t)) {
00342 r = cuddUniqueInter(manager, (int) index,
00343 Cudd_Not(t), Cudd_Not(e));
00344 if (r == NULL) {
00345 Cudd_IterDerefBdd(manager, t);
00346 Cudd_IterDerefBdd(manager, e);
00347 return(NULL);
00348 }
00349 r = Cudd_Not(r);
00350 } else {
00351 r = cuddUniqueInter(manager,(int)index,t,e);
00352 if (r == NULL) {
00353 Cudd_IterDerefBdd(manager, t);
00354 Cudd_IterDerefBdd(manager, e);
00355 return(NULL);
00356 }
00357 }
00358 cuddDeref(e);
00359 cuddDeref(t);
00360 }
00361 }
00362
00363 if (F->ref != 1 || G->ref != 1)
00364 cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r);
00365 return (r);
00366
00367 }
00368
00369
00370
00371
00372
00373