/**Function******************************************************************** Synopsis [Existentially Abstracts all the variables in cube from f.] Description [Abstracts all the variables in cube from f by summing over all possible values taken by the variables. Returns the abstracted ADD.] SideEffects [None] SeeAlso [Cudd_addUnivAbstract Cudd_bddExistAbstract Cudd_addOrAbstract] ******************************************************************************/ DdNode * Cudd_addExistAbstract( DdManager * manager, DdNode * f, DdNode * cube) { DdNode *res; two = cuddUniqueConst(manager,(CUDD_VALUE_TYPE) 2); if (two == NULL) return(NULL); cuddRef(two); if (addCheckPositiveCube(manager, cube) == 0) { (void) fprintf(manager->err,"Error: Can only abstract cubes"); return(NULL); } do { manager->reordered = 0; res = cuddAddExistAbstractRecur(manager, f, cube); } while (manager->reordered == 1); if (res == NULL) { Cudd_RecursiveDeref(manager,two); return(NULL); } cuddRef(res); Cudd_RecursiveDeref(manager,two); cuddDeref(res); return(res); } /* end of Cudd_addExistAbstract */
/** @brief Existentially Abstracts all the variables in cube from f. @details Abstracts all the variables in cube from f by summing over all possible values taken by the variables. @return the abstracted %ADD. @sideeffect None @see Cudd_addUnivAbstract Cudd_bddExistAbstract Cudd_addOrAbstract */ DdNode * Cudd_addExistAbstract( DdManager * manager, DdNode * f, DdNode * cube) { DdNode *res; if (addCheckPositiveCube(manager, cube) == 0) { (void) fprintf(manager->err,"Error: Can only abstract cubes"); return(NULL); } do { manager->reordered = 0; res = cuddAddExistAbstractRecur(manager, f, cube); } while (manager->reordered == 1); if (manager->errorCode == CUDD_TIMEOUT_EXPIRED && manager->timeoutHandler) { manager->timeoutHandler(manager, manager->tohArg); } return(res); } /* end of Cudd_addExistAbstract */
/**Function******************************************************************** Synopsis [Performs the recursive step of Cudd_addExistAbstract.] Description [Performs the recursive step of Cudd_addExistAbstract. Returns the ADD obtained by abstracting the variables of cube from f, if successful; NULL otherwise.] SideEffects [None] SeeAlso [] ******************************************************************************/ DdNode * cuddAddExistAbstractRecur( DdManager * manager, DdNode * f, DdNode * cube) { DdNode *T, *E, *res, *res1, *res2, *zero; statLine(manager); zero = DD_ZERO(manager); /* Cube is guaranteed to be a cube at this point. */ if (f == zero || cuddIsConstant(cube)) { return(f); } /* Abstract a variable that does not appear in f => multiply by 2. */ if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { res1 = cuddAddExistAbstractRecur(manager, f, cuddT(cube)); if (res1 == NULL) return(NULL); cuddRef(res1); /* Use the "internal" procedure to be alerted in case of ** dynamic reordering. If dynamic reordering occurs, we ** have to abort the entire abstraction. */ res = cuddAddApplyRecur(manager,Cudd_addTimes,res1,two); if (res == NULL) { Cudd_RecursiveDeref(manager,res1); return(NULL); } cuddRef(res); Cudd_RecursiveDeref(manager,res1); cuddDeref(res); return(res); } if ((res = cuddCacheLookup2(manager, Cudd_addExistAbstract, f, cube)) != NULL) { return(res); } T = cuddT(f); E = cuddE(f); /* If the two indices are the same, so are their levels. */ if (f->index == cube->index) { res1 = cuddAddExistAbstractRecur(manager, T, cuddT(cube)); if (res1 == NULL) return(NULL); cuddRef(res1); res2 = cuddAddExistAbstractRecur(manager, E, cuddT(cube)); if (res2 == NULL) { Cudd_RecursiveDeref(manager,res1); return(NULL); } cuddRef(res2); res = cuddAddApplyRecur(manager, Cudd_addPlus, res1, res2); if (res == NULL) { Cudd_RecursiveDeref(manager,res1); Cudd_RecursiveDeref(manager,res2); return(NULL); } cuddRef(res); Cudd_RecursiveDeref(manager,res1); Cudd_RecursiveDeref(manager,res2); cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); cuddDeref(res); return(res); } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ res1 = cuddAddExistAbstractRecur(manager, T, cube); if (res1 == NULL) return(NULL); cuddRef(res1); res2 = cuddAddExistAbstractRecur(manager, E, cube); if (res2 == NULL) { Cudd_RecursiveDeref(manager,res1); return(NULL); } cuddRef(res2); res = (res1 == res2) ? res1 : cuddUniqueInter(manager, (int) f->index, res1, res2); if (res == NULL) { Cudd_RecursiveDeref(manager,res1); Cudd_RecursiveDeref(manager,res2); return(NULL); } cuddDeref(res1); cuddDeref(res2); cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); return(res); } } /* end of cuddAddExistAbstractRecur */
/**Function******************************************************************** Synopsis [Performs the recursive step of Cudd_addNonSimCompose.] Description [] SideEffects [None] SeeAlso [] ******************************************************************************/ static DdNode * cuddAddNonSimComposeRecur( DdManager * dd, DdNode * f, DdNode ** vector, DdNode * key, DdNode * cube, int lastsub) { DdNode *f1, *f0, *key1, *key0, *cube1, *var; DdNode *T,*E; DdNode *r; unsigned int top, topf, topk, topc; unsigned int index; int i; DdNode **vect1; DdNode **vect0; statLine(dd); /* If we are past the deepest substitution, return f. */ if (cube == DD_ONE(dd) || cuddIsConstant(f)) { return(f); } /* If problem already solved, look up answer and return. */ r = cuddCacheLookup(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube); if (r != NULL) { return(r); } /* Find top variable. we just need to look at f, key, and cube, ** because all the varibles in the gi are in key. */ topf = cuddI(dd,f->index); topk = cuddI(dd,key->index); top = ddMin(topf,topk); topc = cuddI(dd,cube->index); top = ddMin(top,topc); index = dd->invperm[top]; /* Compute the cofactors. */ if (topf == top) { f1 = cuddT(f); f0 = cuddE(f); } else { f1 = f0 = f; } if (topc == top) { cube1 = cuddT(cube); /* We want to eliminate vector[index] from key. Otherwise ** cache performance is severely affected. Hence we ** existentially quantify the variable with index "index" from key. */ var = Cudd_addIthVar(dd, (int) index); if (var == NULL) { return(NULL); } cuddRef(var); key1 = cuddAddExistAbstractRecur(dd, key, var); if (key1 == NULL) { Cudd_RecursiveDeref(dd,var); return(NULL); } cuddRef(key1); Cudd_RecursiveDeref(dd,var); key0 = key1; } else { cube1 = cube; if (topk == top) { key1 = cuddT(key); key0 = cuddE(key); } else { key1 = key0 = key; } cuddRef(key1); } /* Allocate two new vectors for the cofactors of vector. */ vect1 = ALLOC(DdNode *,lastsub); if (vect1 == NULL) { dd->errorCode = CUDD_MEMORY_OUT; Cudd_RecursiveDeref(dd,key1); return(NULL); } vect0 = ALLOC(DdNode *,lastsub); if (vect0 == NULL) { dd->errorCode = CUDD_MEMORY_OUT; Cudd_RecursiveDeref(dd,key1); FREE(vect1); return(NULL); } /* Cofactor the gi. Eliminate vect1[index] and vect0[index], because ** we do not need them. */ for (i = 0; i < lastsub; i++) { DdNode *gi = vector[i]; if (gi == NULL) { vect1[i] = vect0[i] = NULL; } else if (gi->index == index) { vect1[i] = cuddT(gi); vect0[i] = cuddE(gi); } else { vect1[i] = vect0[i] = gi; } } vect1[index] = vect0[index] = NULL; /* Recur on children. */ T = cuddAddNonSimComposeRecur(dd,f1,vect1,key1,cube1,lastsub); FREE(vect1); if (T == NULL) { Cudd_RecursiveDeref(dd,key1); FREE(vect0); return(NULL); } cuddRef(T); E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub); FREE(vect0); if (E == NULL) { Cudd_RecursiveDeref(dd,key1); Cudd_RecursiveDeref(dd,T); return(NULL); } cuddRef(E); Cudd_RecursiveDeref(dd,key1); /* Retrieve the 0-1 ADD for the current top variable from vector, ** and call cuddAddIteRecur with the T and E we just created. */ r = cuddAddIteRecur(dd,vector[index],T,E); if (r == NULL) { Cudd_RecursiveDeref(dd,T); Cudd_RecursiveDeref(dd,E); return(NULL); } cuddRef(r); Cudd_RecursiveDeref(dd,T); Cudd_RecursiveDeref(dd,E); cuddDeref(r); /* Store answer to trim recursion. */ cuddCacheInsert(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube,r); return(r); } /* end of cuddAddNonSimComposeRecur */