diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2007-09-30 08:01:00 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2007-09-30 08:01:00 -0700 |
commit | e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7 (patch) | |
tree | de3ffe87c3e17950351e3b7d97fa18318bd5ea9a /src/bdd/cudd/cuddCompose.c | |
parent | 7d7e60f2dc84393cd4c5db22d2eaf7b1fb1a79b2 (diff) | |
download | abc-e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7.tar.gz abc-e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7.tar.bz2 abc-e54d9691616b9a0326e2fdb3156bb4eeb8abfcd7.zip |
Version abc70930
Diffstat (limited to 'src/bdd/cudd/cuddCompose.c')
-rw-r--r-- | src/bdd/cudd/cuddCompose.c | 1722 |
1 files changed, 0 insertions, 1722 deletions
diff --git a/src/bdd/cudd/cuddCompose.c b/src/bdd/cudd/cuddCompose.c deleted file mode 100644 index 8c858051..00000000 --- a/src/bdd/cudd/cuddCompose.c +++ /dev/null @@ -1,1722 +0,0 @@ -/**CFile*********************************************************************** - - FileName [cuddCompose.c] - - PackageName [cudd] - - Synopsis [Functional composition and variable permutation of DDs.] - - Description [External procedures included in this module: - <ul> - <li> Cudd_bddCompose() - <li> Cudd_addCompose() - <li> Cudd_addPermute() - <li> Cudd_addSwapVariables() - <li> Cudd_bddPermute() - <li> Cudd_bddVarMap() - <li> Cudd_SetVarMap() - <li> Cudd_bddSwapVariables() - <li> Cudd_bddAdjPermuteX() - <li> Cudd_addVectorCompose() - <li> Cudd_addGeneralVectorCompose() - <li> Cudd_addNonSimCompose() - <li> Cudd_bddVectorCompose() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddComposeRecur() - <li> cuddAddComposeRecur() - </ul> - Static procedures included in this module: - <ul> - <li> cuddAddPermuteRecur() - <li> cuddBddPermuteRecur() - <li> cuddBddVarMapRecur() - <li> cuddAddVectorComposeRecur() - <li> cuddAddGeneralVectorComposeRecur() - <li> cuddAddNonSimComposeRecur() - <li> cuddBddVectorComposeRecur() - <li> ddIsIthAddVar() - <li> ddIsIthAddVarPair() - </ul> - The permutation functions use a local cache because the results to - be remembered depend on the permutation being applied. Since the - permutation is just an array, it cannot be stored in the global - cache. There are different procedured for BDDs and ADDs. This is - because bddPermuteRecur uses cuddBddIteRecur. If this were changed, - the procedures could be merged.] - - Author [Fabio Somenzi and Kavita Ravi] - - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] - -******************************************************************************/ - -#include "util_hack.h" -#include "cuddInt.h" - - -/*---------------------------------------------------------------------------*/ -/* Constant declarations */ -/*---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------*/ -/* Stucture declarations */ -/*---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------*/ -/* Type declarations */ -/*---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------*/ -/* Variable declarations */ -/*---------------------------------------------------------------------------*/ - -#ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddCompose.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; -#endif - -#ifdef DD_DEBUG -static int addPermuteRecurHits; -static int bddPermuteRecurHits; -static int bddVectorComposeHits; -static int addVectorComposeHits; - -static int addGeneralVectorComposeHits; -#endif - -/*---------------------------------------------------------------------------*/ -/* Macro declarations */ -/*---------------------------------------------------------------------------*/ - - -/**AutomaticStart*************************************************************/ - -/*---------------------------------------------------------------------------*/ -/* Static function prototypes */ -/*---------------------------------------------------------------------------*/ - -static DdNode * cuddAddPermuteRecur ARGS((DdManager *manager, DdHashTable *table, DdNode *node, int *permut)); -static DdNode * cuddBddPermuteRecur ARGS((DdManager *manager, DdHashTable *table, DdNode *node, int *permut)); -static DdNode * cuddBddVarMapRecur ARGS((DdManager *manager, DdNode *f)); -static DdNode * cuddAddVectorComposeRecur ARGS((DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest)); -static DdNode * cuddAddNonSimComposeRecur ARGS((DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub)); -static DdNode * cuddBddVectorComposeRecur ARGS((DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest)); -DD_INLINE static int ddIsIthAddVar ARGS((DdManager *dd, DdNode *f, unsigned int i)); - -static DdNode * cuddAddGeneralVectorComposeRecur ARGS((DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest)); -DD_INLINE static int ddIsIthAddVarPair ARGS((DdManager *dd, DdNode *f, DdNode *g, unsigned int i)); - -/**AutomaticEnd***************************************************************/ - - -/*---------------------------------------------------------------------------*/ -/* Definition of exported functions */ -/*---------------------------------------------------------------------------*/ - - -/**Function******************************************************************** - - Synopsis [Substitutes g for x_v in the BDD for f.] - - Description [Substitutes g for x_v in the BDD for f. v is the index of the - variable to be substituted. Cudd_bddCompose passes the corresponding - projection function to the recursive procedure, so that the cache may - be used. Returns the composed BDD if successful; NULL otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_addCompose] - -******************************************************************************/ -DdNode * -Cudd_bddCompose( - DdManager * dd, - DdNode * f, - DdNode * g, - int v) -{ - DdNode *proj, *res; - - /* Sanity check. */ - if (v < 0 || v > dd->size) return(NULL); - - proj = dd->vars[v]; - do { - dd->reordered = 0; - res = cuddBddComposeRecur(dd,f,g,proj); - } while (dd->reordered == 1); - return(res); - -} /* end of Cudd_bddCompose */ - - -/**Function******************************************************************** - - Synopsis [Substitutes g for x_v in the ADD for f.] - - Description [Substitutes g for x_v in the ADD for f. v is the index of the - variable to be substituted. g must be a 0-1 ADD. Cudd_bddCompose passes - the corresponding projection function to the recursive procedure, so - that the cache may be used. Returns the composed ADD if successful; - NULL otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_bddCompose] - -******************************************************************************/ -DdNode * -Cudd_addCompose( - DdManager * dd, - DdNode * f, - DdNode * g, - int v) -{ - DdNode *proj, *res; - - /* Sanity check. */ - if (v < 0 || v > dd->size) return(NULL); - - proj = dd->vars[v]; - do { - dd->reordered = 0; - res = cuddAddComposeRecur(dd,f,g,proj); - } while (dd->reordered == 1); - return(res); - -} /* end of Cudd_addCompose */ - - -/**Function******************************************************************** - - Synopsis [Permutes the variables of an ADD.] - - Description [Given a permutation in array permut, creates a new ADD - with permuted variables. There should be an entry in array permut - for each variable in the manager. The i-th entry of permut holds the - index of the variable that is to substitute the i-th - variable. Returns a pointer to the resulting ADD if successful; NULL - otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_bddPermute Cudd_addSwapVariables] - -******************************************************************************/ -DdNode * -Cudd_addPermute( - DdManager * manager, - DdNode * node, - int * permut) -{ - DdHashTable *table; - DdNode *res; - - do { - manager->reordered = 0; - table = cuddHashTableInit(manager,1,2); - if (table == NULL) return(NULL); - /* Recursively solve the problem. */ - res = cuddAddPermuteRecur(manager,table,node,permut); - if (res != NULL) cuddRef(res); - /* Dispose of local cache. */ - cuddHashTableQuit(table); - } while (manager->reordered == 1); - - if (res != NULL) cuddDeref(res); - return(res); - -} /* end of Cudd_addPermute */ - - -/**Function******************************************************************** - - Synopsis [Swaps two sets of variables of the same size (x and y) in - the ADD f.] - - Description [Swaps two sets of variables of the same size (x and y) in - the ADD f. The size is given by n. The two sets of variables are - assumed to be disjoint. Returns a pointer to the resulting ADD if - successful; NULL otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_addPermute Cudd_bddSwapVariables] - -******************************************************************************/ -DdNode * -Cudd_addSwapVariables( - DdManager * dd, - DdNode * f, - DdNode ** x, - DdNode ** y, - int n) -{ - DdNode *swapped; - int i, j, k; - int *permut; - - permut = ALLOC(int,dd->size); - if (permut == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - for (i = 0; i < dd->size; i++) permut[i] = i; - for (i = 0; i < n; i++) { - j = x[i]->index; - k = y[i]->index; - permut[j] = k; - permut[k] = j; - } - - swapped = Cudd_addPermute(dd,f,permut); - FREE(permut); - - return(swapped); - -} /* end of Cudd_addSwapVariables */ - - -/**Function******************************************************************** - - Synopsis [Permutes the variables of a BDD.] - - Description [Given a permutation in array permut, creates a new BDD - with permuted variables. There should be an entry in array permut - for each variable in the manager. The i-th entry of permut holds the - index of the variable that is to substitute the i-th variable. - Returns a pointer to the resulting BDD if successful; NULL - otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_addPermute Cudd_bddSwapVariables] - -******************************************************************************/ -DdNode * -Cudd_bddPermute( - DdManager * manager, - DdNode * node, - int * permut) -{ - DdHashTable *table; - DdNode *res; - - do { - manager->reordered = 0; - table = cuddHashTableInit(manager,1,2); - if (table == NULL) return(NULL); - res = cuddBddPermuteRecur(manager,table,node,permut); - if (res != NULL) cuddRef(res); - /* Dispose of local cache. */ - cuddHashTableQuit(table); - - } while (manager->reordered == 1); - - if (res != NULL) cuddDeref(res); - return(res); - -} /* end of Cudd_bddPermute */ - - -/**Function******************************************************************** - - Synopsis [Remaps the variables of a BDD using the default variable map.] - - Description [Remaps the variables of a BDD using the default - variable map. A typical use of this function is to swap two sets of - variables. The variable map must be registered with Cudd_SetVarMap. - Returns a pointer to the resulting BDD if successful; NULL - otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables Cudd_SetVarMap] - -******************************************************************************/ -DdNode * -Cudd_bddVarMap( - DdManager * manager /* DD manager */, - DdNode * f /* function in which to remap variables */) -{ - DdNode *res; - - if (manager->map == NULL) return(NULL); - do { - manager->reordered = 0; - res = cuddBddVarMapRecur(manager, f); - } while (manager->reordered == 1); - - return(res); - -} /* end of Cudd_bddVarMap */ - - -/**Function******************************************************************** - - Synopsis [Registers a variable mapping with the manager.] - - Description [Registers with the manager a variable mapping described - by two sets of variables. This variable mapping is then used by - functions like Cudd_bddVarMap. This function is convenient for - those applications that perform the same mapping several times. - However, if several different permutations are used, it may be more - efficient not to rely on the registered mapping, because changing - mapping causes the cache to be cleared. (The initial setting, - however, does not clear the cache.) The two sets of variables (x and - y) must have the same size (x and y). The size is given by n. The - two sets of variables are normally disjoint, but this restriction is - not imposeded by the function. When new variables are created, the - map is automatically extended (each new variable maps to - itself). The typical use, however, is to wait until all variables - are created, and then create the map. Returns 1 if the mapping is - successfully registered with the manager; 0 otherwise.] - - SideEffects [Modifies the manager. May clear the cache.] - - SeeAlso [Cudd_bddVarMap Cudd_bddPermute Cudd_bddSwapVariables] - -******************************************************************************/ -int -Cudd_SetVarMap ( - DdManager *manager /* DD manager */, - DdNode **x /* first array of variables */, - DdNode **y /* second array of variables */, - int n /* length of both arrays */) -{ - int i; - - if (manager->map != NULL) { - cuddCacheFlush(manager); - } else { - manager->map = ALLOC(int,manager->maxSize); - if (manager->map == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return(0); - } - manager->memused += sizeof(int) * manager->maxSize; - } - /* Initialize the map to the identity. */ - for (i = 0; i < manager->size; i++) { - manager->map[i] = i; - } - /* Create the map. */ - for (i = 0; i < n; i++) { - manager->map[x[i]->index] = y[i]->index; - manager->map[y[i]->index] = x[i]->index; - } - return(1); - -} /* end of Cudd_SetVarMap */ - - -/**Function******************************************************************** - - Synopsis [Swaps two sets of variables of the same size (x and y) in - the BDD f.] - - Description [Swaps two sets of variables of the same size (x and y) - in the BDD f. The size is given by n. The two sets of variables are - assumed to be disjoint. Returns a pointer to the resulting BDD if - successful; NULL otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_bddPermute Cudd_addSwapVariables] - -******************************************************************************/ -DdNode * -Cudd_bddSwapVariables( - DdManager * dd, - DdNode * f, - DdNode ** x, - DdNode ** y, - int n) -{ - DdNode *swapped; - int i, j, k; - int *permut; - - permut = ALLOC(int,dd->size); - if (permut == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - for (i = 0; i < dd->size; i++) permut[i] = i; - for (i = 0; i < n; i++) { - j = x[i]->index; - k = y[i]->index; - permut[j] = k; - permut[k] = j; - } - - swapped = Cudd_bddPermute(dd,f,permut); - FREE(permut); - - return(swapped); - -} /* end of Cudd_bddSwapVariables */ - - -/**Function******************************************************************** - - Synopsis [Rearranges a set of variables in the BDD B.] - - Description [Rearranges a set of variables in the BDD B. The size of - the set is given by n. This procedure is intended for the - `randomization' of the priority functions. Returns a pointer to the - BDD if successful; NULL otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables - Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_PrioritySelect] - -******************************************************************************/ -DdNode * -Cudd_bddAdjPermuteX( - DdManager * dd, - DdNode * B, - DdNode ** x, - int n) -{ - DdNode *swapped; - int i, j, k; - int *permut; - - permut = ALLOC(int,dd->size); - if (permut == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - for (i = 0; i < dd->size; i++) permut[i] = i; - for (i = 0; i < n-2; i += 3) { - j = x[i]->index; - k = x[i+1]->index; - permut[j] = k; - permut[k] = j; - } - - swapped = Cudd_bddPermute(dd,B,permut); - FREE(permut); - - return(swapped); - -} /* end of Cudd_bddAdjPermuteX */ - - -/**Function******************************************************************** - - Synopsis [Composes an ADD with a vector of 0-1 ADDs.] - - Description [Given a vector of 0-1 ADDs, creates a new ADD by - substituting the 0-1 ADDs for the variables of the ADD f. There - should be an entry in vector for each variable in the manager. - If no substitution is sought for a given variable, the corresponding - projection function should be specified in the vector. - This function implements simultaneous composition. - Returns a pointer to the resulting ADD if successful; NULL - otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_addNonSimCompose Cudd_addPermute Cudd_addCompose - Cudd_bddVectorCompose] - -******************************************************************************/ -DdNode * -Cudd_addVectorCompose( - DdManager * dd, - DdNode * f, - DdNode ** vector) -{ - DdHashTable *table; - DdNode *res; - int deepest; - int i; - - do { - dd->reordered = 0; - /* Initialize local cache. */ - table = cuddHashTableInit(dd,1,2); - if (table == NULL) return(NULL); - - /* Find deepest real substitution. */ - for (deepest = dd->size - 1; deepest >= 0; deepest--) { - i = dd->invperm[deepest]; - if (!ddIsIthAddVar(dd,vector[i],i)) { - break; - } - } - - /* Recursively solve the problem. */ - res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest); - if (res != NULL) cuddRef(res); - - /* Dispose of local cache. */ - cuddHashTableQuit(table); - } while (dd->reordered == 1); - - if (res != NULL) cuddDeref(res); - return(res); - -} /* end of Cudd_addVectorCompose */ - - -/**Function******************************************************************** - - Synopsis [Composes an ADD with a vector of ADDs.] - - Description [Given a vector of ADDs, creates a new ADD by substituting the - ADDs for the variables of the ADD f. vectorOn contains ADDs to be substituted - for the x_v and vectorOff the ADDs to be substituted for x_v'. There should - be an entry in vector for each variable in the manager. If no substitution - is sought for a given variable, the corresponding projection function should - be specified in the vector. This function implements simultaneous - composition. Returns a pointer to the resulting ADD if successful; NULL - otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_addVectorCompose Cudd_addNonSimCompose Cudd_addPermute - Cudd_addCompose Cudd_bddVectorCompose] - -******************************************************************************/ -DdNode * -Cudd_addGeneralVectorCompose( - DdManager * dd, - DdNode * f, - DdNode ** vectorOn, - DdNode ** vectorOff) -{ - DdHashTable *table; - DdNode *res; - int deepest; - int i; - - do { - dd->reordered = 0; - /* Initialize local cache. */ - table = cuddHashTableInit(dd,1,2); - if (table == NULL) return(NULL); - - /* Find deepest real substitution. */ - for (deepest = dd->size - 1; deepest >= 0; deepest--) { - i = dd->invperm[deepest]; - if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) { - break; - } - } - - /* Recursively solve the problem. */ - res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn, - vectorOff,deepest); - if (res != NULL) cuddRef(res); - - /* Dispose of local cache. */ - cuddHashTableQuit(table); - } while (dd->reordered == 1); - - if (res != NULL) cuddDeref(res); - return(res); - -} /* end of Cudd_addGeneralVectorCompose */ - - -/**Function******************************************************************** - - Synopsis [Composes an ADD with a vector of 0-1 ADDs.] - - Description [Given a vector of 0-1 ADDs, creates a new ADD by - substituting the 0-1 ADDs for the variables of the ADD f. There - should be an entry in vector for each variable in the manager. - This function implements non-simultaneous composition. If any of the - functions being composed depends on any of the variables being - substituted, then the result depends on the order of composition, - which in turn depends on the variable order: The variables farther from - the roots in the order are substituted first. - Returns a pointer to the resulting ADD if successful; NULL - otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_addVectorCompose Cudd_addPermute Cudd_addCompose] - -******************************************************************************/ -DdNode * -Cudd_addNonSimCompose( - DdManager * dd, - DdNode * f, - DdNode ** vector) -{ - DdNode *cube, *key, *var, *tmp, *piece; - DdNode *res; - int i, lastsub; - - /* The cache entry for this function is composed of three parts: - ** f itself, the replacement relation, and the cube of the - ** variables being substituted. - ** The replacement relation is the product of the terms (yi EXNOR gi). - ** This apporach allows us to use the global cache for this function, - ** with great savings in memory with respect to using arrays for the - ** cache entries. - ** First we build replacement relation and cube of substituted - ** variables from the vector specifying the desired composition. - */ - key = DD_ONE(dd); - cuddRef(key); - cube = DD_ONE(dd); - cuddRef(cube); - for (i = (int) dd->size - 1; i >= 0; i--) { - if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) { - continue; - } - var = Cudd_addIthVar(dd,i); - if (var == NULL) { - Cudd_RecursiveDeref(dd,key); - Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(var); - /* Update cube. */ - tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,key); - Cudd_RecursiveDeref(dd,cube); - Cudd_RecursiveDeref(dd,var); - return(NULL); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,cube); - cube = tmp; - /* Update replacement relation. */ - piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]); - if (piece == NULL) { - Cudd_RecursiveDeref(dd,key); - Cudd_RecursiveDeref(dd,var); - return(NULL); - } - cuddRef(piece); - Cudd_RecursiveDeref(dd,var); - tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,key); - Cudd_RecursiveDeref(dd,piece); - return(NULL); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,key); - Cudd_RecursiveDeref(dd,piece); - key = tmp; - } - - /* Now try composition, until no reordering occurs. */ - do { - /* Find real substitution with largest index. */ - for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) { - if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) { - break; - } - } - - /* Recursively solve the problem. */ - dd->reordered = 0; - res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1); - if (res != NULL) cuddRef(res); - - } while (dd->reordered == 1); - - Cudd_RecursiveDeref(dd,key); - Cudd_RecursiveDeref(dd,cube); - if (res != NULL) cuddDeref(res); - return(res); - -} /* end of Cudd_addNonSimCompose */ - - -/**Function******************************************************************** - - Synopsis [Composes a BDD with a vector of BDDs.] - - Description [Given a vector of BDDs, creates a new BDD by - substituting the BDDs for the variables of the BDD f. There - should be an entry in vector for each variable in the manager. - If no substitution is sought for a given variable, the corresponding - projection function should be specified in the vector. - This function implements simultaneous composition. - Returns a pointer to the resulting BDD if successful; NULL - otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_bddPermute Cudd_bddCompose Cudd_addVectorCompose] - -******************************************************************************/ -DdNode * -Cudd_bddVectorCompose( - DdManager * dd, - DdNode * f, - DdNode ** vector) -{ - DdHashTable *table; - DdNode *res; - int deepest; - int i; - - do { - dd->reordered = 0; - /* Initialize local cache. */ - table = cuddHashTableInit(dd,1,2); - if (table == NULL) return(NULL); - - /* Find deepest real substitution. */ - for (deepest = dd->size - 1; deepest >= 0; deepest--) { - i = dd->invperm[deepest]; - if (vector[i] != dd->vars[i]) { - break; - } - } - - /* Recursively solve the problem. */ - res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest); - if (res != NULL) cuddRef(res); - - /* Dispose of local cache. */ - cuddHashTableQuit(table); - } while (dd->reordered == 1); - - if (res != NULL) cuddDeref(res); - return(res); - -} /* end of Cudd_bddVectorCompose */ - - -/*---------------------------------------------------------------------------*/ -/* Definition of internal functions */ -/*---------------------------------------------------------------------------*/ - - -/**Function******************************************************************** - - Synopsis [Performs the recursive step of Cudd_bddCompose.] - - Description [Performs the recursive step of Cudd_bddCompose. - Exploits the fact that the composition of f' with g - produces the complement of the composition of f with g to better - utilize the cache. Returns the composed BDD if successful; NULL - otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_bddCompose] - -******************************************************************************/ -DdNode * -cuddBddComposeRecur( - DdManager * dd, - DdNode * f, - DdNode * g, - DdNode * proj) -{ - DdNode *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e; - unsigned int v, topf, topg, topindex; - int comple; - - statLine(dd); - v = dd->perm[proj->index]; - F = Cudd_Regular(f); - topf = cuddI(dd,F->index); - - /* Terminal case. Subsumes the test for constant f. */ - if (topf > v) return(f); - - /* We solve the problem for a regular pointer, and then complement - ** the result if the pointer was originally complemented. - */ - comple = Cudd_IsComplement(f); - - /* Check cache. */ - r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj); - if (r != NULL) { - return(Cudd_NotCond(r,comple)); - } - - if (topf == v) { - /* Compose. */ - f1 = cuddT(F); - f0 = cuddE(F); - r = cuddBddIteRecur(dd, g, f1, f0); - if (r == NULL) return(NULL); - } else { - /* Compute cofactors of f and g. Remember the index of the top - ** variable. - */ - G = Cudd_Regular(g); - topg = cuddI(dd,G->index); - if (topf > topg) { - topindex = G->index; - f1 = f0 = F; - } else { - topindex = F->index; - f1 = cuddT(F); - f0 = cuddE(F); - } - if (topg > topf) { - g1 = g0 = g; - } else { - g1 = cuddT(G); - g0 = cuddE(G); - if (g != G) { - g1 = Cudd_Not(g1); - g0 = Cudd_Not(g0); - } - } - /* Recursive step. */ - t = cuddBddComposeRecur(dd, f1, g1, proj); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddBddComposeRecur(dd, f0, g0, proj); - if (e == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - cuddRef(e); - - r = cuddBddIteRecur(dd, dd->vars[topindex], t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, t); - Cudd_IterDerefBdd(dd, e); - return(NULL); - } - cuddRef(r); - Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */ - Cudd_IterDerefBdd(dd, e); - cuddDeref(r); - } - - cuddCacheInsert(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj,r); - - return(Cudd_NotCond(r,comple)); - -} /* end of cuddBddComposeRecur */ - - -/**Function******************************************************************** - - Synopsis [Performs the recursive step of Cudd_addCompose.] - - Description [Performs the recursive step of Cudd_addCompose. - Returns the composed BDD if successful; NULL otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_addCompose] - -******************************************************************************/ -DdNode * -cuddAddComposeRecur( - DdManager * dd, - DdNode * f, - DdNode * g, - DdNode * proj) -{ - DdNode *f1, *f0, *g1, *g0, *r, *t, *e; - unsigned int v, topf, topg, topindex; - - statLine(dd); - v = dd->perm[proj->index]; - topf = cuddI(dd,f->index); - - /* Terminal case. Subsumes the test for constant f. */ - if (topf > v) return(f); - - /* Check cache. */ - r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj); - if (r != NULL) { - return(r); - } - - if (topf == v) { - /* Compose. */ - f1 = cuddT(f); - f0 = cuddE(f); - r = cuddAddIteRecur(dd, g, f1, f0); - if (r == NULL) return(NULL); - } else { - /* Compute cofactors of f and g. Remember the index of the top - ** variable. - */ - topg = cuddI(dd,g->index); - if (topf > topg) { - topindex = g->index; - f1 = f0 = f; - } else { - topindex = f->index; - f1 = cuddT(f); - f0 = cuddE(f); - } - if (topg > topf) { - g1 = g0 = g; - } else { - g1 = cuddT(g); - g0 = cuddE(g); - } - /* Recursive step. */ - t = cuddAddComposeRecur(dd, f1, g1, proj); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddAddComposeRecur(dd, f0, g0, proj); - if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - cuddRef(e); - - if (t == e) { - r = t; - } else { - r = cuddUniqueInter(dd, (int) topindex, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - return(NULL); - } - } - cuddDeref(t); - cuddDeref(e); - } - - cuddCacheInsert(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj,r); - - return(r); - -} /* end of cuddAddComposeRecur */ - - -/*---------------------------------------------------------------------------*/ -/* Definition of static functions */ -/*---------------------------------------------------------------------------*/ - - -/**Function******************************************************************** - - Synopsis [Implements the recursive step of Cudd_addPermute.] - - Description [ Recursively puts the ADD in the order given in the - array permut. Checks for trivial cases to terminate recursion, then - splits on the children of this node. Once the solutions for the - children are obtained, it puts into the current position the node - from the rest of the ADD that should be here. Then returns this ADD. - The key here is that the node being visited is NOT put in its proper - place by this instance, but rather is switched when its proper - position is reached in the recursion tree.<p> - The DdNode * that is returned is the same ADD as passed in as node, - but in the new order.] - - SideEffects [None] - - SeeAlso [Cudd_addPermute cuddBddPermuteRecur] - -******************************************************************************/ -static DdNode * -cuddAddPermuteRecur( - DdManager * manager /* DD manager */, - DdHashTable * table /* computed table */, - DdNode * node /* ADD to be reordered */, - int * permut /* permutation array */) -{ - DdNode *T,*E; - DdNode *res,*var; - int index; - - statLine(manager); - /* Check for terminal case of constant node. */ - if (cuddIsConstant(node)) { - return(node); - } - - /* If problem already solved, look up answer and return. */ - if (node->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { -#ifdef DD_DEBUG - addPermuteRecurHits++; -#endif - return(res); - } - - /* Split and recur on children of this node. */ - T = cuddAddPermuteRecur(manager,table,cuddT(node),permut); - if (T == NULL) return(NULL); - cuddRef(T); - E = cuddAddPermuteRecur(manager,table,cuddE(node),permut); - if (E == NULL) { - Cudd_RecursiveDeref(manager, T); - return(NULL); - } - cuddRef(E); - - /* Move variable that should be in this position to this position - ** by creating a single var ADD for that variable, and calling - ** cuddAddIteRecur with the T and E we just created. - */ - index = permut[node->index]; - var = cuddUniqueInter(manager,index,DD_ONE(manager),DD_ZERO(manager)); - if (var == NULL) return(NULL); - cuddRef(var); - res = cuddAddIteRecur(manager,var,T,E); - if (res == NULL) { - Cudd_RecursiveDeref(manager,var); - Cudd_RecursiveDeref(manager, T); - Cudd_RecursiveDeref(manager, E); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(manager,var); - Cudd_RecursiveDeref(manager, T); - Cudd_RecursiveDeref(manager, E); - - /* Do not keep the result if the reference count is only 1, since - ** it will not be visited again. - */ - if (node->ref != 1) { - ptrint fanout = (ptrint) node->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,node,res,fanout)) { - Cudd_RecursiveDeref(manager, res); - return(NULL); - } - } - cuddDeref(res); - return(res); - -} /* end of cuddAddPermuteRecur */ - - -/**Function******************************************************************** - - Synopsis [Implements the recursive step of Cudd_bddPermute.] - - Description [ Recursively puts the BDD in the order given in the array permut. - Checks for trivial cases to terminate recursion, then splits on the - children of this node. Once the solutions for the children are - obtained, it puts into the current position the node from the rest of - the BDD that should be here. Then returns this BDD. - The key here is that the node being visited is NOT put in its proper - place by this instance, but rather is switched when its proper position - is reached in the recursion tree.<p> - The DdNode * that is returned is the same BDD as passed in as node, - but in the new order.] - - SideEffects [None] - - SeeAlso [Cudd_bddPermute cuddAddPermuteRecur] - -******************************************************************************/ -static DdNode * -cuddBddPermuteRecur( - DdManager * manager /* DD manager */, - DdHashTable * table /* computed table */, - DdNode * node /* BDD to be reordered */, - int * permut /* permutation array */) -{ - DdNode *N,*T,*E; - DdNode *res; - int index; - - statLine(manager); - N = Cudd_Regular(node); - - /* Check for terminal case of constant node. */ - if (cuddIsConstant(N)) { - return(node); - } - - /* If problem already solved, look up answer and return. */ - if (N->ref != 1 && (res = cuddHashTableLookup1(table,N)) != NULL) { -#ifdef DD_DEBUG - bddPermuteRecurHits++; -#endif - return(Cudd_NotCond(res,N != node)); - } - - /* Split and recur on children of this node. */ - T = cuddBddPermuteRecur(manager,table,cuddT(N),permut); - if (T == NULL) return(NULL); - cuddRef(T); - E = cuddBddPermuteRecur(manager,table,cuddE(N),permut); - 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 = permut[N->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 (N->ref != 1) { - ptrint fanout = (ptrint) N->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,N,res,fanout)) { - Cudd_IterDerefBdd(manager, res); - return(NULL); - } - } - cuddDeref(res); - return(Cudd_NotCond(res,N != node)); - -} /* end of cuddBddPermuteRecur */ - - -/**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_addVectorCompose.] - - Description [] - - SideEffects [None] - - SeeAlso [] - -******************************************************************************/ -static DdNode * -cuddAddVectorComposeRecur( - DdManager * dd /* DD manager */, - DdHashTable * table /* computed table */, - DdNode * f /* ADD in which to compose */, - DdNode ** vector /* functions to substitute */, - int deepest /* depth of deepest substitution */) -{ - DdNode *T,*E; - DdNode *res; - - statLine(dd); - /* If we are past the deepest substitution, return f. */ - if (cuddI(dd,f->index) > deepest) { - return(f); - } - - if ((res = cuddHashTableLookup1(table,f)) != NULL) { -#ifdef DD_DEBUG - addVectorComposeHits++; -#endif - return(res); - } - - /* Split and recur on children of this node. */ - T = cuddAddVectorComposeRecur(dd,table,cuddT(f),vector,deepest); - if (T == NULL) return(NULL); - cuddRef(T); - E = cuddAddVectorComposeRecur(dd,table,cuddE(f),vector,deepest); - if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - cuddRef(E); - - /* Retrieve the 0-1 ADD for the current top variable and call - ** cuddAddIteRecur with the T and E we just created. - */ - res = cuddAddIteRecur(dd,vector[f->index],T,E); - if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - - /* Do not keep the result if the reference count is only 1, since - ** it will not be visited again - */ - if (f->ref != 1) { - ptrint fanout = (ptrint) f->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,f,res,fanout)) { - Cudd_RecursiveDeref(dd, res); - return(NULL); - } - } - cuddDeref(res); - return(res); - -} /* end of cuddAddVectorComposeRecur */ - - -/**Function******************************************************************** - - Synopsis [Performs the recursive step of Cudd_addGeneralVectorCompose.] - - Description [] - - SideEffects [None] - - SeeAlso [] - -******************************************************************************/ -static DdNode * -cuddAddGeneralVectorComposeRecur( - DdManager * dd /* DD manager */, - DdHashTable * table /* computed table */, - DdNode * f /* ADD in which to compose */, - DdNode ** vectorOn /* functions to substitute for x_i */, - DdNode ** vectorOff /* functions to substitute for x_i' */, - int deepest /* depth of deepest substitution */) -{ - DdNode *T,*E,*t,*e; - DdNode *res; - - /* If we are past the deepest substitution, return f. */ - if (cuddI(dd,f->index) > deepest) { - return(f); - } - - if ((res = cuddHashTableLookup1(table,f)) != NULL) { -#ifdef DD_DEBUG - addGeneralVectorComposeHits++; -#endif - return(res); - } - - /* Split and recur on children of this node. */ - T = cuddAddGeneralVectorComposeRecur(dd,table,cuddT(f), - vectorOn,vectorOff,deepest); - if (T == NULL) return(NULL); - cuddRef(T); - E = cuddAddGeneralVectorComposeRecur(dd,table,cuddE(f), - vectorOn,vectorOff,deepest); - if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - cuddRef(E); - - /* Retrieve the compose ADDs for the current top variable and call - ** cuddAddApplyRecur with the T and E we just created. - */ - t = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOn[f->index],T); - if (t == NULL) { - Cudd_RecursiveDeref(dd,T); - Cudd_RecursiveDeref(dd,E); - return(NULL); - } - cuddRef(t); - e = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOff[f->index],E); - if (e == NULL) { - Cudd_RecursiveDeref(dd,T); - Cudd_RecursiveDeref(dd,E); - Cudd_RecursiveDeref(dd,t); - return(NULL); - } - cuddRef(e); - res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e); - if (res == NULL) { - Cudd_RecursiveDeref(dd,T); - Cudd_RecursiveDeref(dd,E); - Cudd_RecursiveDeref(dd,t); - Cudd_RecursiveDeref(dd,e); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(dd,T); - Cudd_RecursiveDeref(dd,E); - Cudd_RecursiveDeref(dd,t); - Cudd_RecursiveDeref(dd,e); - - /* Do not keep the result if the reference count is only 1, since - ** it will not be visited again - */ - if (f->ref != 1) { - ptrint fanout = (ptrint) f->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,f,res,fanout)) { - Cudd_RecursiveDeref(dd, res); - return(NULL); - } - } - cuddDeref(res); - return(res); - -} /* end of cuddAddGeneralVectorComposeRecur */ - - -/**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 */ - - -/**Function******************************************************************** - - Synopsis [Performs the recursive step of Cudd_bddVectorCompose.] - - Description [] - - SideEffects [None] - - SeeAlso [] - -******************************************************************************/ -static DdNode * -cuddBddVectorComposeRecur( - DdManager * dd /* DD manager */, - DdHashTable * table /* computed table */, - DdNode * f /* BDD in which to compose */, - DdNode ** vector /* functions to be composed */, - int deepest /* depth of the deepest substitution */) -{ - DdNode *F,*T,*E; - DdNode *res; - - statLine(dd); - F = Cudd_Regular(f); - - /* If we are past the deepest substitution, return f. */ - if (cuddI(dd,F->index) > deepest) { - return(f); - } - - /* If problem already solved, look up answer and return. */ - if ((res = cuddHashTableLookup1(table,F)) != NULL) { -#ifdef DD_DEBUG - bddVectorComposeHits++; -#endif - return(Cudd_NotCond(res,F != f)); - } - - /* Split and recur on children of this node. */ - T = cuddBddVectorComposeRecur(dd,table,cuddT(F),vector, deepest); - if (T == NULL) return(NULL); - cuddRef(T); - E = cuddBddVectorComposeRecur(dd,table,cuddE(F),vector, deepest); - if (E == NULL) { - Cudd_IterDerefBdd(dd, T); - return(NULL); - } - cuddRef(E); - - /* Call cuddBddIteRecur with the BDD that replaces the current top - ** variable and the T and E we just created. - */ - res = cuddBddIteRecur(dd,vector[F->index],T,E); - if (res == NULL) { - Cudd_IterDerefBdd(dd, T); - Cudd_IterDerefBdd(dd, E); - return(NULL); - } - cuddRef(res); - Cudd_IterDerefBdd(dd, T); - Cudd_IterDerefBdd(dd, E); - - /* Do not keep the result if the reference count is only 1, since - ** it will not be visited again. - */ - if (F->ref != 1) { - ptrint fanout = (ptrint) F->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,F,res,fanout)) { - Cudd_IterDerefBdd(dd, res); - return(NULL); - } - } - cuddDeref(res); - return(Cudd_NotCond(res,F != f)); - -} /* end of cuddBddVectorComposeRecur */ - - -/**Function******************************************************************** - - Synopsis [Comparison of a function to the i-th ADD variable.] - - Description [Comparison of a function to the i-th ADD variable. Returns 1 if - the function is the i-th ADD variable; 0 otherwise.] - - SideEffects [None] - - SeeAlso [] - -******************************************************************************/ -DD_INLINE -static int -ddIsIthAddVar( - DdManager * dd, - DdNode * f, - unsigned int i) -{ - return(f->index == i && cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd)); - -} /* end of ddIsIthAddVar */ - - -/**Function******************************************************************** - - Synopsis [Comparison of a pair of functions to the i-th ADD variable.] - - Description [Comparison of a pair of functions to the i-th ADD - variable. Returns 1 if the functions are the i-th ADD variable and its - complement; 0 otherwise.] - - SideEffects [None] - - SeeAlso [] - -******************************************************************************/ -DD_INLINE -static int -ddIsIthAddVarPair( - DdManager * dd, - DdNode * f, - DdNode * g, - unsigned int i) -{ - return(f->index == i && g->index == i && - cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd) && - cuddT(g) == DD_ZERO(dd) && cuddE(g) == DD_ONE(dd)); - -} /* end of ddIsIthAddVarPair */ |