📄 cuddbddite.c
字号:
if (f == one) return(g); else return(f); } if (G == one) { if (g == one) return(f); else return(g); } /* At this point f and g are not constant. */ if (f > g) { /* Try to increase cache efficiency. */ DdNode *tmp = f; f = g; g = tmp; F = Cudd_Regular(f); G = Cudd_Regular(g); } /* Check cache. */ if (F->ref != 1 || G->ref != 1) { r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g); if (r != NULL) return(r); } /* Here we can skip the use of cuddI, because the operands are known ** to be non-constant. */ topf = manager->perm[F->index]; topg = manager->perm[G->index]; /* Compute cofactors. */ if (topf <= topg) { index = F->index; fv = cuddT(F); fnv = cuddE(F); if (Cudd_IsComplement(f)) { fv = Cudd_Not(fv); fnv = Cudd_Not(fnv); } } else { index = G->index; fv = fnv = f; } if (topg <= topf) { gv = cuddT(G); gnv = cuddE(G); if (Cudd_IsComplement(g)) { gv = Cudd_Not(gv); gnv = Cudd_Not(gnv); } } else { gv = gnv = g; } t = cuddBddAndRecur(manager, fv, gv); if (t == NULL) return(NULL); cuddRef(t); e = cuddBddAndRecur(manager, fnv, gnv); if (e == NULL) { Cudd_IterDerefBdd(manager, t); return(NULL); } cuddRef(e); if (t == e) { r = t; } else { if (Cudd_IsComplement(t)) { r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); if (r == NULL) { Cudd_IterDerefBdd(manager, t); Cudd_IterDerefBdd(manager, e); return(NULL); } r = Cudd_Not(r); } else { r = cuddUniqueInter(manager,(int)index,t,e); if (r == NULL) { Cudd_IterDerefBdd(manager, t); Cudd_IterDerefBdd(manager, e); return(NULL); } } } cuddDeref(e); cuddDeref(t); if (F->ref != 1 || G->ref != 1) cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r); return(r);} /* end of cuddBddAndRecur *//**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]******************************************************************************/DdNode *cuddBddXorRecur( DdManager * manager, DdNode * f, DdNode * g){ DdNode *fv, *fnv, *G, *gv, *gnv; DdNode *one, *zero, *r, *t, *e; unsigned int topf, topg, index; statLine(manager); one = DD_ONE(manager); zero = Cudd_Not(one); /* Terminal cases. */ if (f == g) return(zero); if (f == Cudd_Not(g)) return(one); if (f > g) { /* Try to increase cache efficiency and simplify tests. */ DdNode *tmp = f; f = g; g = tmp; } if (g == zero) return(f); if (g == one) return(Cudd_Not(f)); if (Cudd_IsComplement(f)) { f = Cudd_Not(f); g = Cudd_Not(g); } /* Now the first argument is regular. */ if (f == one) return(Cudd_Not(g)); /* At this point f and g are not constant. */ /* Check cache. */ r = cuddCacheLookup2(manager, Cudd_bddXor, f, g); if (r != NULL) return(r); /* Here we can skip the use of cuddI, because the operands are known ** to be non-constant. */ topf = manager->perm[f->index]; G = Cudd_Regular(g); topg = manager->perm[G->index]; /* Compute cofactors. */ if (topf <= topg) { index = f->index; fv = cuddT(f); fnv = cuddE(f); } else { index = G->index; fv = fnv = f; } if (topg <= topf) { gv = cuddT(G); gnv = cuddE(G); if (Cudd_IsComplement(g)) { gv = Cudd_Not(gv); gnv = Cudd_Not(gnv); } } else { gv = gnv = g; } t = cuddBddXorRecur(manager, fv, gv); if (t == NULL) return(NULL); cuddRef(t); e = cuddBddXorRecur(manager, fnv, gnv); if (e == NULL) { Cudd_IterDerefBdd(manager, t); return(NULL); } cuddRef(e); if (t == e) { r = t; } else { if (Cudd_IsComplement(t)) { r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); if (r == NULL) { Cudd_IterDerefBdd(manager, t); Cudd_IterDerefBdd(manager, e); return(NULL); } r = Cudd_Not(r); } else { r = cuddUniqueInter(manager,(int)index,t,e); if (r == NULL) { Cudd_IterDerefBdd(manager, t); Cudd_IterDerefBdd(manager, e); return(NULL); } } } cuddDeref(e); cuddDeref(t); cuddCacheInsert2(manager, Cudd_bddXor, f, g, r); return(r);} /* end of cuddBddXorRecur *//*---------------------------------------------------------------------------*//* Definition of static functions *//*---------------------------------------------------------------------------*//**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]******************************************************************************/static voidbddVarToConst( DdNode * f, DdNode ** gp, DdNode ** hp, DdNode * one){ DdNode *g = *gp; DdNode *h = *hp; if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ *gp = one; } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ *gp = Cudd_Not(one); } if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ *hp = Cudd_Not(one); } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ *hp = one; }} /* end of bddVarToConst *//**Function******************************************************************** Synopsis [Picks unique member from equiv expressions.] Description [Reduces 2 variable expressions to canonical form.] SideEffects [None] SeeAlso [bddVarToConst bddVarToCanonicalSimple]******************************************************************************/static intbddVarToCanonical( DdManager * dd, DdNode ** fp, DdNode ** gp, DdNode ** hp, unsigned int * topfp, unsigned int * topgp, unsigned int * tophp){ register DdNode *F, *G, *H, *r, *f, *g, *h; register unsigned int topf, topg, toph; DdNode *one = dd->one; int comple, change; f = *fp; g = *gp; h = *hp; F = Cudd_Regular(f); G = Cudd_Regular(g); H = Cudd_Regular(h); topf = cuddI(dd,F->index); topg = cuddI(dd,G->index); toph = cuddI(dd,H->index); change = 0; if (G == one) { /* ITE(F,c,H) */ if ((topf > toph) || (topf == toph && f > h)) { r = h; h = f; f = r; /* ITE(F,1,H) = ITE(H,1,F) */ if (g != one) { /* g == zero */ f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */ h = Cudd_Not(h); } change = 1; } } else if (H == one) { /* ITE(F,G,c) */ if ((topf > topg) || (topf == topg && f > g)) { r = g; g = f; f = r; /* ITE(F,G,0) = ITE(G,F,0) */ if (h == one) { f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */ g = Cudd_Not(g); } change = 1; } } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */ if ((topf > topg) || (topf == topg && f > g)) { r = f; f = g; g = r; h = Cudd_Not(r); change = 1; } } /* adjust pointers so that the first 2 arguments to ITE are regular */ if (Cudd_IsComplement(f) != 0) { /* ITE(!F,G,H) = ITE(F,H,G) */ f = Cudd_Not(f); r = g; g = h; h = r; change = 1; } comple = 0; if (Cudd_IsComplement(g) != 0) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ g = Cudd_Not(g); h = Cudd_Not(h); change = 1; comple = 1; } if (change != 0) { *fp = f; *gp = g; *hp = h; } *topfp = cuddI(dd,f->index); *topgp = cuddI(dd,g->index); *tophp = cuddI(dd,Cudd_Regular(h)->index); return(comple);} /* end of bddVarToCanonical *//**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]******************************************************************************/static intbddVarToCanonicalSimple( DdManager * dd, DdNode ** fp, DdNode ** gp, DdNode ** hp, unsigned int * topfp, unsigned int * topgp, unsigned int * tophp){ register DdNode *r, *f, *g, *h; int comple, change; f = *fp; g = *gp; h = *hp; change = 0; /* adjust pointers so that the first 2 arguments to ITE are regular */ if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */ f = Cudd_Not(f); r = g; g = h; h = r; change = 1; } comple = 0; if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ g = Cudd_Not(g); h = Cudd_Not(h); change = 1; comple = 1; } if (change) { *fp = f; *gp = g; *hp = h; } /* Here we can skip the use of cuddI, because the operands are known ** to be non-constant. */ *topfp = dd->perm[f->index]; *topgp = dd->perm[g->index]; *tophp = dd->perm[Cudd_Regular(h)->index]; return(comple);} /* end of bddVarToCanonicalSimple */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -