/**Function******************************************************************** Synopsis [Finds the maximum discriminant of f.] Description [Returns a pointer to a constant ADD.] SideEffects [None] ******************************************************************************/ DdNode * Cudd_addFindMax( DdManager * dd, DdNode * f) { DdNode *t, *e, *res; statLine(dd); if (cuddIsConstant(f)) { return(f); } res = cuddCacheLookup1(dd,Cudd_addFindMax,f); if (res != NULL) { return(res); } t = Cudd_addFindMax(dd,cuddT(f)); if (t == DD_PLUS_INFINITY(dd)) return(t); e = Cudd_addFindMax(dd,cuddE(f)); res = (cuddV(t) >= cuddV(e)) ? t : e; cuddCacheInsert1(dd,Cudd_addFindMax,f,res); return(res); } /* end of Cudd_addFindMax */
/**Function******************************************************************** Synopsis [Performs the recursive step of Cuddaux_Support.] Description [Performs the recursive step of Cuddaux_Support.] SideEffects [None] SeeAlso [] ******************************************************************************/ DdNode* cuddauxSupportRecur(DdManager* dd, DdNode * f) { DdNode *one, *fv, *fvn, *T,*E, *res, *res1; one = DD_ONE(dd); if (cuddIsConstant(f)) { return one; } fv = cuddT(f); fvn = Cudd_Regular(cuddE(f)); if (cuddIsConstant(fv) && cuddIsConstant(fvn)){ return dd->vars[f->index]; } /* Look in the cache */ res = cuddCacheLookup1(dd,Cuddaux_Support,f); if (res != NULL) return(res); T = cuddIsConstant(fv) ? one : cuddauxSupportRecur(dd,fv); if (T == NULL) return(NULL); cuddRef(T); E = cuddIsConstant(fvn) ? one : cuddauxSupportRecur(dd,fvn); if (E == NULL){ Cudd_IterDerefBdd(dd,T); return(NULL); } if (T==E){ res = cuddUniqueInter(dd,f->index,T,Cudd_Not(one)); if (res == NULL){ Cudd_IterDerefBdd(dd,T); return NULL; } cuddDeref(T); } else { cuddRef(E); res1 = cuddBddAndRecur(dd,T,E); if (res1 == NULL){ Cudd_IterDerefBdd(dd,T); Cudd_IterDerefBdd(dd,E); return(NULL); } cuddRef(res1); Cudd_IterDerefBdd(dd,T); Cudd_IterDerefBdd(dd,E); res = cuddUniqueInter(dd,f->index,res1,Cudd_Not(one)); if (res == NULL){ Cudd_IterDerefBdd(dd,T); Cudd_IterDerefBdd(dd,E); Cudd_IterDerefBdd(dd,res1); return(NULL); } cuddDeref(res1); } cuddCacheInsert1(dd,Cuddaux_Support,f,res); return(res); } /* end of cuddauxSupportRecur */
/**Function************************************************************* Synopsis [Performs the recursive step of Extra_bddSpaceCanonVars().] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * extraBddSpaceCanonVars( DdManager * dd, DdNode * bF ) { DdNode * bRes, * bFR; statLine( dd ); bFR = Cudd_Regular(bF); if ( cuddIsConstant(bFR) ) return bF; if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceCanonVars, bF)) ) return bRes; else { DdNode * bF0, * bF1; DdNode * bRes, * bRes0; if ( bFR != bF ) // bF is complemented { bF0 = Cudd_Not( cuddE(bFR) ); bF1 = Cudd_Not( cuddT(bFR) ); } else { bF0 = cuddE(bFR); bF1 = cuddT(bFR); } if ( bF0 == b0 ) { bRes = extraBddSpaceCanonVars( dd, bF1 ); if ( bRes == NULL ) return NULL; } else if ( bF1 == b0 ) { bRes = extraBddSpaceCanonVars( dd, bF0 ); if ( bRes == NULL ) return NULL; } else { bRes0 = extraBddSpaceCanonVars( dd, bF0 ); if ( bRes0 == NULL ) return NULL; cuddRef( bRes0 ); bRes = cuddUniqueInter( dd, bFR->index, bRes0, b0 ); if ( bRes == NULL ) { Cudd_RecursiveDeref( dd,bRes0 ); return NULL; } cuddDeref( bRes0 ); } cuddCacheInsert1( dd, extraBddSpaceCanonVars, bF, bRes ); return bRes; } }
/**Function******************************************************************** Synopsis [Implements the recursive step of Cudd_bddVarMap.] Description [Implements the recursive step of Cudd_bddVarMap. Returns a pointer to the result if successful; NULL otherwise.] SideEffects [None] SeeAlso [Cudd_bddVarMap] ******************************************************************************/ static DdNode * cuddBddVarMapRecur( DdManager *manager /* DD manager */, DdNode *f /* BDD to be remapped */) { DdNode *F, *T, *E; DdNode *res; int index; statLine(manager); F = Cudd_Regular(f); /* Check for terminal case of constant node. */ if (cuddIsConstant(F)) { return(f); } /* If problem already solved, look up answer and return. */ if (F->ref != 1 && (res = cuddCacheLookup1(manager,Cudd_bddVarMap,F)) != NULL) { return(Cudd_NotCond(res,F != f)); } /* Split and recur on children of this node. */ T = cuddBddVarMapRecur(manager,cuddT(F)); if (T == NULL) return(NULL); cuddRef(T); E = cuddBddVarMapRecur(manager,cuddE(F)); if (E == NULL) { Cudd_IterDerefBdd(manager, T); return(NULL); } cuddRef(E); /* Move variable that should be in this position to this position ** by retrieving the single var BDD for that variable, and calling ** cuddBddIteRecur with the T and E we just created. */ index = manager->map[F->index]; res = cuddBddIteRecur(manager,manager->vars[index],T,E); if (res == NULL) { Cudd_IterDerefBdd(manager, T); Cudd_IterDerefBdd(manager, E); return(NULL); } cuddRef(res); Cudd_IterDerefBdd(manager, T); Cudd_IterDerefBdd(manager, E); /* Do not keep the result if the reference count is only 1, since ** it will not be visited again. */ if (F->ref != 1) { cuddCacheInsert1(manager,Cudd_bddVarMap,F,res); } cuddDeref(res); return(Cudd_NotCond(res,F != f)); } /* end of cuddBddVarMapRecur */
/**Function******************************************************************** Synopsis [Performs the recursive step of Cudd_addMonadicApply.] Description [Performs the recursive step of Cudd_addMonadicApply. Returns a pointer to the result if successful; NULL otherwise.] SideEffects [None] SeeAlso [cuddAddApplyRecur] ******************************************************************************/ DdNode * cuddAddMonadicApplyRecur( DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f) { DdNode *res, *ft, *fe, *T, *E; unsigned int ford; unsigned int index; /* Check terminal cases. */ statLine(dd); res = (*op)(dd,f); if (res != NULL) return(res); /* Check cache. */ res = cuddCacheLookup1(dd,op,f); if (res != NULL) return(res); /* Recursive step. */ ford = cuddI(dd,f->index); index = f->index; ft = cuddT(f); fe = cuddE(f); T = cuddAddMonadicApplyRecur(dd,op,ft); if (T == NULL) return(NULL); cuddRef(T); E = cuddAddMonadicApplyRecur(dd,op,fe); if (E == NULL) { Cudd_RecursiveDeref(dd,T); return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); if (res == NULL) { Cudd_RecursiveDeref(dd, T); Cudd_RecursiveDeref(dd, E); return(NULL); } cuddDeref(T); cuddDeref(E); /* Store result. */ cuddCacheInsert1(dd,op,f,res); return(res); } /* end of cuddAddMonadicApplyRecur */
/** @brief Implements the recursive step of Cudd_addRoundOff. @return a pointer to the result. @sideeffect None */ DdNode * cuddAddRoundOffRecur( DdManager * dd, DdNode * f, double trunc) { DdNode *res, *fv, *fvn, *T, *E; double n; DD_CTFP1 cacheOp; statLine(dd); if (cuddIsConstant(f)) { n = ceil(cuddV(f)*trunc)/trunc; res = cuddUniqueConst(dd,n); return(res); } cacheOp = (DD_CTFP1) Cudd_addRoundOff; res = cuddCacheLookup1(dd,cacheOp,f); if (res != NULL) { return(res); } checkWhetherToGiveUp(dd); /* Recursive Step */ fv = cuddT(f); fvn = cuddE(f); T = cuddAddRoundOffRecur(dd,fv,trunc); if (T == NULL) { return(NULL); } cuddRef(T); E = cuddAddRoundOffRecur(dd,fvn,trunc); if (E == NULL) { Cudd_RecursiveDeref(dd,T); return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); if (res == NULL) { Cudd_RecursiveDeref(dd,T); Cudd_RecursiveDeref(dd,E); return(NULL); } cuddDeref(T); cuddDeref(E); /* Store result. */ cuddCacheInsert1(dd,cacheOp,f,res); return(res); } /* end of cuddAddRoundOffRecur */
DdNode * cuddAddMonadicApplyWithDataRecur( DdManager * dd, DD_MAOPD op, DdNode * f, void * data) { DdNode *res, *ft, *fe, *T, *E; unsigned int index; /* Check terminal cases. */ statLine(dd); res = (*op)(dd,f, data); if (res != NULL) return(res); /* Check cache. */ res = cuddCacheLookup1(dd,(DD_MAOP)global_bloody_counter_unary,f); if (res != NULL) return(res); /* Recursive step. */ index = f->index; ft = cuddT(f); fe = cuddE(f); T = cuddAddMonadicApplyWithDataRecur(dd,op,ft, data); if (T == NULL) return(NULL); cuddRef(T); E = cuddAddMonadicApplyWithDataRecur(dd,op,fe, data); if (E == NULL) { Cudd_RecursiveDeref(dd,T); return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); if (res == NULL) { Cudd_RecursiveDeref(dd, T); Cudd_RecursiveDeref(dd, E); return(NULL); } cuddDeref(T); cuddDeref(E); /* Store result. */ cuddCacheInsert1(dd,(DD_MAOP)global_bloody_counter_unary,f,res); return(res); } /* end of cuddAddMonadicApplyWithDataRecur */
/** @brief Implements the recursive step of Cudd_addNegate. @return a pointer to the result. @sideeffect None */ DdNode * cuddAddNegateRecur( DdManager * dd, DdNode * f) { DdNode *res, *fv, *fvn, *T, *E; statLine(dd); /* Check terminal cases. */ if (cuddIsConstant(f)) { res = cuddUniqueConst(dd,-cuddV(f)); return(res); } /* Check cache */ res = cuddCacheLookup1(dd,Cudd_addNegate,f); if (res != NULL) return(res); checkWhetherToGiveUp(dd); /* Recursive Step */ fv = cuddT(f); fvn = cuddE(f); T = cuddAddNegateRecur(dd,fv); if (T == NULL) return(NULL); cuddRef(T); E = cuddAddNegateRecur(dd,fvn); if (E == NULL) { Cudd_RecursiveDeref(dd,T); return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); if (res == NULL) { Cudd_RecursiveDeref(dd, T); Cudd_RecursiveDeref(dd, E); return(NULL); } cuddDeref(T); cuddDeref(E); /* Store result. */ cuddCacheInsert1(dd,Cudd_addNegate,f,res); return(res); } /* end of cuddAddNegateRecur */
/**Function******************************************************************** Synopsis [Performs the recursive step of Cudd_addCmpl.] Description [Performs the recursive step of Cudd_addCmpl. Returns a pointer to the resulting ADD if successful; NULL otherwise.] SideEffects [None] SeeAlso [Cudd_addCmpl] ******************************************************************************/ DdNode * cuddAddCmplRecur( DdManager * dd, DdNode * f) { DdNode *one,*zero; DdNode *r,*Fv,*Fnv,*t,*e; statLine(dd); one = DD_ONE(dd); zero = DD_ZERO(dd); if (cuddIsConstant(f)) { if (f == zero) { return(one); } else { return(zero); } } r = cuddCacheLookup1(dd,Cudd_addCmpl,f); if (r != NULL) { return(r); } Fv = cuddT(f); Fnv = cuddE(f); t = cuddAddCmplRecur(dd,Fv); if (t == NULL) return(NULL); cuddRef(t); e = cuddAddCmplRecur(dd,Fnv); if (e == NULL) { Cudd_RecursiveDeref(dd,t); return(NULL); } cuddRef(e); r = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); if (r == NULL) { Cudd_RecursiveDeref(dd, t); Cudd_RecursiveDeref(dd, e); return(NULL); } cuddDeref(t); cuddDeref(e); cuddCacheInsert1(dd,Cudd_addCmpl,f,r); return(r); } /* end of cuddAddCmplRecur */
/**Function******************************************************************** Synopsis [Converts a ZDD cover to a BDD graph.] Description [Converts a ZDD cover to a BDD graph. If successful, it returns a BDD node, otherwise it returns NULL. It is a recursive algorithm as the following. First computes 3 cofactors of a ZDD cover; f1, f0 and fd. Second, compute BDDs(b1, b0 and bd) of f1, f0 and fd. Third, compute T=b1+bd and E=b0+bd. Fourth, compute ITE(v,T,E) where v is the variable which has the index of the top node of the ZDD cover. In this case, since the index of v can be larger than either one of T or one of E, cuddUniqueInterIVO is called, here IVO stands for independent variable ordering.] SideEffects [] SeeAlso [Cudd_MakeBddFromZddCover] ******************************************************************************/ DdNode * cuddMakeBddFromZddCover( DdManager * dd, DdNode * node) { DdNode *neW; int v; DdNode *f1, *f0, *fd; DdNode *b1, *b0, *bd; DdNode *T, *E; statLine(dd); if (node == dd->one) return(dd->one); if (node == dd->zero) return(Cudd_Not(dd->one)); /* Check cache */ neW = cuddCacheLookup1(dd, cuddMakeBddFromZddCover, node); if (neW) return(neW); v = Cudd_Regular(node)->index; /* either yi or zi */ cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd); Cudd_Ref(f1); Cudd_Ref(f0); Cudd_Ref(fd); b1 = cuddMakeBddFromZddCover(dd, f1); if (!b1) { Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, f0); Cudd_RecursiveDerefZdd(dd, fd); return(NULL); } Cudd_Ref(b1); b0 = cuddMakeBddFromZddCover(dd, f0); if (!b1) { Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, f0); Cudd_RecursiveDerefZdd(dd, fd); Cudd_RecursiveDeref(dd, b1); return(NULL); } Cudd_Ref(b0); Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, f0); if (fd != dd->zero) { bd = cuddMakeBddFromZddCover(dd, fd); if (!bd) { Cudd_RecursiveDerefZdd(dd, fd); Cudd_RecursiveDeref(dd, b1); Cudd_RecursiveDeref(dd, b0); return(NULL); } Cudd_Ref(bd); Cudd_RecursiveDerefZdd(dd, fd); T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd)); if (!T) { Cudd_RecursiveDeref(dd, b1); Cudd_RecursiveDeref(dd, b0); Cudd_RecursiveDeref(dd, bd); return(NULL); } T = Cudd_NotCond(T, T != NULL); Cudd_Ref(T); Cudd_RecursiveDeref(dd, b1); E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd)); if (!E) { Cudd_RecursiveDeref(dd, b0); Cudd_RecursiveDeref(dd, bd); Cudd_RecursiveDeref(dd, T); return(NULL); } E = Cudd_NotCond(E, E != NULL); Cudd_Ref(E); Cudd_RecursiveDeref(dd, b0); Cudd_RecursiveDeref(dd, bd); } else { Cudd_RecursiveDerefZdd(dd, fd); T = b1; E = b0; } if (Cudd_IsComplement(T)) { neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E)); if (!neW) { Cudd_RecursiveDeref(dd, T); Cudd_RecursiveDeref(dd, E); return(NULL); } neW = Cudd_Not(neW); } else { neW = cuddUniqueInterIVO(dd, v / 2, T, E); if (!neW) { Cudd_RecursiveDeref(dd, T); Cudd_RecursiveDeref(dd, E); return(NULL); } } Cudd_Ref(neW); Cudd_RecursiveDeref(dd, T); Cudd_RecursiveDeref(dd, E); cuddCacheInsert1(dd, cuddMakeBddFromZddCover, node, neW); Cudd_Deref(neW); return(neW); } /* end of cuddMakeBddFromZddCover */
/**Function******************************************************************** Synopsis [Performs the recursive step of Cudd_zddPortToBdd.] Description [] SideEffects [None] SeeAlso [] ******************************************************************************/ static DdNode * zddPortToBddStep( DdManager * dd /* manager */, DdNode * f /* ZDD to be converted */, int depth /* recursion depth */) { DdNode *one, *zero, *T, *E, *res, *var; unsigned int index; unsigned int level; statLine(dd); one = DD_ONE(dd); zero = DD_ZERO(dd); if (f == zero) return(Cudd_Not(one)); if (depth == dd->sizeZ) return(one); index = dd->invpermZ[depth]; level = cuddIZ(dd,f->index); var = cuddUniqueInter(dd,index,one,Cudd_Not(one)); if (var == NULL) return(NULL); cuddRef(var); if (level > (unsigned) depth) { E = zddPortToBddStep(dd,f,depth+1); if (E == NULL) { Cudd_RecursiveDeref(dd,var); return(NULL); } cuddRef(E); res = cuddBddIteRecur(dd,var,Cudd_Not(one),E); if (res == NULL) { Cudd_RecursiveDeref(dd,var); Cudd_RecursiveDeref(dd,E); return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd,var); Cudd_RecursiveDeref(dd,E); cuddDeref(res); return(res); } res = cuddCacheLookup1(dd,Cudd_zddPortToBdd,f); if (res != NULL) { Cudd_RecursiveDeref(dd,var); return(res); } T = zddPortToBddStep(dd,cuddT(f),depth+1); if (T == NULL) { Cudd_RecursiveDeref(dd,var); return(NULL); } cuddRef(T); E = zddPortToBddStep(dd,cuddE(f),depth+1); if (E == NULL) { Cudd_RecursiveDeref(dd,var); Cudd_RecursiveDeref(dd,T); return(NULL); } cuddRef(E); res = cuddBddIteRecur(dd,var,T,E); if (res == NULL) { Cudd_RecursiveDeref(dd,var); Cudd_RecursiveDeref(dd,T); Cudd_RecursiveDeref(dd,E); return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd,var); Cudd_RecursiveDeref(dd,T); Cudd_RecursiveDeref(dd,E); cuddDeref(res); cuddCacheInsert1(dd,Cudd_zddPortToBdd,f,res); return(res); } /* end of zddPortToBddStep */
/**Function************************************************************* Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * extraBddSpaceFromFunctionNeg( DdManager * dd, DdNode * bF ) { DdNode * bRes, * bFR; statLine( dd ); bFR = Cudd_Regular(bF); if ( cuddIsConstant(bFR) ) return b0; if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceFromFunctionNeg, bF)) ) return bRes; else { DdNode * bF0, * bF1; DdNode * bPos0, * bPos1; DdNode * bNeg0, * bNeg1; DdNode * bRes0, * bRes1; if ( bFR != bF ) // bF is complemented { bF0 = Cudd_Not( cuddE(bFR) ); bF1 = Cudd_Not( cuddT(bFR) ); } else { bF0 = cuddE(bFR); bF1 = cuddT(bFR); } bPos0 = extraBddSpaceFromFunctionNeg( dd, bF0 ); if ( bPos0 == NULL ) return NULL; cuddRef( bPos0 ); bPos1 = extraBddSpaceFromFunctionNeg( dd, bF1 ); if ( bPos1 == NULL ) { Cudd_RecursiveDeref( dd, bPos0 ); return NULL; } cuddRef( bPos1 ); bRes0 = cuddBddAndRecur( dd, bPos0, bPos1 ); if ( bRes0 == NULL ) { Cudd_RecursiveDeref( dd, bPos0 ); Cudd_RecursiveDeref( dd, bPos1 ); return NULL; } cuddRef( bRes0 ); Cudd_RecursiveDeref( dd, bPos0 ); Cudd_RecursiveDeref( dd, bPos1 ); bNeg0 = extraBddSpaceFromFunctionPos( dd, bF0 ); if ( bNeg0 == NULL ) { Cudd_RecursiveDeref( dd, bRes0 ); return NULL; } cuddRef( bNeg0 ); bNeg1 = extraBddSpaceFromFunctionPos( dd, bF1 ); if ( bNeg1 == NULL ) { Cudd_RecursiveDeref( dd, bRes0 ); Cudd_RecursiveDeref( dd, bNeg0 ); return NULL; } cuddRef( bNeg1 ); bRes1 = cuddBddAndRecur( dd, bNeg0, bNeg1 ); if ( bRes1 == NULL ) { Cudd_RecursiveDeref( dd, bRes0 ); Cudd_RecursiveDeref( dd, bNeg0 ); Cudd_RecursiveDeref( dd, bNeg1 ); return NULL; } cuddRef( bRes1 ); Cudd_RecursiveDeref( dd, bNeg0 ); Cudd_RecursiveDeref( dd, bNeg1 ); // consider the case when Res0 and Res1 are the same node if ( bRes0 == bRes1 ) bRes = bRes1; // consider the case when Res1 is complemented else if ( Cudd_IsComplement(bRes1) ) { bRes = cuddUniqueInter( dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0) ); if ( bRes == NULL ) { Cudd_RecursiveDeref(dd,bRes0); Cudd_RecursiveDeref(dd,bRes1); return NULL; } bRes = Cudd_Not(bRes); } else { bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 ); if ( bRes == NULL ) { Cudd_RecursiveDeref(dd,bRes0); Cudd_RecursiveDeref(dd,bRes1); return NULL; } } cuddDeref( bRes0 ); cuddDeref( bRes1 ); cuddCacheInsert1( dd, extraBddSpaceFromFunctionNeg, bF, bRes ); return bRes; } }
/**Function************************************************************* Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * extraBddSpaceFromMatrixNeg( DdManager * dd, DdNode * zA ) { DdNode * bRes; statLine( dd ); if ( zA == z0 ) return b1; if ( zA == z1 ) return b0; if ( (bRes = cuddCacheLookup1(dd, extraBddSpaceFromMatrixNeg, zA)) ) return bRes; else { DdNode * bP0, * bP1; DdNode * bN0, * bN1; DdNode * bRes0, * bRes1; bP0 = extraBddSpaceFromMatrixNeg( dd, cuddE(zA) ); if ( bP0 == NULL ) return NULL; cuddRef( bP0 ); bP1 = extraBddSpaceFromMatrixNeg( dd, cuddT(zA) ); if ( bP1 == NULL ) { Cudd_RecursiveDeref( dd, bP0 ); return NULL; } cuddRef( bP1 ); bRes0 = cuddBddAndRecur( dd, bP0, bP1 ); if ( bRes0 == NULL ) { Cudd_RecursiveDeref( dd, bP0 ); Cudd_RecursiveDeref( dd, bP1 ); return NULL; } cuddRef( bRes0 ); Cudd_RecursiveDeref( dd, bP0 ); Cudd_RecursiveDeref( dd, bP1 ); bN0 = extraBddSpaceFromMatrixNeg( dd, cuddE(zA) ); if ( bN0 == NULL ) { Cudd_RecursiveDeref( dd, bRes0 ); return NULL; } cuddRef( bN0 ); bN1 = extraBddSpaceFromMatrixPos( dd, cuddT(zA) ); if ( bN1 == NULL ) { Cudd_RecursiveDeref( dd, bRes0 ); Cudd_RecursiveDeref( dd, bN0 ); return NULL; } cuddRef( bN1 ); bRes1 = cuddBddAndRecur( dd, bN0, bN1 ); if ( bRes1 == NULL ) { Cudd_RecursiveDeref( dd, bRes0 ); Cudd_RecursiveDeref( dd, bN0 ); Cudd_RecursiveDeref( dd, bN1 ); return NULL; } cuddRef( bRes1 ); Cudd_RecursiveDeref( dd, bN0 ); Cudd_RecursiveDeref( dd, bN1 ); // consider the case when Res0 and Res1 are the same node if ( bRes0 == bRes1 ) bRes = bRes1; // consider the case when Res1 is complemented else if ( Cudd_IsComplement(bRes1) ) { bRes = cuddUniqueInter( dd, zA->index/2, Cudd_Not(bRes1), Cudd_Not(bRes0) ); if ( bRes == NULL ) { Cudd_RecursiveDeref(dd,bRes0); Cudd_RecursiveDeref(dd,bRes1); return NULL; } bRes = Cudd_Not(bRes); } else { bRes = cuddUniqueInter( dd, zA->index/2, bRes1, bRes0 ); if ( bRes == NULL ) { Cudd_RecursiveDeref(dd,bRes0); Cudd_RecursiveDeref(dd,bRes1); return NULL; } } cuddDeref( bRes0 ); cuddDeref( bRes1 ); cuddCacheInsert1( dd, extraBddSpaceFromMatrixNeg, zA, bRes ); return bRes; } }
/**Function******************************************************************** Synopsis [Performs the recursive step for Cudd_addBddBooleanMap.] Description [Performs the recursive step for Cudd_addBddBooleanMap. Returns a pointer to the BDD if successful; NULL otherwise.] SideEffects [None] SeeAlso [addBddDoStrictThreshold] ******************************************************************************/ static DdNode * addBddBooleanMap( DdManager * dd, DdNode * f) { DdNode *res, *T, *E; DdNode *fv, *fvn; int v; statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { if ((f != DD_TRUE(dd)) && (f != DD_FALSE(dd))) { (void)fprintf(dd->err, "Error: Can only convert Add with FALSE or TRUE leaves to Bdd."); return(NULL); } return(Cudd_NotCond(DD_TRUE(dd), f == DD_FALSE(dd))); } /* Check cache. */ res = cuddCacheLookup1(dd,addBddBooleanMap,f); if (res != NULL) return(res); /* Recursive step. */ v = f->index; fv = cuddT(f); fvn = cuddE(f); T = addBddBooleanMap(dd,fv); if (T == NULL) return(NULL); cuddRef(T); E = addBddBooleanMap(dd,fvn); if (E == NULL) { Cudd_RecursiveDeref(dd, T); return(NULL); } cuddRef(E); if (Cudd_IsComplement(T)) { res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); if (res == NULL) { Cudd_RecursiveDeref(dd, T); Cudd_RecursiveDeref(dd, E); return(NULL); } res = Cudd_Not(res); } else { res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); if (res == NULL) { Cudd_RecursiveDeref(dd, T); Cudd_RecursiveDeref(dd, E); return(NULL); } } cuddDeref(T); cuddDeref(E); /* Store result. */ cuddCacheInsert1(dd,addBddBooleanMap,f,res); return(res); } /* end of addBddBooleanMap */
/**Function******************************************************************** Synopsis [Performs the recursive step for Cudd_addBddPattern.] Description [Performs the recursive step for Cudd_addBddPattern. Returns a pointer to the resulting BDD if successful; NULL otherwise.] SideEffects [None] SeeAlso [] ******************************************************************************/ DdNode * cuddAddBddDoPattern( DdManager * dd, DdNode * f) { DdNode *res, *T, *E; DdNode *fv, *fvn; int v; /* NuSMV: begin add */ abort(); /* NOT USED BY NUSMV */ /* NuSMV: begin end */ statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { return(Cudd_NotCond(DD_TRUE(dd),f == DD_FALSE(dd))); } /* Check cache. */ res = cuddCacheLookup1(dd,Cudd_addBddPattern,f); if (res != NULL) return(res); /* Recursive step. */ v = f->index; fv = cuddT(f); fvn = cuddE(f); T = cuddAddBddDoPattern(dd,fv); if (T == NULL) return(NULL); cuddRef(T); E = cuddAddBddDoPattern(dd,fvn); if (E == NULL) { Cudd_RecursiveDeref(dd, T); return(NULL); } cuddRef(E); if (Cudd_IsComplement(T)) { res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); if (res == NULL) { Cudd_RecursiveDeref(dd, T); Cudd_RecursiveDeref(dd, E); return(NULL); } res = Cudd_Not(res); } else { res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); if (res == NULL) { Cudd_RecursiveDeref(dd, T); Cudd_RecursiveDeref(dd, E); return(NULL); } } cuddDeref(T); cuddDeref(E); /* Store result. */ cuddCacheInsert1(dd,Cudd_addBddPattern,f,res); return(res); } /* end of cuddAddBddDoPattern */
/**Function******************************************************************** Synopsis [Performs the recursive step for Cudd_BddTo01Add.] Description [Performs the recursive step for Cudd_BddTo01Add. Returns a pointer to the resulting ADD if successful; NULL otherwise.] SideEffects [None] SeeAlso [] ******************************************************************************/ static DdNode * ddBddTo01AddRecur( DdManager * dd, DdNode * B) { DdNode *res, *res1, *T, *E, *Bt, *Be; int complement = 0; statLine(dd); if (B == DD_TRUE(dd)) { return DD_ONE(dd); } else if (B == Cudd_Not(DD_TRUE(dd))) { return DD_ZERO(dd); } /* Check visited table */ res = cuddCacheLookup1(dd,ddBddTo01AddRecur,B); if (res != NULL) return(res); if (Cudd_IsComplement(B)) { complement = 1; Bt = cuddT(Cudd_Regular(B)); Be = cuddE(Cudd_Regular(B)); } else { Bt = cuddT(B); Be = cuddE(B); } T = ddBddTo01AddRecur(dd, Bt); if (T == NULL) return(NULL); cuddRef(T); E = ddBddTo01AddRecur(dd, Be); if (E == NULL) { Cudd_RecursiveDeref(dd, T); return(NULL); } cuddRef(E); /* No need to check for T == E, because it is guaranteed not to happen. */ res = cuddUniqueInter(dd, (int) Cudd_Regular(B)->index, T, E); if (res == NULL) { Cudd_RecursiveDeref(dd ,T); Cudd_RecursiveDeref(dd ,E); return(NULL); } cuddDeref(T); cuddDeref(E); if (complement) { cuddRef(res); res1 = cuddAddCmpl01Recur(dd, res); if (res1 == NULL) { Cudd_RecursiveDeref(dd, res); return(NULL); } cuddRef(res1); Cudd_RecursiveDeref(dd, res); res = res1; cuddDeref(res); } /* Store result. */ cuddCacheInsert1(dd,ddBddTo01AddRecur,B,res); return(res); } /* end of ddBddTo01AddRecur */