/**Function******************************************************************** Synopsis [Checks whether ADD g is constant whenever ADD f is 1.] Description [Checks whether ADD g is constant whenever ADD f is 1. f must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may or may not be constant) or DD_NON_CONSTANT. If f is identically 0, the check is assumed to be successful, and the background value is returned. No new nodes are created.] SideEffects [None] SeeAlso [Cudd_addIteConstant Cudd_addLeq] ******************************************************************************/ DdNode * Cudd_addEvalConst( DdManager * dd, DdNode * f, DdNode * g) { DdNode *zero; DdNode *Fv,*Fnv,*Gv,*Gnv,*r,*t,*e; unsigned int topf,topg; #ifdef DD_DEBUG assert(!Cudd_IsComplement(f)); #endif statLine(dd); /* Terminal cases. */ if (f == DD_ONE(dd) || cuddIsConstant(g)) { return(g); } if (f == (zero = DD_ZERO(dd))) { return(dd->background); } #ifdef DD_DEBUG assert(!cuddIsConstant(f)); #endif /* From now on, f and g are known not to be constants. */ topf = cuddI(dd,f->index); topg = cuddI(dd,g->index); /* Check cache. */ r = cuddConstantLookup(dd,DD_ADD_EVAL_CONST_TAG,f,g,g); if (r != NULL) { return(r); } /* Compute cofactors. */ if (topf <= topg) { Fv = cuddT(f); Fnv = cuddE(f); } else { Fv = Fnv = f; } if (topg <= topf) { Gv = cuddT(g); Gnv = cuddE(g); } else { Gv = Gnv = g; } /* Recursive step. */ if (Fv != zero) { t = Cudd_addEvalConst(dd,Fv,Gv); if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); return(DD_NON_CONSTANT); } if (Fnv != zero) { e = Cudd_addEvalConst(dd,Fnv,Gnv); if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); return(DD_NON_CONSTANT); } } cuddCacheInsert2(dd,Cudd_addEvalConst,f,g,t); return(t); } else { /* Fnv must be != zero */ e = Cudd_addEvalConst(dd,Fnv,Gnv); cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e); return(e); } } /* end of Cudd_addEvalConst */
/**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] ******************************************************************************/ DdNode * Cudd_bddIteConstant( DdManager * dd, DdNode * f, DdNode * g, DdNode * h) { DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; DdNode *one = DD_ONE(dd); DdNode *zero = Cudd_Not(one); int comple; unsigned int topf, topg, toph, v; statLine(dd); /* Trivial cases. */ if (f == one) /* ITE(1,G,H) => G */ return(g); if (f == zero) /* ITE(0,G,H) => H */ return(h); /* f now not a constant. */ bddVarToConst(f, &g, &h, one); /* possibly convert g or h */ /* to constants */ if (g == h) /* ITE(F,G,G) => G */ return(g); if (Cudd_IsConstant(g) && Cudd_IsConstant(h)) return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */ /* => DD_NON_CONSTANT */ if (g == Cudd_Not(h)) return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */ /* if F != G and F != G' */ comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph); /* Cache lookup. */ r = cuddConstantLookup(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h); if (r != NULL) { return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT)); } v = ddMin(topg, toph); /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */ if (topf < v && cuddT(f) == one && cuddE(f) == zero) { return(DD_NON_CONSTANT); } /* Compute cofactors. */ if (topf <= v) { v = ddMin(topf, v); /* v = top_var(F,G,H) */ Fv = cuddT(f); Fnv = cuddE(f); } else { Fv = Fnv = f; } if (topg == v) { Gv = cuddT(g); Gnv = cuddE(g); } else { Gv = Gnv = g; } if (toph == v) { H = Cudd_Regular(h); Hv = cuddT(H); Hnv = cuddE(H); if (Cudd_IsComplement(h)) { Hv = Cudd_Not(Hv); Hnv = Cudd_Not(Hnv); } } else { Hv = Hnv = h; } /* Recursion. */ t = Cudd_bddIteConstant(dd, Fv, Gv, Hv); if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) { cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); return(DD_NON_CONSTANT); } e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv); if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) { cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); return(DD_NON_CONSTANT); } cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t); return(Cudd_NotCond(t,comple)); } /* end of Cudd_bddIteConstant */
/**Function******************************************************************** Synopsis [Implements ITEconstant for ADDs.] Description [Implements ITEconstant for ADDs. f must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may or may not be constant) or DD_NON_CONSTANT. No new nodes are created. This function can be used, for instance, to check that g has a constant value (specified by h) whenever f is 1. If the constant value is unknown, then one should use Cudd_addEvalConst.] SideEffects [None] SeeAlso [Cudd_addIte Cudd_addEvalConst Cudd_bddIteConstant] ******************************************************************************/ DdNode * Cudd_addIteConstant( DdManager * dd, DdNode * f, DdNode * g, DdNode * h) { DdNode *one,*zero; DdNode *Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*r,*t,*e; unsigned int topf,topg,toph,v; statLine(dd); /* Trivial cases. */ if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ return(g); } if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ return(h); } /* From now on, f is known not to be a constant. */ addVarToConst(f,&g,&h,one,zero); /* Check remaining one variable cases. */ if (g == h) { /* ITE(F,G,G) = G */ return(g); } if (cuddIsConstant(g) && cuddIsConstant(h)) { return(DD_NON_CONSTANT); } topf = cuddI(dd,f->index); topg = cuddI(dd,g->index); toph = cuddI(dd,h->index); v = ddMin(topg,toph); /* ITE(F,G,H) = (x,G,H) (non constant) if F = (x,1,0), x < top(G,H). */ if (topf < v && cuddIsConstant(cuddT(f)) && cuddIsConstant(cuddE(f))) { return(DD_NON_CONSTANT); } /* Check cache. */ r = cuddConstantLookup(dd,DD_ADD_ITE_CONSTANT_TAG,f,g,h); if (r != NULL) { return(r); } /* Compute cofactors. */ if (topf <= v) { v = ddMin(topf,v); /* v = top_var(F,G,H) */ Fv = cuddT(f); Fnv = cuddE(f); } else { Fv = Fnv = f; } if (topg == v) { Gv = cuddT(g); Gnv = cuddE(g); } else { Gv = Gnv = g; } if (toph == v) { Hv = cuddT(h); Hnv = cuddE(h); } else { Hv = Hnv = h; } /* Recursive step. */ t = Cudd_addIteConstant(dd,Fv,Gv,Hv); if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); return(DD_NON_CONSTANT); } e = Cudd_addIteConstant(dd,Fnv,Gnv,Hnv); if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); return(DD_NON_CONSTANT); } cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, t); return(t); } /* end of Cudd_addIteConstant */