/**Function******************************************************************** Synopsis [Computes the cofactor of f with respect to g.] Description [Computes the cofactor of f with respect to g; g must be the BDD or the ADD of a cube. Returns a pointer to the cofactor if successful; NULL otherwise.] SideEffects [None] SeeAlso [Cudd_bddConstrain Cudd_bddRestrict] ******************************************************************************/ DdNode * Cudd_Cofactor( DdManager * dd, DdNode * f, DdNode * g) { DdNode *res,*_false; /* NuSMV: begin add */ abort(); /* NOT USED BY NUSMV */ /* NuSMV: begin end */ _false = Cudd_Not(DD_TRUE(dd)); if (g == _false || g == DD_FALSE(dd)) { (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n"); dd->errorCode = CUDD_INVALID_ARG; return(NULL); } do { dd->reordered = 0; res = cuddCofactorRecur(dd,f,g); } while (dd->reordered == 1); return(res); } /* end of Cudd_Cofactor */
/**Function******************************************************************** Synopsis [Computes the cofactor of f with respect to g.] Description [Computes the cofactor of f with respect to g; g must be the BDD or the ADD of a cube. Returns a pointer to the cofactor if successful; NULL otherwise.] SideEffects [None] SeeAlso [Cudd_bddConstrain Cudd_bddRestrict] ******************************************************************************/ DdNode * Cudd_Cofactor( DdManager * dd, DdNode * f, DdNode * g) { DdNode *res,*zero; zero = Cudd_Not(DD_ONE(dd)); if (g == zero || g == DD_ZERO(dd)) { (void) fprintf(stdout,"Cudd_Cofactor: Invalid restriction 1\n"); return(NULL); } do { dd->reordered = 0; res = cuddCofactorRecur(dd,f,g); } while (dd->reordered == 1); return(res); } /* end of Cudd_Cofactor */
/**Function******************************************************************** Synopsis [Implements the recursive step of Cudd_SolveEqn.] Description [Implements the recursive step of Cudd_SolveEqn. Returns NULL if the intermediate solution blows up or reordering occurs. The parametric solutions are stored in the array G.] SideEffects [none] SeeAlso [Cudd_SolveEqn, Cudd_VerifySol] ******************************************************************************/ DdNode * cuddSolveEqnRecur( DdManager * bdd, DdNode * F /* the left-hand side of the equation */, DdNode * Y /* the cube of remaining y variables */, DdNode ** G /* the array of solutions */, int n /* number of unknowns */, int * yIndex /* array holding the y variable indices */, int i /* level of recursion */) { DdNode *Fn, *Fm1, *Fv, *Fvbar, *T, *w, *nextY, *one; DdNodePtr *variables; int j; statLine(bdd); variables = bdd->vars; one = DD_ONE(bdd); /* Base condition. */ if (Y == one) { return F; } /* Cofactor of Y. */ yIndex[i] = Y->index; nextY = Cudd_T(Y); /* Universal abstraction of F with respect to the top variable index. */ Fm1 = cuddBddExistAbstractRecur(bdd, Cudd_Not(F), variables[yIndex[i]]); if (Fm1) { Fm1 = Cudd_Not(Fm1); cuddRef(Fm1); } else { return(NULL); } Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1); if (Fn) { cuddRef(Fn); } else { Cudd_RecursiveDeref(bdd, Fm1); return(NULL); } Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]); if (Fv) { cuddRef(Fv); } else { Cudd_RecursiveDeref(bdd, Fm1); Cudd_RecursiveDeref(bdd, Fn); return(NULL); } Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]])); if (Fvbar) { cuddRef(Fvbar); } else { Cudd_RecursiveDeref(bdd, Fm1); Cudd_RecursiveDeref(bdd, Fn); Cudd_RecursiveDeref(bdd, Fv); return(NULL); } /* Build i-th component of the solution. */ w = cuddBddIteRecur(bdd, variables[yIndex[i]], Cudd_Not(Fv), Fvbar); if (w) { cuddRef(w); } else { Cudd_RecursiveDeref(bdd, Fm1); Cudd_RecursiveDeref(bdd, Fn); Cudd_RecursiveDeref(bdd, Fv); Cudd_RecursiveDeref(bdd, Fvbar); return(NULL); } T = cuddBddRestrictRecur(bdd, w, Cudd_Not(Fm1)); if(T) { cuddRef(T); } else { Cudd_RecursiveDeref(bdd, Fm1); Cudd_RecursiveDeref(bdd, Fn); Cudd_RecursiveDeref(bdd, Fv); Cudd_RecursiveDeref(bdd, Fvbar); Cudd_RecursiveDeref(bdd, w); return(NULL); } Cudd_RecursiveDeref(bdd,Fm1); Cudd_RecursiveDeref(bdd,w); Cudd_RecursiveDeref(bdd,Fv); Cudd_RecursiveDeref(bdd,Fvbar); /* Substitute components of solution already found into solution. */ for (j = n-1; j > i; j--) { w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]); if(w) { cuddRef(w); } else { Cudd_RecursiveDeref(bdd, Fn); Cudd_RecursiveDeref(bdd, T); return(NULL); } Cudd_RecursiveDeref(bdd,T); T = w; } G[i] = T; Cudd_Deref(Fn); return(Fn); } /* end of cuddSolveEqnRecur */
/**Function******************************************************************** Synopsis [Performs the recursive step of Cudd_Cofactor.] Description [Performs the recursive step of Cudd_Cofactor. Returns a pointer to the cofactor if successful; NULL otherwise.] SideEffects [None] SeeAlso [Cudd_Cofactor] ******************************************************************************/ DdNode * cuddCofactorRecur( DdManager * dd, DdNode * f, DdNode * g) { DdNode *one,*zero,*F,*G,*g1,*g0,*f1,*f0,*t,*e,*r; unsigned int topf,topg; int comple; F = Cudd_Regular(f); if (cuddIsConstant(F)) return(f); one = DD_ONE(dd); /* The invariant g != 0 is true on entry to this procedure and is ** recursively maintained by it. Therefore it suffices to test g ** against one to make sure it is not constant. */ if (g == one) return(f); /* From now on, f and g are known not to be constants. */ comple = f != F; r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g); if (r != NULL) { return(Cudd_NotCond(r,comple)); } topf = dd->perm[F->index]; G = Cudd_Regular(g); topg = dd->perm[G->index]; /* We take the cofactors of F because we are going to rely on ** the fact that the cofactors of the complement are the complements ** of the cofactors to better utilize the cache. Variable comple ** remembers whether we have to complement the result or not. */ if (topf <= topg) { f1 = cuddT(F); f0 = cuddE(F); } else { f1 = f0 = F; } if (topg <= topf) { g1 = cuddT(G); g0 = cuddE(G); if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); } } else { g1 = g0 = g; } zero = Cudd_Not(one); if (topf >= topg) { if (g0 == zero || g0 == DD_ZERO(dd)) { r = cuddCofactorRecur(dd, f1, g1); } else if (g1 == zero || g1 == DD_ZERO(dd)) { r = cuddCofactorRecur(dd, f0, g0); } else { (void) fprintf(stdout,"Cudd_Cofactor: Invalid restriction 2\n"); return(NULL); } if (r == NULL) return(NULL); } else /* if (topf < topg) */ { t = cuddCofactorRecur(dd, f1, g); if (t == NULL) return(NULL); cuddRef(t); e = cuddCofactorRecur(dd, f0, g); if (e == NULL) { Cudd_RecursiveDeref(dd, t); return(NULL); } cuddRef(e); if (t == e) { r = t; } else if (Cudd_IsComplement(t)) { r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e)); if (r != NULL) r = Cudd_Not(r); } else { r = cuddUniqueInter(dd,(int)F->index,t,e); } if (r == NULL) { Cudd_RecursiveDeref(dd ,e); Cudd_RecursiveDeref(dd ,t); return(NULL); } cuddDeref(t); cuddDeref(e); } cuddCacheInsert2(dd,Cudd_Cofactor,F,g,r); return(Cudd_NotCond(r,comple)); } /* end of cuddCofactorRecur */