00001
00027 #include "util_hack.h"
00028 #include "cuddInt.h"
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #ifndef lint
00051 static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";
00052 #endif
00053
00054
00055
00056
00057
00058
00059
00062
00063
00064
00065
00066
00070
00071
00072
00073
00074
00091 DdNode *
00092 Cudd_bddAndAbstract(
00093 DdManager * manager,
00094 DdNode * f,
00095 DdNode * g,
00096 DdNode * cube)
00097 {
00098 DdNode *res;
00099
00100 do {
00101 manager->reordered = 0;
00102 res = cuddBddAndAbstractRecur(manager, f, g, cube);
00103 } while (manager->reordered == 1);
00104 return(res);
00105
00106 }
00107
00108
00109
00110
00111
00112
00113
00128 DdNode *
00129 cuddBddAndAbstractRecur(
00130 DdManager * manager,
00131 DdNode * f,
00132 DdNode * g,
00133 DdNode * cube)
00134 {
00135 DdNode *F, *ft, *fe, *G, *gt, *ge;
00136 DdNode *one, *zero, *r, *t, *e;
00137 unsigned int topf, topg, topcube, top, index;
00138
00139 statLine(manager);
00140 one = DD_ONE(manager);
00141 zero = Cudd_Not(one);
00142
00143
00144 if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
00145 if (f == one && g == one) return(one);
00146
00147 if (cube == one) {
00148 return(cuddBddAndRecur(manager, f, g));
00149 }
00150 if (f == one || f == g) {
00151 return(cuddBddExistAbstractRecur(manager, g, cube));
00152 }
00153 if (g == one) {
00154 return(cuddBddExistAbstractRecur(manager, f, cube));
00155 }
00156
00157
00158 if (f > g) {
00159 DdNode *tmp = f;
00160 f = g;
00161 g = tmp;
00162 }
00163
00164
00165
00166
00167 F = Cudd_Regular(f);
00168 G = Cudd_Regular(g);
00169 topf = manager->perm[F->index];
00170 topg = manager->perm[G->index];
00171 top = ddMin(topf, topg);
00172 topcube = manager->perm[cube->index];
00173
00174 while (topcube < top) {
00175 cube = cuddT(cube);
00176 if (cube == one) {
00177 return(cuddBddAndRecur(manager, f, g));
00178 }
00179 topcube = manager->perm[cube->index];
00180 }
00181
00182
00183
00184 if (F->ref != 1 || G->ref != 1) {
00185 r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube);
00186 if (r != NULL) {
00187 return(r);
00188 }
00189 }
00190
00191 if (topf == top) {
00192 index = F->index;
00193 ft = cuddT(F);
00194 fe = cuddE(F);
00195 if (Cudd_IsComplement(f)) {
00196 ft = Cudd_Not(ft);
00197 fe = Cudd_Not(fe);
00198 }
00199 } else {
00200 index = G->index;
00201 ft = fe = f;
00202 }
00203
00204 if (topg == top) {
00205 gt = cuddT(G);
00206 ge = cuddE(G);
00207 if (Cudd_IsComplement(g)) {
00208 gt = Cudd_Not(gt);
00209 ge = Cudd_Not(ge);
00210 }
00211 } else {
00212 gt = ge = g;
00213 }
00214
00215 if (topcube == top) {
00216 DdNode *Cube = cuddT(cube);
00217 t = cuddBddAndAbstractRecur(manager, ft, gt, Cube);
00218 if (t == NULL) return(NULL);
00219
00220
00221
00222
00223
00224 if (t == one || t == fe || t == ge) {
00225 if (F->ref != 1 || G->ref != 1)
00226 cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG,
00227 f, g, cube, t);
00228 return(t);
00229 }
00230 cuddRef(t);
00231
00232 if (t == Cudd_Not(fe)) {
00233 e = cuddBddExistAbstractRecur(manager, ge, Cube);
00234 } else if (t == Cudd_Not(ge)) {
00235 e = cuddBddExistAbstractRecur(manager, fe, Cube);
00236 } else {
00237 e = cuddBddAndAbstractRecur(manager, fe, ge, Cube);
00238 }
00239 if (e == NULL) {
00240 Cudd_IterDerefBdd(manager, t);
00241 return(NULL);
00242 }
00243 if (t == e) {
00244 r = t;
00245 cuddDeref(t);
00246 } else {
00247 cuddRef(e);
00248 r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e));
00249 if (r == NULL) {
00250 Cudd_IterDerefBdd(manager, t);
00251 Cudd_IterDerefBdd(manager, e);
00252 return(NULL);
00253 }
00254 r = Cudd_Not(r);
00255 cuddRef(r);
00256 Cudd_DelayedDerefBdd(manager, t);
00257 Cudd_DelayedDerefBdd(manager, e);
00258 cuddDeref(r);
00259 }
00260 } else {
00261 t = cuddBddAndAbstractRecur(manager, ft, gt, cube);
00262 if (t == NULL) return(NULL);
00263 cuddRef(t);
00264 e = cuddBddAndAbstractRecur(manager, fe, ge, cube);
00265 if (e == NULL) {
00266 Cudd_IterDerefBdd(manager, t);
00267 return(NULL);
00268 }
00269 if (t == e) {
00270 r = t;
00271 cuddDeref(t);
00272 } else {
00273 cuddRef(e);
00274 if (Cudd_IsComplement(t)) {
00275 r = cuddUniqueInter(manager, (int) index,
00276 Cudd_Not(t), Cudd_Not(e));
00277 if (r == NULL) {
00278 Cudd_IterDerefBdd(manager, t);
00279 Cudd_IterDerefBdd(manager, e);
00280 return(NULL);
00281 }
00282 r = Cudd_Not(r);
00283 } else {
00284 r = cuddUniqueInter(manager,(int)index,t,e);
00285 if (r == NULL) {
00286 Cudd_IterDerefBdd(manager, t);
00287 Cudd_IterDerefBdd(manager, e);
00288 return(NULL);
00289 }
00290 }
00291 cuddDeref(e);
00292 cuddDeref(t);
00293 }
00294 }
00295
00296 if (F->ref != 1 || G->ref != 1)
00297 cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r);
00298 return (r);
00299
00300 }
00301
00302
00303
00304
00305
00306