#include "util_hack.h"
#include "cuddInt.h"
Go to the source code of this file.
Functions | |
static void bddVarToConst | ARGS ((DdNode *f, DdNode **gp, DdNode **hp, DdNode *one)) |
static int bddVarToCanonical | ARGS ((DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)) |
DdNode * | Cudd_bddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h) |
DdNode * | Cudd_bddIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h) |
DdNode * | Cudd_bddIntersect (DdManager *dd, DdNode *f, DdNode *g) |
DdNode * | Cudd_bddAnd (DdManager *dd, DdNode *f, DdNode *g) |
DdNode * | Cudd_bddOr (DdManager *dd, DdNode *f, DdNode *g) |
DdNode * | Cudd_bddNand (DdManager *dd, DdNode *f, DdNode *g) |
DdNode * | Cudd_bddNor (DdManager *dd, DdNode *f, DdNode *g) |
DdNode * | Cudd_bddXor (DdManager *dd, DdNode *f, DdNode *g) |
DdNode * | Cudd_bddXnor (DdManager *dd, DdNode *f, DdNode *g) |
int | Cudd_bddLeq (DdManager *dd, DdNode *f, DdNode *g) |
DdNode * | cuddBddIteRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *h) |
DdNode * | cuddBddIntersectRecur (DdManager *dd, DdNode *f, DdNode *g) |
DdNode * | cuddBddAndRecur (DdManager *manager, DdNode *f, DdNode *g) |
DdNode * | cuddBddXorRecur (DdManager *manager, DdNode *f, DdNode *g) |
static void | bddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one) |
static int | bddVarToCanonical (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp) |
static int | bddVarToCanonicalSimple (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp) |
Variables | |
static char rcsid[] | DD_UNUSED = "$Id: cuddBddIte.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $" |
static int bddVarToCanonicalSimple ARGS | ( | (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp) | ) | [static] |
AutomaticStart
static int bddVarToCanonical | ( | DdManager * | dd, | |
DdNode ** | fp, | |||
DdNode ** | gp, | |||
DdNode ** | hp, | |||
unsigned int * | topfp, | |||
unsigned int * | topgp, | |||
unsigned int * | tophp | |||
) | [static] |
Function********************************************************************
Synopsis [Picks unique member from equiv expressions.]
Description [Reduces 2 variable expressions to canonical form.]
SideEffects [None]
SeeAlso [bddVarToConst bddVarToCanonicalSimple]
Definition at line 1103 of file cuddBddIte.c.
01111 { 01112 register DdNode *F, *G, *H, *r, *f, *g, *h; 01113 register unsigned int topf, topg, toph; 01114 DdNode *one = dd->one; 01115 int comple, change; 01116 01117 f = *fp; 01118 g = *gp; 01119 h = *hp; 01120 F = Cudd_Regular(f); 01121 G = Cudd_Regular(g); 01122 H = Cudd_Regular(h); 01123 topf = cuddI(dd,F->index); 01124 topg = cuddI(dd,G->index); 01125 toph = cuddI(dd,H->index); 01126 01127 change = 0; 01128 01129 if (G == one) { /* ITE(F,c,H) */ 01130 if ((topf > toph) || (topf == toph && f > h)) { 01131 r = h; 01132 h = f; 01133 f = r; /* ITE(F,1,H) = ITE(H,1,F) */ 01134 if (g != one) { /* g == zero */ 01135 f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */ 01136 h = Cudd_Not(h); 01137 } 01138 change = 1; 01139 } 01140 } else if (H == one) { /* ITE(F,G,c) */ 01141 if ((topf > topg) || (topf == topg && f > g)) { 01142 r = g; 01143 g = f; 01144 f = r; /* ITE(F,G,0) = ITE(G,F,0) */ 01145 if (h == one) { 01146 f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */ 01147 g = Cudd_Not(g); 01148 } 01149 change = 1; 01150 } 01151 } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */ 01152 if ((topf > topg) || (topf == topg && f > g)) { 01153 r = f; 01154 f = g; 01155 g = r; 01156 h = Cudd_Not(r); 01157 change = 1; 01158 } 01159 } 01160 /* adjust pointers so that the first 2 arguments to ITE are regular */ 01161 if (Cudd_IsComplement(f) != 0) { /* ITE(!F,G,H) = ITE(F,H,G) */ 01162 f = Cudd_Not(f); 01163 r = g; 01164 g = h; 01165 h = r; 01166 change = 1; 01167 } 01168 comple = 0; 01169 if (Cudd_IsComplement(g) != 0) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ 01170 g = Cudd_Not(g); 01171 h = Cudd_Not(h); 01172 change = 1; 01173 comple = 1; 01174 } 01175 if (change != 0) { 01176 *fp = f; 01177 *gp = g; 01178 *hp = h; 01179 } 01180 *topfp = cuddI(dd,f->index); 01181 *topgp = cuddI(dd,g->index); 01182 *tophp = cuddI(dd,Cudd_Regular(h)->index); 01183 01184 return(comple); 01185 01186 } /* end of bddVarToCanonical */
static int bddVarToCanonicalSimple | ( | DdManager * | dd, | |
DdNode ** | fp, | |||
DdNode ** | gp, | |||
DdNode ** | hp, | |||
unsigned int * | topfp, | |||
unsigned int * | topgp, | |||
unsigned int * | tophp | |||
) | [static] |
Function********************************************************************
Synopsis [Picks unique member from equiv expressions.]
Description [Makes sure the first two pointers are regular. This mat require the complementation of the result, which is signaled by returning 1 instead of 0. This function is simpler than the general case because it assumes that no two arguments are the same or complementary, and no argument is constant.]
SideEffects [None]
SeeAlso [bddVarToConst bddVarToCanonical]
Definition at line 1205 of file cuddBddIte.c.
01213 { 01214 register DdNode *r, *f, *g, *h; 01215 int comple, change; 01216 01217 f = *fp; 01218 g = *gp; 01219 h = *hp; 01220 01221 change = 0; 01222 01223 /* adjust pointers so that the first 2 arguments to ITE are regular */ 01224 if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */ 01225 f = Cudd_Not(f); 01226 r = g; 01227 g = h; 01228 h = r; 01229 change = 1; 01230 } 01231 comple = 0; 01232 if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ 01233 g = Cudd_Not(g); 01234 h = Cudd_Not(h); 01235 change = 1; 01236 comple = 1; 01237 } 01238 if (change) { 01239 *fp = f; 01240 *gp = g; 01241 *hp = h; 01242 } 01243 01244 /* Here we can skip the use of cuddI, because the operands are known 01245 ** to be non-constant. 01246 */ 01247 *topfp = dd->perm[f->index]; 01248 *topgp = dd->perm[g->index]; 01249 *tophp = dd->perm[Cudd_Regular(h)->index]; 01250 01251 return(comple); 01252 01253 } /* end of bddVarToCanonicalSimple */
Function********************************************************************
Synopsis [Replaces variables with constants if possible.]
Description [This function performs part of the transformation to standard form by replacing variables with constants if possible.]
SideEffects [None]
SeeAlso [bddVarToCanonical bddVarToCanonicalSimple]
Definition at line 1068 of file cuddBddIte.c.
01073 { 01074 DdNode *g = *gp; 01075 DdNode *h = *hp; 01076 01077 if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ 01078 *gp = one; 01079 } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ 01080 *gp = Cudd_Not(one); 01081 } 01082 if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ 01083 *hp = Cudd_Not(one); 01084 } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ 01085 *hp = one; 01086 } 01087 01088 } /* end of bddVarToConst */
Function********************************************************************
Synopsis [Computes the conjunction of two BDDs f and g.]
Description [Computes the conjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAndAbstract Cudd_bddIntersect Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]
Definition at line 282 of file cuddBddIte.c.
00286 { 00287 DdNode *res; 00288 00289 do { 00290 dd->reordered = 0; 00291 res = cuddBddAndRecur(dd,f,g); 00292 } while (dd->reordered == 1); 00293 return(res); 00294 00295 } /* end of Cudd_bddAnd */
Function********************************************************************
Synopsis [Returns a function included in the intersection of f and g.]
Description [Computes a function included in the intersection of f and g. (That is, a witness that the intersection is not empty.) Cudd_bddIntersect tries to build as few new nodes as possible. If the only result of interest is whether f and g intersect, Cudd_bddLeq should be used instead.]
SideEffects [None]
SeeAlso [Cudd_bddLeq Cudd_bddIteConstant]
Definition at line 250 of file cuddBddIte.c.
00254 { 00255 DdNode *res; 00256 00257 do { 00258 dd->reordered = 0; 00259 res = cuddBddIntersectRecur(dd,f,g); 00260 } while (dd->reordered == 1); 00261 00262 return(res); 00263 00264 } /* end of Cudd_bddIntersect */
AutomaticEnd Function********************************************************************
Synopsis [Implements ITE(f,g,h).]
Description [Implements ITE(f,g,h). Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_addIte Cudd_bddIteConstant Cudd_bddIntersect]
Definition at line 111 of file cuddBddIte.c.
00116 { 00117 DdNode *res; 00118 00119 do { 00120 dd->reordered = 0; 00121 res = cuddBddIteRecur(dd,f,g,h); 00122 } while (dd->reordered == 1); 00123 return(res); 00124 00125 } /* end of Cudd_bddIte */
Function********************************************************************
Synopsis [Implements ITEconstant(f,g,h).]
Description [Implements ITEconstant(f,g,h). Returns a pointer to the resulting BDD (which may or may not be constant) or DD_NON_CONSTANT. No new nodes are created.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_bddIntersect Cudd_bddLeq Cudd_addIteConstant]
Definition at line 142 of file cuddBddIte.c.
00147 { 00148 DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; 00149 DdNode *one = DD_ONE(dd); 00150 DdNode *zero = Cudd_Not(one); 00151 int comple; 00152 unsigned int topf, topg, toph, v; 00153 00154 statLine(dd); 00155 /* Trivial cases. */ 00156 if (f == one) /* ITE(1,G,H) => G */ 00157 return(g); 00158 00159 if (f == zero) /* ITE(0,G,H) => H */ 00160 return(h); 00161 00162 /* f now not a constant. */ 00163 bddVarToConst(f, &g, &h, one); /* possibly convert g or h */ 00164 /* to constants */ 00165 00166 if (g == h) /* ITE(F,G,G) => G */ 00167 return(g); 00168 00169 if (Cudd_IsConstant(g) && Cudd_IsConstant(h)) 00170 return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */ 00171 /* => DD_NON_CONSTANT */ 00172 00173 if (g == Cudd_Not(h)) 00174 return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */ 00175 /* if F != G and F != G' */ 00176 00177 comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph); 00178 00179 /* Cache lookup. */ 00180 r = cuddConstantLookup(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h); 00181 if (r != NULL) { 00182 return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT)); 00183 } 00184 00185 v = ddMin(topg, toph); 00186 00187 /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */ 00188 if (topf < v && cuddT(f) == one && cuddE(f) == zero) { 00189 return(DD_NON_CONSTANT); 00190 } 00191 00192 /* Compute cofactors. */ 00193 if (topf <= v) { 00194 v = ddMin(topf, v); /* v = top_var(F,G,H) */ 00195 Fv = cuddT(f); Fnv = cuddE(f); 00196 } else { 00197 Fv = Fnv = f; 00198 } 00199 00200 if (topg == v) { 00201 Gv = cuddT(g); Gnv = cuddE(g); 00202 } else { 00203 Gv = Gnv = g; 00204 } 00205 00206 if (toph == v) { 00207 H = Cudd_Regular(h); 00208 Hv = cuddT(H); Hnv = cuddE(H); 00209 if (Cudd_IsComplement(h)) { 00210 Hv = Cudd_Not(Hv); 00211 Hnv = Cudd_Not(Hnv); 00212 } 00213 } else { 00214 Hv = Hnv = h; 00215 } 00216 00217 /* Recursion. */ 00218 t = Cudd_bddIteConstant(dd, Fv, Gv, Hv); 00219 if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) { 00220 cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); 00221 return(DD_NON_CONSTANT); 00222 } 00223 e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv); 00224 if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) { 00225 cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); 00226 return(DD_NON_CONSTANT); 00227 } 00228 cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t); 00229 return(Cudd_NotCond(t,comple)); 00230 00231 } /* end of Cudd_bddIteConstant */
Function********************************************************************
Synopsis [Determines whether f is less than or equal to g.]
Description [Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are created.]
SideEffects [None]
SeeAlso [Cudd_bddIteConstant Cudd_addEvalConst]
Definition at line 468 of file cuddBddIte.c.
00472 { 00473 DdNode *one, *zero, *tmp, *F, *fv, *fvn, *gv, *gvn; 00474 unsigned int topf, topg, res; 00475 00476 statLine(dd); 00477 /* Terminal cases and normalization. */ 00478 if (f == g) return(1); 00479 00480 if (Cudd_IsComplement(g)) { 00481 /* Special case: if f is regular and g is complemented, 00482 ** f(1,...,1) = 1 > 0 = g(1,...,1). 00483 */ 00484 if (!Cudd_IsComplement(f)) return(0); 00485 /* Both are complemented: Swap and complement because 00486 ** f <= g <=> g' <= f' and we want the second argument to be regular. 00487 */ 00488 tmp = g; 00489 g = Cudd_Not(f); 00490 f = Cudd_Not(tmp); 00491 } else if (Cudd_IsComplement(f) && g < f) { 00492 tmp = g; 00493 g = Cudd_Not(f); 00494 f = Cudd_Not(tmp); 00495 } 00496 00497 /* Now g is regular and, if f is not regular, f < g. */ 00498 one = DD_ONE(dd); 00499 if (g == one) return(1); /* no need to test against zero */ 00500 if (f == one) return(0); /* since at this point g != one */ 00501 if (Cudd_Not(f) == g) return(0); /* because neither is constant */ 00502 zero = Cudd_Not(one); 00503 if (f == zero) return(1); 00504 00505 /* Here neither f nor g is constant. */ 00506 00507 /* Check cache. */ 00508 tmp = cuddCacheLookup2(dd,(DdNode * (*)(DdManager *, DdNode *, 00509 DdNode *))Cudd_bddLeq,f,g); 00510 if (tmp != NULL) { 00511 return(tmp == one); 00512 } 00513 00514 /* Compute cofactors. */ 00515 F = Cudd_Regular(f); 00516 topf = dd->perm[F->index]; 00517 topg = dd->perm[g->index]; 00518 if (topf <= topg) { 00519 fv = cuddT(F); fvn = cuddE(F); 00520 if (f != F) { 00521 fv = Cudd_Not(fv); 00522 fvn = Cudd_Not(fvn); 00523 } 00524 } else { 00525 fv = fvn = f; 00526 } 00527 if (topg <= topf) { 00528 gv = cuddT(g); gvn = cuddE(g); 00529 } else { 00530 gv = gvn = g; 00531 } 00532 00533 /* Recursive calls. Since we want to maximize the probability of 00534 ** the special case f(1,...,1) > g(1,...,1), we consider the negative 00535 ** cofactors first. Indeed, the complementation parity of the positive 00536 ** cofactors is the same as the one of the parent functions. 00537 */ 00538 res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv); 00539 00540 /* Store result in cache and return. */ 00541 cuddCacheInsert2(dd,(DdNode * (*)(DdManager *, DdNode *, DdNode *))Cudd_bddLeq,f,g,(res ? one : zero)); 00542 return(res); 00543 00544 } /* end of Cudd_bddLeq */
Function********************************************************************
Synopsis [Computes the NAND of two BDDs f and g.]
Description [Computes the NAND of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNor Cudd_bddXor Cudd_bddXnor]
Definition at line 345 of file cuddBddIte.c.
00349 { 00350 DdNode *res; 00351 00352 do { 00353 dd->reordered = 0; 00354 res = cuddBddAndRecur(dd,f,g); 00355 } while (dd->reordered == 1); 00356 res = Cudd_NotCond(res,res != NULL); 00357 return(res); 00358 00359 } /* end of Cudd_bddNand */
Function********************************************************************
Synopsis [Computes the NOR of two BDDs f and g.]
Description [Computes the NOR of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddXor Cudd_bddXnor]
Definition at line 377 of file cuddBddIte.c.
Function********************************************************************
Synopsis [Computes the disjunction of two BDDs f and g.]
Description [Computes the disjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]
Definition at line 313 of file cuddBddIte.c.
00317 { 00318 DdNode *res; 00319 00320 do { 00321 dd->reordered = 0; 00322 res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); 00323 } while (dd->reordered == 1); 00324 res = Cudd_NotCond(res,res != NULL); 00325 return(res); 00326 00327 } /* end of Cudd_bddOr */
Function********************************************************************
Synopsis [Computes the exclusive NOR of two BDDs f and g.]
Description [Computes the exclusive NOR of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor]
Definition at line 439 of file cuddBddIte.c.
00443 { 00444 DdNode *res; 00445 00446 do { 00447 dd->reordered = 0; 00448 res = cuddBddXorRecur(dd,f,Cudd_Not(g)); 00449 } while (dd->reordered == 1); 00450 return(res); 00451 00452 } /* end of Cudd_bddXnor */
Function********************************************************************
Synopsis [Computes the exclusive OR of two BDDs f and g.]
Description [Computes the exclusive OR of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXnor]
Definition at line 408 of file cuddBddIte.c.
00412 { 00413 DdNode *res; 00414 00415 do { 00416 dd->reordered = 0; 00417 res = cuddBddXorRecur(dd,f,g); 00418 } while (dd->reordered == 1); 00419 return(res); 00420 00421 } /* end of Cudd_bddXor */
Function********************************************************************
Synopsis [Implements the recursive step of Cudd_bddAnd.]
Description [Implements the recursive step of Cudd_bddAnd by taking the conjunction of two BDDs. Returns a pointer to the result is successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddAnd]
Definition at line 819 of file cuddBddIte.c.
00823 { 00824 DdNode *F, *fv, *fnv, *G, *gv, *gnv; 00825 DdNode *one, *r, *t, *e; 00826 unsigned int topf, topg, index; 00827 00828 statLine(manager); 00829 one = DD_ONE(manager); 00830 00831 /* Terminal cases. */ 00832 F = Cudd_Regular(f); 00833 G = Cudd_Regular(g); 00834 if (F == G) { 00835 if (f == g) return(f); 00836 else return(Cudd_Not(one)); 00837 } 00838 if (F == one) { 00839 if (f == one) return(g); 00840 else return(f); 00841 } 00842 if (G == one) { 00843 if (g == one) return(f); 00844 else return(g); 00845 } 00846 00847 /* At this point f and g are not constant. */ 00848 if (f > g) { /* Try to increase cache efficiency. */ 00849 DdNode *tmp = f; 00850 f = g; 00851 g = tmp; 00852 F = Cudd_Regular(f); 00853 G = Cudd_Regular(g); 00854 } 00855 00856 /* Check cache. */ 00857 if (F->ref != 1 || G->ref != 1) { 00858 r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g); 00859 if (r != NULL) return(r); 00860 } 00861 00862 /* Here we can skip the use of cuddI, because the operands are known 00863 ** to be non-constant. 00864 */ 00865 topf = manager->perm[F->index]; 00866 topg = manager->perm[G->index]; 00867 00868 /* Compute cofactors. */ 00869 if (topf <= topg) { 00870 index = F->index; 00871 fv = cuddT(F); 00872 fnv = cuddE(F); 00873 if (Cudd_IsComplement(f)) { 00874 fv = Cudd_Not(fv); 00875 fnv = Cudd_Not(fnv); 00876 } 00877 } else { 00878 index = G->index; 00879 fv = fnv = f; 00880 } 00881 00882 if (topg <= topf) { 00883 gv = cuddT(G); 00884 gnv = cuddE(G); 00885 if (Cudd_IsComplement(g)) { 00886 gv = Cudd_Not(gv); 00887 gnv = Cudd_Not(gnv); 00888 } 00889 } else { 00890 gv = gnv = g; 00891 } 00892 00893 t = cuddBddAndRecur(manager, fv, gv); 00894 if (t == NULL) return(NULL); 00895 cuddRef(t); 00896 00897 e = cuddBddAndRecur(manager, fnv, gnv); 00898 if (e == NULL) { 00899 Cudd_IterDerefBdd(manager, t); 00900 return(NULL); 00901 } 00902 cuddRef(e); 00903 00904 if (t == e) { 00905 r = t; 00906 } else { 00907 if (Cudd_IsComplement(t)) { 00908 r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); 00909 if (r == NULL) { 00910 Cudd_IterDerefBdd(manager, t); 00911 Cudd_IterDerefBdd(manager, e); 00912 return(NULL); 00913 } 00914 r = Cudd_Not(r); 00915 } else { 00916 r = cuddUniqueInter(manager,(int)index,t,e); 00917 if (r == NULL) { 00918 Cudd_IterDerefBdd(manager, t); 00919 Cudd_IterDerefBdd(manager, e); 00920 return(NULL); 00921 } 00922 } 00923 } 00924 cuddDeref(e); 00925 cuddDeref(t); 00926 if (F->ref != 1 || G->ref != 1) 00927 cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r); 00928 return(r); 00929 00930 } /* end of cuddBddAndRecur */
Function********************************************************************
Synopsis [Implements the recursive step of Cudd_bddIntersect.]
Description []
SideEffects [None]
SeeAlso [Cudd_bddIntersect]
Definition at line 704 of file cuddBddIte.c.
00708 { 00709 DdNode *res; 00710 DdNode *F, *G, *t, *e; 00711 DdNode *fv, *fnv, *gv, *gnv; 00712 DdNode *one, *zero; 00713 unsigned int index, topf, topg; 00714 00715 statLine(dd); 00716 one = DD_ONE(dd); 00717 zero = Cudd_Not(one); 00718 00719 /* Terminal cases. */ 00720 if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); 00721 if (f == g || g == one) return(f); 00722 if (f == one) return(g); 00723 00724 /* At this point f and g are not constant. */ 00725 if (f > g) { DdNode *tmp = f; f = g; g = tmp; } 00726 res = cuddCacheLookup2(dd,Cudd_bddIntersect,f,g); 00727 if (res != NULL) return(res); 00728 00729 /* Find splitting variable. Here we can skip the use of cuddI, 00730 ** because the operands are known to be non-constant. 00731 */ 00732 F = Cudd_Regular(f); 00733 topf = dd->perm[F->index]; 00734 G = Cudd_Regular(g); 00735 topg = dd->perm[G->index]; 00736 00737 /* Compute cofactors. */ 00738 if (topf <= topg) { 00739 index = F->index; 00740 fv = cuddT(F); 00741 fnv = cuddE(F); 00742 if (Cudd_IsComplement(f)) { 00743 fv = Cudd_Not(fv); 00744 fnv = Cudd_Not(fnv); 00745 } 00746 } else { 00747 index = G->index; 00748 fv = fnv = f; 00749 } 00750 00751 if (topg <= topf) { 00752 gv = cuddT(G); 00753 gnv = cuddE(G); 00754 if (Cudd_IsComplement(g)) { 00755 gv = Cudd_Not(gv); 00756 gnv = Cudd_Not(gnv); 00757 } 00758 } else { 00759 gv = gnv = g; 00760 } 00761 00762 /* Compute partial results. */ 00763 t = cuddBddIntersectRecur(dd,fv,gv); 00764 if (t == NULL) return(NULL); 00765 cuddRef(t); 00766 if (t != zero) { 00767 e = zero; 00768 } else { 00769 e = cuddBddIntersectRecur(dd,fnv,gnv); 00770 if (e == NULL) { 00771 Cudd_IterDerefBdd(dd, t); 00772 return(NULL); 00773 } 00774 } 00775 cuddRef(e); 00776 00777 if (t == e) { /* both equal zero */ 00778 res = t; 00779 } else if (Cudd_IsComplement(t)) { 00780 res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e)); 00781 if (res == NULL) { 00782 Cudd_IterDerefBdd(dd, t); 00783 Cudd_IterDerefBdd(dd, e); 00784 return(NULL); 00785 } 00786 res = Cudd_Not(res); 00787 } else { 00788 res = cuddUniqueInter(dd,(int)index,t,e); 00789 if (res == NULL) { 00790 Cudd_IterDerefBdd(dd, t); 00791 Cudd_IterDerefBdd(dd, e); 00792 return(NULL); 00793 } 00794 } 00795 cuddDeref(e); 00796 cuddDeref(t); 00797 00798 cuddCacheInsert2(dd,Cudd_bddIntersect,f,g,res); 00799 00800 return(res); 00801 00802 } /* end of cuddBddIntersectRecur */
Function********************************************************************
Synopsis [Implements the recursive step of Cudd_bddIte.]
Description [Implements the recursive step of Cudd_bddIte. Returns a pointer to the resulting BDD. NULL if the intermediate result blows up or if reordering occurs.]
SideEffects [None]
SeeAlso []
Definition at line 566 of file cuddBddIte.c.
00571 { 00572 DdNode *one, *zero, *res; 00573 DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; 00574 unsigned int topf, topg, toph, v; 00575 int index; 00576 int comple; 00577 00578 statLine(dd); 00579 /* Terminal cases. */ 00580 00581 /* One variable cases. */ 00582 if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */ 00583 return(g); 00584 00585 if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */ 00586 return(h); 00587 00588 /* From now on, f is known not to be a constant. */ 00589 if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ 00590 if (h == zero) { /* ITE(F,1,0) = F */ 00591 return(f); 00592 } else { 00593 res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h)); 00594 return(Cudd_NotCond(res,res != NULL)); 00595 } 00596 } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ 00597 if (h == one) { /* ITE(F,0,1) = !F */ 00598 return(Cudd_Not(f)); 00599 } else { 00600 res = cuddBddAndRecur(dd,Cudd_Not(f),h); 00601 return(res); 00602 } 00603 } 00604 if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ 00605 res = cuddBddAndRecur(dd,f,g); 00606 return(res); 00607 } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ 00608 res = cuddBddAndRecur(dd,f,Cudd_Not(g)); 00609 return(Cudd_NotCond(res,res != NULL)); 00610 } 00611 00612 /* Check remaining one variable case. */ 00613 if (g == h) { /* ITE(F,G,G) = G */ 00614 return(g); 00615 } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */ 00616 res = cuddBddXorRecur(dd,f,h); 00617 return(res); 00618 } 00619 00620 /* From here, there are no constants. */ 00621 comple = bddVarToCanonicalSimple(dd, &f, &g, &h, &topf, &topg, &toph); 00622 00623 /* f & g are now regular pointers */ 00624 00625 v = ddMin(topg, toph); 00626 00627 /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */ 00628 if (topf < v && cuddT(f) == one && cuddE(f) == zero) { 00629 r = cuddUniqueInter(dd, (int) f->index, g, h); 00630 return(Cudd_NotCond(r,comple && r != NULL)); 00631 } 00632 00633 /* Check cache. */ 00634 r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h); 00635 if (r != NULL) { 00636 return(Cudd_NotCond(r,comple)); 00637 } 00638 00639 /* Compute cofactors. */ 00640 if (topf <= v) { 00641 v = ddMin(topf, v); /* v = top_var(F,G,H) */ 00642 index = f->index; 00643 Fv = cuddT(f); Fnv = cuddE(f); 00644 } else { 00645 Fv = Fnv = f; 00646 } 00647 if (topg == v) { 00648 index = g->index; 00649 Gv = cuddT(g); Gnv = cuddE(g); 00650 } else { 00651 Gv = Gnv = g; 00652 } 00653 if (toph == v) { 00654 H = Cudd_Regular(h); 00655 index = H->index; 00656 Hv = cuddT(H); Hnv = cuddE(H); 00657 if (Cudd_IsComplement(h)) { 00658 Hv = Cudd_Not(Hv); 00659 Hnv = Cudd_Not(Hnv); 00660 } 00661 } else { 00662 Hv = Hnv = h; 00663 } 00664 00665 /* Recursive step. */ 00666 t = cuddBddIteRecur(dd,Fv,Gv,Hv); 00667 if (t == NULL) return(NULL); 00668 cuddRef(t); 00669 00670 e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv); 00671 if (e == NULL) { 00672 Cudd_IterDerefBdd(dd,t); 00673 return(NULL); 00674 } 00675 cuddRef(e); 00676 00677 r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); 00678 if (r == NULL) { 00679 Cudd_IterDerefBdd(dd,t); 00680 Cudd_IterDerefBdd(dd,e); 00681 return(NULL); 00682 } 00683 cuddDeref(t); 00684 cuddDeref(e); 00685 00686 cuddCacheInsert(dd, DD_BDD_ITE_TAG, f, g, h, r); 00687 return(Cudd_NotCond(r,comple)); 00688 00689 } /* end of cuddBddIteRecur */
Function********************************************************************
Synopsis [Implements the recursive step of Cudd_bddXor.]
Description [Implements the recursive step of Cudd_bddXor by taking the exclusive OR of two BDDs. Returns a pointer to the result is successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddXor]
Definition at line 947 of file cuddBddIte.c.
00951 { 00952 DdNode *fv, *fnv, *G, *gv, *gnv; 00953 DdNode *one, *zero, *r, *t, *e; 00954 unsigned int topf, topg, index; 00955 00956 statLine(manager); 00957 one = DD_ONE(manager); 00958 zero = Cudd_Not(one); 00959 00960 /* Terminal cases. */ 00961 if (f == g) return(zero); 00962 if (f == Cudd_Not(g)) return(one); 00963 if (f > g) { /* Try to increase cache efficiency and simplify tests. */ 00964 DdNode *tmp = f; 00965 f = g; 00966 g = tmp; 00967 } 00968 if (g == zero) return(f); 00969 if (g == one) return(Cudd_Not(f)); 00970 if (Cudd_IsComplement(f)) { 00971 f = Cudd_Not(f); 00972 g = Cudd_Not(g); 00973 } 00974 /* Now the first argument is regular. */ 00975 if (f == one) return(Cudd_Not(g)); 00976 00977 /* At this point f and g are not constant. */ 00978 00979 /* Check cache. */ 00980 r = cuddCacheLookup2(manager, Cudd_bddXor, f, g); 00981 if (r != NULL) return(r); 00982 00983 /* Here we can skip the use of cuddI, because the operands are known 00984 ** to be non-constant. 00985 */ 00986 topf = manager->perm[f->index]; 00987 G = Cudd_Regular(g); 00988 topg = manager->perm[G->index]; 00989 00990 /* Compute cofactors. */ 00991 if (topf <= topg) { 00992 index = f->index; 00993 fv = cuddT(f); 00994 fnv = cuddE(f); 00995 } else { 00996 index = G->index; 00997 fv = fnv = f; 00998 } 00999 01000 if (topg <= topf) { 01001 gv = cuddT(G); 01002 gnv = cuddE(G); 01003 if (Cudd_IsComplement(g)) { 01004 gv = Cudd_Not(gv); 01005 gnv = Cudd_Not(gnv); 01006 } 01007 } else { 01008 gv = gnv = g; 01009 } 01010 01011 t = cuddBddXorRecur(manager, fv, gv); 01012 if (t == NULL) return(NULL); 01013 cuddRef(t); 01014 01015 e = cuddBddXorRecur(manager, fnv, gnv); 01016 if (e == NULL) { 01017 Cudd_IterDerefBdd(manager, t); 01018 return(NULL); 01019 } 01020 cuddRef(e); 01021 01022 if (t == e) { 01023 r = t; 01024 } else { 01025 if (Cudd_IsComplement(t)) { 01026 r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); 01027 if (r == NULL) { 01028 Cudd_IterDerefBdd(manager, t); 01029 Cudd_IterDerefBdd(manager, e); 01030 return(NULL); 01031 } 01032 r = Cudd_Not(r); 01033 } else { 01034 r = cuddUniqueInter(manager,(int)index,t,e); 01035 if (r == NULL) { 01036 Cudd_IterDerefBdd(manager, t); 01037 Cudd_IterDerefBdd(manager, e); 01038 return(NULL); 01039 } 01040 } 01041 } 01042 cuddDeref(e); 01043 cuddDeref(t); 01044 cuddCacheInsert2(manager, Cudd_bddXor, f, g, r); 01045 return(r); 01046 01047 } /* end of cuddBddXorRecur */
char rcsid [] DD_UNUSED = "$Id: cuddBddIte.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $" [static] |
CFile***********************************************************************
FileName [cuddBddIte.c]
PackageName [cudd]
Synopsis [BDD ITE function and satellites.]
Description [External procedures included in this module:
Internal procedures included in this module:
Static procedures included in this module:
]
SeeAlso []
Author [Fabio Somenzi]
Copyright [This file was created at the University of Colorado at Boulder. The University of Colorado at Boulder makes no warranty about the suitability of this software for any purpose. It is presented on an AS IS basis.]
Definition at line 71 of file cuddBddIte.c.