/**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 [BDD restrict according to Coudert and Madre's algorithm (ICCAD90).] Description [BDD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns the restricted BDD if successful; otherwise NULL.] SideEffects [None] SeeAlso [Cudd_bddRestrict] ******************************************************************************/ DdNode* Cuddaux_bddRestrict(DdManager * dd, DdNode * f, DdNode * c) { DdNode *one,*zero; DdNode *suppF, *suppC, *commonSupp, *onlyC; DdNode *cplus, *res; int retval; one = DD_ONE(dd); zero = Cudd_Not(one); /* Check terminal cases here to avoid computing supports in trivial cases. ** This also allows us notto check later for the case c == 0, in which ** there is no common support. */ if (c == one) return(f); if (c == zero){ fprintf(stderr,"Cuddaux_bddRestrict: warning: false careset\n"); return(zero); } if (Cudd_IsConstant(f)) return(f); if (f == c) return(one); if (f == Cudd_Not(c)) return(zero); /* Check if supports intersect. */ suppF = Cuddaux_Support(dd,f); if (suppF==NULL) return(NULL); cuddRef(suppF); suppC = Cuddaux_Support(dd,c); if (suppC==NULL){ Cudd_IterDerefBdd(dd,suppF); return(NULL); } cuddRef(suppC); commonSupp = Cudd_bddLiteralSetIntersection(dd,suppF,suppC); if (commonSupp==NULL){ Cudd_IterDerefBdd(dd,suppF); Cudd_IterDerefBdd(dd,suppC); return(NULL); } if (commonSupp == one) { Cudd_IterDerefBdd(dd,suppF); Cudd_IterDerefBdd(dd,suppC); return(f); } cuddRef(commonSupp); Cudd_IterDerefBdd(dd,suppF); /* Abstract from c the variables that do not appear in f. */ onlyC = Cudd_Cofactor(dd,suppC,commonSupp); if (onlyC == NULL) { Cudd_IterDerefBdd(dd,suppC); Cudd_IterDerefBdd(dd,commonSupp); return(NULL); } cuddRef(onlyC); Cudd_IterDerefBdd(dd,suppC); Cudd_IterDerefBdd(dd,commonSupp); cplus = Cudd_bddExistAbstract(dd, c, onlyC); if (cplus == NULL) { Cudd_IterDerefBdd(dd,onlyC); return(NULL); } cuddRef(cplus); Cudd_IterDerefBdd(dd,onlyC); do { dd->reordered = 0; res = cuddBddRestrictRecur(dd, f, cplus); } while (dd->reordered == 1); if (res == NULL) { Cudd_IterDerefBdd(dd,cplus); return(NULL); } cuddRef(res); Cudd_IterDerefBdd(dd,cplus); cuddDeref(res); return(res); } /* end of Cuddaux_bddRestrict */