src/bdd/cudd/cuddCompose.c File Reference

#include "util_hack.h"
#include "cuddInt.h"
Include dependency graph for cuddCompose.c:

Go to the source code of this file.

Functions

static DdNode *cuddAddPermuteRecur 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 DD_INLINE 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))
static DD_INLINE int
ddIsIthAddVarPair 
ARGS ((DdManager *dd, DdNode *f, DdNode *g, unsigned int i))
DdNodeCudd_bddCompose (DdManager *dd, DdNode *f, DdNode *g, int v)
DdNodeCudd_addCompose (DdManager *dd, DdNode *f, DdNode *g, int v)
DdNodeCudd_addPermute (DdManager *manager, DdNode *node, int *permut)
DdNodeCudd_addSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n)
DdNodeCudd_bddPermute (DdManager *manager, DdNode *node, int *permut)
DdNodeCudd_bddVarMap (DdManager *manager, DdNode *f)
int Cudd_SetVarMap (DdManager *manager, DdNode **x, DdNode **y, int n)
DdNodeCudd_bddSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n)
DdNodeCudd_bddAdjPermuteX (DdManager *dd, DdNode *B, DdNode **x, int n)
DdNodeCudd_addVectorCompose (DdManager *dd, DdNode *f, DdNode **vector)
DdNodeCudd_addGeneralVectorCompose (DdManager *dd, DdNode *f, DdNode **vectorOn, DdNode **vectorOff)
DdNodeCudd_addNonSimCompose (DdManager *dd, DdNode *f, DdNode **vector)
DdNodeCudd_bddVectorCompose (DdManager *dd, DdNode *f, DdNode **vector)
DdNodecuddBddComposeRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *proj)
DdNodecuddAddComposeRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *proj)
static DdNodecuddAddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut)
static DdNodecuddBddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut)
static DdNodecuddBddVarMapRecur (DdManager *manager, DdNode *f)
static DdNodecuddAddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest)
static DdNodecuddAddGeneralVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest)
static DdNodecuddAddNonSimComposeRecur (DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub)
static DdNodecuddBddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest)
static DD_INLINE int ddIsIthAddVar (DdManager *dd, DdNode *f, unsigned int i)
static DD_INLINE int ddIsIthAddVarPair (DdManager *dd, DdNode *f, DdNode *g, unsigned int i)

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddCompose.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"

Function Documentation

static DD_INLINE int ddIsIthAddVarPair ARGS ( (DdManager *dd, DdNode *f, DdNode *g, unsigned int i)   )  [static]
static DdNode* cuddAddGeneralVectorComposeRecur ARGS ( (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest)   )  [static]
static DD_INLINE int ddIsIthAddVar ARGS ( (DdManager *dd, DdNode *f, unsigned int i)   )  [static]
static DdNode* cuddAddNonSimComposeRecur ARGS ( (DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub)   )  [static]
static DdNode *cuddBddVectorComposeRecur ARGS ( (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest)   )  [static]
static DdNode* cuddBddVarMapRecur ARGS ( (DdManager *manager, DdNode *f)   )  [static]
static DdNode *cuddBddPermuteRecur ARGS ( (DdManager *manager, DdHashTable *table, DdNode *node, int *permut)   )  [static]

AutomaticStart

DdNode* Cudd_addCompose ( DdManager dd,
DdNode f,
DdNode g,
int  v 
)

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]

Definition at line 173 of file cuddCompose.c.

00178 {
00179     DdNode *proj, *res;
00180 
00181     /* Sanity check. */
00182     if (v < 0 || v > dd->size) return(NULL);
00183 
00184     proj =  dd->vars[v];
00185     do {
00186         dd->reordered = 0;
00187         res = cuddAddComposeRecur(dd,f,g,proj);
00188     } while (dd->reordered == 1);
00189     return(res);
00190 
00191 } /* end of Cudd_addCompose */

DdNode* Cudd_addGeneralVectorCompose ( DdManager dd,
DdNode f,
DdNode **  vectorOn,
DdNode **  vectorOff 
)

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]

Definition at line 590 of file cuddCompose.c.

00595 {
00596     DdHashTable         *table;
00597     DdNode              *res;
00598     int                 deepest;
00599     int                 i;
00600 
00601     do {
00602         dd->reordered = 0;
00603         /* Initialize local cache. */
00604         table = cuddHashTableInit(dd,1,2);
00605         if (table == NULL) return(NULL);
00606 
00607         /* Find deepest real substitution. */
00608         for (deepest = dd->size - 1; deepest >= 0; deepest--) {
00609             i = dd->invperm[deepest];
00610             if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) {
00611                 break;
00612             }
00613         }
00614 
00615         /* Recursively solve the problem. */
00616         res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn,
00617                                                vectorOff,deepest);
00618         if (res != NULL) cuddRef(res);
00619 
00620         /* Dispose of local cache. */
00621         cuddHashTableQuit(table);
00622     } while (dd->reordered == 1);
00623 
00624     if (res != NULL) cuddDeref(res);
00625     return(res);
00626 
00627 } /* end of Cudd_addGeneralVectorCompose */

DdNode* Cudd_addNonSimCompose ( DdManager dd,
DdNode f,
DdNode **  vector 
)

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]

Definition at line 651 of file cuddCompose.c.

00655 {
00656     DdNode              *cube, *key, *var, *tmp, *piece;
00657     DdNode              *res;
00658     int                 i, lastsub;
00659 
00660     /* The cache entry for this function is composed of three parts:
00661     ** f itself, the replacement relation, and the cube of the
00662     ** variables being substituted.
00663     ** The replacement relation is the product of the terms (yi EXNOR gi).
00664     ** This apporach allows us to use the global cache for this function,
00665     ** with great savings in memory with respect to using arrays for the
00666     ** cache entries.
00667     ** First we build replacement relation and cube of substituted
00668     ** variables from the vector specifying the desired composition.
00669     */
00670     key = DD_ONE(dd);
00671     cuddRef(key);
00672     cube = DD_ONE(dd);
00673     cuddRef(cube);
00674     for (i = (int) dd->size - 1; i >= 0; i--) {
00675         if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) {
00676             continue;
00677         }
00678         var = Cudd_addIthVar(dd,i);
00679         if (var == NULL) {
00680             Cudd_RecursiveDeref(dd,key);
00681             Cudd_RecursiveDeref(dd,cube);
00682             return(NULL);
00683         }
00684         cuddRef(var);
00685         /* Update cube. */
00686         tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube);
00687         if (tmp == NULL) {
00688             Cudd_RecursiveDeref(dd,key);
00689             Cudd_RecursiveDeref(dd,cube);
00690             Cudd_RecursiveDeref(dd,var);
00691             return(NULL);
00692         }
00693         cuddRef(tmp);
00694         Cudd_RecursiveDeref(dd,cube);
00695         cube = tmp;
00696         /* Update replacement relation. */
00697         piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]);
00698         if (piece == NULL) {
00699             Cudd_RecursiveDeref(dd,key);
00700             Cudd_RecursiveDeref(dd,var);
00701             return(NULL);
00702         }
00703         cuddRef(piece);
00704         Cudd_RecursiveDeref(dd,var);
00705         tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece);
00706         if (tmp == NULL) {
00707             Cudd_RecursiveDeref(dd,key);
00708             Cudd_RecursiveDeref(dd,piece);
00709             return(NULL);
00710         }
00711         cuddRef(tmp);
00712         Cudd_RecursiveDeref(dd,key);
00713         Cudd_RecursiveDeref(dd,piece);
00714         key = tmp;
00715     }
00716 
00717     /* Now try composition, until no reordering occurs. */
00718     do {
00719         /* Find real substitution with largest index. */
00720         for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) {
00721             if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) {
00722                 break;
00723             }
00724         }
00725 
00726         /* Recursively solve the problem. */
00727         dd->reordered = 0;
00728         res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1);
00729         if (res != NULL) cuddRef(res);
00730 
00731     } while (dd->reordered == 1);
00732 
00733     Cudd_RecursiveDeref(dd,key);
00734     Cudd_RecursiveDeref(dd,cube);
00735     if (res != NULL) cuddDeref(res);
00736     return(res);
00737 
00738 } /* end of Cudd_addNonSimCompose */

DdNode* Cudd_addPermute ( DdManager manager,
DdNode node,
int *  permut 
)

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]

Definition at line 211 of file cuddCompose.c.

00215 {
00216     DdHashTable         *table;
00217     DdNode              *res;
00218 
00219     do {
00220         manager->reordered = 0;
00221         table = cuddHashTableInit(manager,1,2);
00222         if (table == NULL) return(NULL);
00223         /* Recursively solve the problem. */
00224         res = cuddAddPermuteRecur(manager,table,node,permut);
00225         if (res != NULL) cuddRef(res);
00226         /* Dispose of local cache. */
00227         cuddHashTableQuit(table);
00228     } while (manager->reordered == 1);
00229 
00230     if (res != NULL) cuddDeref(res);
00231     return(res);
00232 
00233 } /* end of Cudd_addPermute */

DdNode* Cudd_addSwapVariables ( DdManager dd,
DdNode f,
DdNode **  x,
DdNode **  y,
int  n 
)

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]

Definition at line 252 of file cuddCompose.c.

00258 {
00259     DdNode *swapped;
00260     int  i, j, k;
00261     int  *permut;
00262 
00263     permut = ALLOC(int,dd->size);
00264     if (permut == NULL) {
00265         dd->errorCode = CUDD_MEMORY_OUT;
00266         return(NULL);
00267     }
00268     for (i = 0; i < dd->size; i++) permut[i] = i;
00269     for (i = 0; i < n; i++) {
00270         j = x[i]->index;
00271         k = y[i]->index;
00272         permut[j] = k;
00273         permut[k] = j;
00274     }
00275 
00276     swapped = Cudd_addPermute(dd,f,permut);
00277     FREE(permut);
00278 
00279     return(swapped);
00280 
00281 } /* end of Cudd_addSwapVariables */

DdNode* Cudd_addVectorCompose ( DdManager dd,
DdNode f,
DdNode **  vector 
)

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]

Definition at line 532 of file cuddCompose.c.

00536 {
00537     DdHashTable         *table;
00538     DdNode              *res;
00539     int                 deepest;
00540     int                 i;
00541 
00542     do {
00543         dd->reordered = 0;
00544         /* Initialize local cache. */
00545         table = cuddHashTableInit(dd,1,2);
00546         if (table == NULL) return(NULL);
00547 
00548         /* Find deepest real substitution. */
00549         for (deepest = dd->size - 1; deepest >= 0; deepest--) {
00550             i = dd->invperm[deepest];
00551             if (!ddIsIthAddVar(dd,vector[i],i)) {
00552                 break;
00553             }
00554         }
00555 
00556         /* Recursively solve the problem. */
00557         res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest);
00558         if (res != NULL) cuddRef(res);
00559 
00560         /* Dispose of local cache. */
00561         cuddHashTableQuit(table);
00562     } while (dd->reordered == 1);
00563 
00564     if (res != NULL) cuddDeref(res);
00565     return(res);
00566 
00567 } /* end of Cudd_addVectorCompose */

DdNode* Cudd_bddAdjPermuteX ( DdManager dd,
DdNode B,
DdNode **  x,
int  n 
)

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]

Definition at line 481 of file cuddCompose.c.

00486 {
00487     DdNode *swapped;
00488     int  i, j, k;
00489     int  *permut;
00490 
00491     permut = ALLOC(int,dd->size);
00492     if (permut == NULL) {
00493         dd->errorCode = CUDD_MEMORY_OUT;
00494         return(NULL);
00495     }
00496     for (i = 0; i < dd->size; i++) permut[i] = i;
00497     for (i = 0; i < n-2; i += 3) {
00498         j = x[i]->index;
00499         k = x[i+1]->index;
00500         permut[j] = k;
00501         permut[k] = j;
00502     }
00503 
00504     swapped = Cudd_bddPermute(dd,B,permut);
00505     FREE(permut);
00506 
00507     return(swapped);
00508 
00509 } /* end of Cudd_bddAdjPermuteX */

DdNode* Cudd_bddCompose ( DdManager dd,
DdNode f,
DdNode g,
int  v 
)

AutomaticEnd 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]

Definition at line 136 of file cuddCompose.c.

00141 {
00142     DdNode *proj, *res;
00143 
00144     /* Sanity check. */
00145     if (v < 0 || v > dd->size) return(NULL);
00146 
00147     proj =  dd->vars[v];
00148     do {
00149         dd->reordered = 0;
00150         res = cuddBddComposeRecur(dd,f,g,proj);
00151     } while (dd->reordered == 1);
00152     return(res);
00153 
00154 } /* end of Cudd_bddCompose */

DdNode* Cudd_bddPermute ( DdManager manager,
DdNode node,
int *  permut 
)

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]

Definition at line 301 of file cuddCompose.c.

00305 {
00306     DdHashTable         *table;
00307     DdNode              *res;
00308 
00309     do {
00310         manager->reordered = 0;
00311         table = cuddHashTableInit(manager,1,2);
00312         if (table == NULL) return(NULL);
00313         res = cuddBddPermuteRecur(manager,table,node,permut);
00314         if (res != NULL) cuddRef(res);
00315         /* Dispose of local cache. */
00316         cuddHashTableQuit(table);
00317 
00318     } while (manager->reordered == 1);
00319 
00320     if (res != NULL) cuddDeref(res);
00321     return(res);
00322 
00323 } /* end of Cudd_bddPermute */

DdNode* Cudd_bddSwapVariables ( DdManager dd,
DdNode f,
DdNode **  x,
DdNode **  y,
int  n 
)

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]

Definition at line 433 of file cuddCompose.c.

00439 {
00440     DdNode *swapped;
00441     int  i, j, k;
00442     int  *permut;
00443 
00444     permut = ALLOC(int,dd->size);
00445     if (permut == NULL) {
00446         dd->errorCode = CUDD_MEMORY_OUT;
00447         return(NULL);
00448     }
00449     for (i = 0; i < dd->size; i++) permut[i] = i;
00450     for (i = 0; i < n; i++) {
00451         j = x[i]->index;
00452         k = y[i]->index;
00453         permut[j] = k;
00454         permut[k] = j;
00455     }
00456 
00457     swapped = Cudd_bddPermute(dd,f,permut);
00458     FREE(permut);
00459 
00460     return(swapped);
00461 
00462 } /* end of Cudd_bddSwapVariables */

DdNode* Cudd_bddVarMap ( DdManager manager,
DdNode f 
)

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]

Definition at line 342 of file cuddCompose.c.

00345 {
00346     DdNode *res;
00347 
00348     if (manager->map == NULL) return(NULL);
00349     do {
00350         manager->reordered = 0;
00351         res = cuddBddVarMapRecur(manager, f);
00352     } while (manager->reordered == 1);
00353 
00354     return(res);
00355 
00356 } /* end of Cudd_bddVarMap */

DdNode* Cudd_bddVectorCompose ( DdManager dd,
DdNode f,
DdNode **  vector 
)

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]

Definition at line 760 of file cuddCompose.c.

00764 {
00765     DdHashTable         *table;
00766     DdNode              *res;
00767     int                 deepest;
00768     int                 i;
00769 
00770     do {
00771         dd->reordered = 0;
00772         /* Initialize local cache. */
00773         table = cuddHashTableInit(dd,1,2);
00774         if (table == NULL) return(NULL);
00775 
00776         /* Find deepest real substitution. */
00777         for (deepest = dd->size - 1; deepest >= 0; deepest--) {
00778             i = dd->invperm[deepest];
00779             if (vector[i] != dd->vars[i]) {
00780                 break;
00781             }
00782         }
00783 
00784         /* Recursively solve the problem. */
00785         res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest);
00786         if (res != NULL) cuddRef(res);
00787 
00788         /* Dispose of local cache. */
00789         cuddHashTableQuit(table);
00790     } while (dd->reordered == 1);
00791 
00792     if (res != NULL) cuddDeref(res);
00793     return(res);
00794 
00795 } /* end of Cudd_bddVectorCompose */

int Cudd_SetVarMap ( DdManager manager,
DdNode **  x,
DdNode **  y,
int  n 
)

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]

Definition at line 385 of file cuddCompose.c.

00390 {
00391     int i;
00392 
00393     if (manager->map != NULL) {
00394         cuddCacheFlush(manager);
00395     } else {
00396         manager->map = ALLOC(int,manager->maxSize);
00397         if (manager->map == NULL) {
00398             manager->errorCode = CUDD_MEMORY_OUT;
00399             return(0);
00400         }
00401         manager->memused += sizeof(int) * manager->maxSize;
00402     }
00403     /* Initialize the map to the identity. */
00404     for (i = 0; i < manager->size; i++) {
00405         manager->map[i] = i;
00406     }
00407     /* Create the map. */
00408     for (i = 0; i < n; i++) {
00409         manager->map[x[i]->index] = y[i]->index;
00410         manager->map[y[i]->index] = x[i]->index;
00411     }
00412     return(1);
00413 
00414 } /* end of Cudd_SetVarMap */

DdNode* cuddAddComposeRecur ( DdManager dd,
DdNode f,
DdNode g,
DdNode proj 
)

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]

Definition at line 921 of file cuddCompose.c.

00926 {
00927     DdNode *f1, *f0, *g1, *g0, *r, *t, *e;
00928     unsigned int v, topf, topg, topindex;
00929 
00930     statLine(dd);
00931     v = dd->perm[proj->index];
00932     topf = cuddI(dd,f->index);
00933 
00934     /* Terminal case. Subsumes the test for constant f. */
00935     if (topf > v) return(f);
00936 
00937     /* Check cache. */
00938     r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj);
00939     if (r != NULL) {
00940         return(r);
00941     }
00942 
00943     if (topf == v) {
00944         /* Compose. */
00945         f1 = cuddT(f);
00946         f0 = cuddE(f);
00947         r = cuddAddIteRecur(dd, g, f1, f0);
00948         if (r == NULL) return(NULL);
00949     } else {
00950         /* Compute cofactors of f and g. Remember the index of the top
00951         ** variable.
00952         */
00953         topg = cuddI(dd,g->index);
00954         if (topf > topg) {
00955             topindex = g->index;
00956             f1 = f0 = f;
00957         } else {
00958             topindex = f->index;
00959             f1 = cuddT(f);
00960             f0 = cuddE(f);
00961         }
00962         if (topg > topf) {
00963             g1 = g0 = g;
00964         } else {
00965             g1 = cuddT(g);
00966             g0 = cuddE(g);
00967         }
00968         /* Recursive step. */
00969         t = cuddAddComposeRecur(dd, f1, g1, proj);
00970         if (t == NULL) return(NULL);
00971         cuddRef(t);
00972         e = cuddAddComposeRecur(dd, f0, g0, proj);
00973         if (e == NULL) {
00974             Cudd_RecursiveDeref(dd, t);
00975             return(NULL);
00976         }
00977         cuddRef(e);
00978 
00979         if (t == e) {
00980             r = t;
00981         } else {
00982             r = cuddUniqueInter(dd, (int) topindex, t, e);
00983             if (r == NULL) {
00984                 Cudd_RecursiveDeref(dd, t);
00985                 Cudd_RecursiveDeref(dd, e);
00986                 return(NULL);
00987             }
00988         }
00989         cuddDeref(t);
00990         cuddDeref(e);
00991     }
00992 
00993     cuddCacheInsert(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj,r);
00994 
00995     return(r);
00996 
00997 } /* end of cuddAddComposeRecur */

static DdNode* cuddAddGeneralVectorComposeRecur ( DdManager dd,
DdHashTable table,
DdNode f,
DdNode **  vectorOn,
DdNode **  vectorOff,
int  deepest 
) [static]

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_addGeneralVectorCompose.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1349 of file cuddCompose.c.

01356 {
01357     DdNode      *T,*E,*t,*e;
01358     DdNode      *res;
01359 
01360     /* If we are past the deepest substitution, return f. */
01361     if (cuddI(dd,f->index) > deepest) {
01362         return(f);
01363     }
01364 
01365     if ((res = cuddHashTableLookup1(table,f)) != NULL) {
01366 #ifdef DD_DEBUG
01367         addGeneralVectorComposeHits++;
01368 #endif
01369         return(res);
01370     }
01371 
01372     /* Split and recur on children of this node. */
01373     T = cuddAddGeneralVectorComposeRecur(dd,table,cuddT(f),
01374                                          vectorOn,vectorOff,deepest);
01375     if (T == NULL)  return(NULL);
01376     cuddRef(T);
01377     E = cuddAddGeneralVectorComposeRecur(dd,table,cuddE(f),
01378                                          vectorOn,vectorOff,deepest);
01379     if (E == NULL) {
01380         Cudd_RecursiveDeref(dd, T);
01381         return(NULL);
01382     }
01383     cuddRef(E);
01384 
01385     /* Retrieve the compose ADDs for the current top variable and call
01386     ** cuddAddApplyRecur with the T and E we just created.
01387     */
01388     t = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOn[f->index],T);
01389     if (t == NULL) {
01390       Cudd_RecursiveDeref(dd,T);
01391       Cudd_RecursiveDeref(dd,E);
01392       return(NULL);
01393     }
01394     cuddRef(t);
01395     e = cuddAddApplyRecur(dd,Cudd_addTimes,vectorOff[f->index],E);
01396     if (e == NULL) {
01397       Cudd_RecursiveDeref(dd,T);
01398       Cudd_RecursiveDeref(dd,E);
01399       Cudd_RecursiveDeref(dd,t);
01400       return(NULL);
01401     }
01402     cuddRef(e);
01403     res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e);
01404     if (res == NULL) {
01405       Cudd_RecursiveDeref(dd,T);
01406       Cudd_RecursiveDeref(dd,E);
01407       Cudd_RecursiveDeref(dd,t);
01408       Cudd_RecursiveDeref(dd,e);
01409       return(NULL);
01410     }
01411     cuddRef(res);
01412     Cudd_RecursiveDeref(dd,T);
01413     Cudd_RecursiveDeref(dd,E);
01414     Cudd_RecursiveDeref(dd,t);
01415     Cudd_RecursiveDeref(dd,e);
01416 
01417     /* Do not keep the result if the reference count is only 1, since
01418     ** it will not be visited again
01419     */
01420     if (f->ref != 1) {
01421         ptrint fanout = (ptrint) f->ref;
01422         cuddSatDec(fanout);
01423         if (!cuddHashTableInsert1(table,f,res,fanout)) {
01424             Cudd_RecursiveDeref(dd, res);
01425             return(NULL);
01426         }
01427     }
01428     cuddDeref(res);
01429     return(res);
01430 
01431 } /* end of cuddAddGeneralVectorComposeRecur */

static DdNode* cuddAddNonSimComposeRecur ( DdManager dd,
DdNode f,
DdNode **  vector,
DdNode key,
DdNode cube,
int  lastsub 
) [static]

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_addNonSimCompose.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1446 of file cuddCompose.c.

01453 {
01454     DdNode *f1, *f0, *key1, *key0, *cube1, *var;
01455     DdNode *T,*E;
01456     DdNode *r;
01457     unsigned int top, topf, topk, topc;
01458     unsigned int index;
01459     int i;
01460     DdNode **vect1;
01461     DdNode **vect0;
01462 
01463     statLine(dd);
01464     /* If we are past the deepest substitution, return f. */
01465     if (cube == DD_ONE(dd) || cuddIsConstant(f)) {
01466         return(f);
01467     }
01468 
01469     /* If problem already solved, look up answer and return. */
01470     r = cuddCacheLookup(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube);
01471     if (r != NULL) {
01472         return(r);
01473     }
01474 
01475     /* Find top variable. we just need to look at f, key, and cube,
01476     ** because all the varibles in the gi are in key.
01477     */
01478     topf = cuddI(dd,f->index);
01479     topk = cuddI(dd,key->index);
01480     top = ddMin(topf,topk);
01481     topc = cuddI(dd,cube->index);
01482     top = ddMin(top,topc);
01483     index = dd->invperm[top];
01484 
01485     /* Compute the cofactors. */
01486     if (topf == top) {
01487         f1 = cuddT(f);
01488         f0 = cuddE(f);
01489     } else {
01490         f1 = f0 = f;
01491     }
01492     if (topc == top) {
01493         cube1 = cuddT(cube);
01494         /* We want to eliminate vector[index] from key. Otherwise
01495         ** cache performance is severely affected. Hence we
01496         ** existentially quantify the variable with index "index" from key.
01497         */
01498         var = Cudd_addIthVar(dd, (int) index);
01499         if (var == NULL) {
01500             return(NULL);
01501         }
01502         cuddRef(var);
01503         key1 = cuddAddExistAbstractRecur(dd, key, var);
01504         if (key1 == NULL) {
01505             Cudd_RecursiveDeref(dd,var);
01506             return(NULL);
01507         }
01508         cuddRef(key1);
01509         Cudd_RecursiveDeref(dd,var);
01510         key0 = key1;
01511     } else {
01512         cube1 = cube;
01513         if (topk == top) {
01514             key1 = cuddT(key);
01515             key0 = cuddE(key);
01516         } else {
01517             key1 = key0 = key;
01518         }
01519         cuddRef(key1);
01520     }
01521 
01522     /* Allocate two new vectors for the cofactors of vector. */
01523     vect1 = ALLOC(DdNode *,lastsub);
01524     if (vect1 == NULL) {
01525         dd->errorCode = CUDD_MEMORY_OUT;
01526         Cudd_RecursiveDeref(dd,key1);
01527         return(NULL);
01528     }
01529     vect0 = ALLOC(DdNode *,lastsub);
01530     if (vect0 == NULL) {
01531         dd->errorCode = CUDD_MEMORY_OUT;
01532         Cudd_RecursiveDeref(dd,key1);
01533         FREE(vect1);
01534         return(NULL);
01535     }
01536 
01537     /* Cofactor the gi. Eliminate vect1[index] and vect0[index], because
01538     ** we do not need them.
01539     */
01540     for (i = 0; i < lastsub; i++) {
01541         DdNode *gi = vector[i];
01542         if (gi == NULL) {
01543             vect1[i] = vect0[i] = NULL;
01544         } else if (gi->index == index) {
01545             vect1[i] = cuddT(gi);
01546             vect0[i] = cuddE(gi);
01547         } else {
01548             vect1[i] = vect0[i] = gi;
01549         }
01550     }
01551     vect1[index] = vect0[index] = NULL;
01552 
01553     /* Recur on children. */
01554     T = cuddAddNonSimComposeRecur(dd,f1,vect1,key1,cube1,lastsub);
01555     FREE(vect1);
01556     if (T == NULL) {
01557         Cudd_RecursiveDeref(dd,key1);
01558         FREE(vect0);
01559         return(NULL);
01560     }
01561     cuddRef(T);
01562     E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub);
01563     FREE(vect0);
01564     if (E == NULL) {
01565         Cudd_RecursiveDeref(dd,key1);
01566         Cudd_RecursiveDeref(dd,T);
01567         return(NULL);
01568     }
01569     cuddRef(E);
01570     Cudd_RecursiveDeref(dd,key1);
01571 
01572     /* Retrieve the 0-1 ADD for the current top variable from vector,
01573     ** and call cuddAddIteRecur with the T and E we just created.
01574     */
01575     r = cuddAddIteRecur(dd,vector[index],T,E);
01576     if (r == NULL) {
01577         Cudd_RecursiveDeref(dd,T);
01578         Cudd_RecursiveDeref(dd,E);
01579         return(NULL);
01580     }
01581     cuddRef(r);
01582     Cudd_RecursiveDeref(dd,T);
01583     Cudd_RecursiveDeref(dd,E);
01584     cuddDeref(r);
01585 
01586     /* Store answer to trim recursion. */
01587     cuddCacheInsert(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube,r);
01588 
01589     return(r);
01590 
01591 } /* end of cuddAddNonSimComposeRecur */

static DdNode* cuddAddPermuteRecur ( DdManager manager,
DdHashTable table,
DdNode node,
int *  permut 
) [static]

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.

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]

Definition at line 1026 of file cuddCompose.c.

01031 {
01032     DdNode      *T,*E;
01033     DdNode      *res,*var;
01034     int         index;
01035     
01036     statLine(manager);
01037     /* Check for terminal case of constant node. */
01038     if (cuddIsConstant(node)) {
01039         return(node);
01040     }
01041 
01042     /* If problem already solved, look up answer and return. */
01043     if (node->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) {
01044 #ifdef DD_DEBUG
01045         addPermuteRecurHits++;
01046 #endif
01047         return(res);
01048     }
01049 
01050     /* Split and recur on children of this node. */
01051     T = cuddAddPermuteRecur(manager,table,cuddT(node),permut);
01052     if (T == NULL) return(NULL);
01053     cuddRef(T);
01054     E = cuddAddPermuteRecur(manager,table,cuddE(node),permut);
01055     if (E == NULL) {
01056         Cudd_RecursiveDeref(manager, T);
01057         return(NULL);
01058     }
01059     cuddRef(E);
01060 
01061     /* Move variable that should be in this position to this position
01062     ** by creating a single var ADD for that variable, and calling
01063     ** cuddAddIteRecur with the T and E we just created.
01064     */
01065     index = permut[node->index];
01066     var = cuddUniqueInter(manager,index,DD_ONE(manager),DD_ZERO(manager));
01067     if (var == NULL) return(NULL);
01068     cuddRef(var);
01069     res = cuddAddIteRecur(manager,var,T,E);
01070     if (res == NULL) {
01071         Cudd_RecursiveDeref(manager,var);
01072         Cudd_RecursiveDeref(manager, T);
01073         Cudd_RecursiveDeref(manager, E);
01074         return(NULL);
01075     }
01076     cuddRef(res);
01077     Cudd_RecursiveDeref(manager,var);
01078     Cudd_RecursiveDeref(manager, T);
01079     Cudd_RecursiveDeref(manager, E);
01080 
01081     /* Do not keep the result if the reference count is only 1, since
01082     ** it will not be visited again.
01083     */
01084     if (node->ref != 1) {
01085         ptrint fanout = (ptrint) node->ref;
01086         cuddSatDec(fanout);
01087         if (!cuddHashTableInsert1(table,node,res,fanout)) {
01088             Cudd_RecursiveDeref(manager, res);
01089             return(NULL);
01090         }
01091     }
01092     cuddDeref(res);
01093     return(res);
01094 
01095 } /* end of cuddAddPermuteRecur */

static DdNode* cuddAddVectorComposeRecur ( DdManager dd,
DdHashTable table,
DdNode f,
DdNode **  vector,
int  deepest 
) [static]

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_addVectorCompose.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1273 of file cuddCompose.c.

01279 {
01280     DdNode      *T,*E;
01281     DdNode      *res;
01282 
01283     statLine(dd);
01284     /* If we are past the deepest substitution, return f. */
01285     if (cuddI(dd,f->index) > deepest) {
01286         return(f);
01287     }
01288 
01289     if ((res = cuddHashTableLookup1(table,f)) != NULL) {
01290 #ifdef DD_DEBUG
01291         addVectorComposeHits++;
01292 #endif
01293         return(res);
01294     }
01295 
01296     /* Split and recur on children of this node. */
01297     T = cuddAddVectorComposeRecur(dd,table,cuddT(f),vector,deepest);
01298     if (T == NULL)  return(NULL);
01299     cuddRef(T);
01300     E = cuddAddVectorComposeRecur(dd,table,cuddE(f),vector,deepest);
01301     if (E == NULL) {
01302         Cudd_RecursiveDeref(dd, T);
01303         return(NULL);
01304     }
01305     cuddRef(E);
01306 
01307     /* Retrieve the 0-1 ADD for the current top variable and call
01308     ** cuddAddIteRecur with the T and E we just created.
01309     */
01310     res = cuddAddIteRecur(dd,vector[f->index],T,E);
01311     if (res == NULL) {
01312         Cudd_RecursiveDeref(dd, T);
01313         Cudd_RecursiveDeref(dd, E);
01314         return(NULL);
01315     }
01316     cuddRef(res);
01317     Cudd_RecursiveDeref(dd, T);
01318     Cudd_RecursiveDeref(dd, E);
01319 
01320     /* Do not keep the result if the reference count is only 1, since
01321     ** it will not be visited again
01322     */
01323     if (f->ref != 1) {
01324         ptrint fanout = (ptrint) f->ref;
01325         cuddSatDec(fanout);
01326         if (!cuddHashTableInsert1(table,f,res,fanout)) {
01327             Cudd_RecursiveDeref(dd, res);
01328             return(NULL);
01329         }
01330     }
01331     cuddDeref(res);
01332     return(res);
01333 
01334 } /* end of cuddAddVectorComposeRecur */

DdNode* cuddBddComposeRecur ( DdManager dd,
DdNode f,
DdNode g,
DdNode proj 
)

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]

Definition at line 819 of file cuddCompose.c.

00824 {
00825     DdNode      *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e;
00826     unsigned int v, topf, topg, topindex;
00827     int         comple;
00828 
00829     statLine(dd);
00830     v = dd->perm[proj->index];
00831     F = Cudd_Regular(f);
00832     topf = cuddI(dd,F->index);
00833 
00834     /* Terminal case. Subsumes the test for constant f. */
00835     if (topf > v) return(f);
00836 
00837     /* We solve the problem for a regular pointer, and then complement
00838     ** the result if the pointer was originally complemented.
00839     */
00840     comple = Cudd_IsComplement(f);
00841 
00842     /* Check cache. */
00843     r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj);
00844     if (r != NULL) {
00845         return(Cudd_NotCond(r,comple));
00846     }
00847 
00848     if (topf == v) {
00849         /* Compose. */
00850         f1 = cuddT(F);
00851         f0 = cuddE(F);
00852         r = cuddBddIteRecur(dd, g, f1, f0);
00853         if (r == NULL) return(NULL);
00854     } else {
00855         /* Compute cofactors of f and g. Remember the index of the top
00856         ** variable.
00857         */
00858         G = Cudd_Regular(g);
00859         topg = cuddI(dd,G->index);
00860         if (topf > topg) {
00861             topindex = G->index;
00862             f1 = f0 = F;
00863         } else {
00864             topindex = F->index;
00865             f1 = cuddT(F);
00866             f0 = cuddE(F);
00867         }
00868         if (topg > topf) {
00869             g1 = g0 = g;
00870         } else {
00871             g1 = cuddT(G);
00872             g0 = cuddE(G);
00873             if (g != G) {
00874                 g1 = Cudd_Not(g1);
00875                 g0 = Cudd_Not(g0);
00876             }
00877         }
00878         /* Recursive step. */
00879         t = cuddBddComposeRecur(dd, f1, g1, proj);
00880         if (t == NULL) return(NULL);
00881         cuddRef(t);
00882         e = cuddBddComposeRecur(dd, f0, g0, proj);
00883         if (e == NULL) {
00884             Cudd_IterDerefBdd(dd, t);
00885             return(NULL);
00886         }
00887         cuddRef(e);
00888 
00889         r = cuddBddIteRecur(dd, dd->vars[topindex], t, e);
00890         if (r == NULL) {
00891             Cudd_IterDerefBdd(dd, t);
00892             Cudd_IterDerefBdd(dd, e);
00893             return(NULL);
00894         }
00895         cuddRef(r);
00896         Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */
00897         Cudd_IterDerefBdd(dd, e);
00898         cuddDeref(r);
00899     }
00900 
00901     cuddCacheInsert(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj,r);
00902 
00903     return(Cudd_NotCond(r,comple));
00904 
00905 } /* end of cuddBddComposeRecur */

static DdNode* cuddBddPermuteRecur ( DdManager manager,
DdHashTable table,
DdNode node,
int *  permut 
) [static]

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.

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]

Definition at line 1119 of file cuddCompose.c.

01124 {
01125     DdNode      *N,*T,*E;
01126     DdNode      *res;
01127     int         index;
01128 
01129     statLine(manager);
01130     N = Cudd_Regular(node);
01131 
01132     /* Check for terminal case of constant node. */
01133     if (cuddIsConstant(N)) {
01134         return(node);
01135     }
01136 
01137     /* If problem already solved, look up answer and return. */
01138     if (N->ref != 1 && (res = cuddHashTableLookup1(table,N)) != NULL) {
01139 #ifdef DD_DEBUG
01140         bddPermuteRecurHits++;
01141 #endif
01142         return(Cudd_NotCond(res,N != node));
01143     }
01144 
01145     /* Split and recur on children of this node. */
01146     T = cuddBddPermuteRecur(manager,table,cuddT(N),permut);
01147     if (T == NULL) return(NULL);
01148     cuddRef(T);
01149     E = cuddBddPermuteRecur(manager,table,cuddE(N),permut);
01150     if (E == NULL) {
01151         Cudd_IterDerefBdd(manager, T);
01152         return(NULL);
01153     }
01154     cuddRef(E);
01155 
01156     /* Move variable that should be in this position to this position
01157     ** by retrieving the single var BDD for that variable, and calling
01158     ** cuddBddIteRecur with the T and E we just created.
01159     */
01160     index = permut[N->index];
01161     res = cuddBddIteRecur(manager,manager->vars[index],T,E);
01162     if (res == NULL) {
01163         Cudd_IterDerefBdd(manager, T);
01164         Cudd_IterDerefBdd(manager, E);
01165         return(NULL);
01166     }
01167     cuddRef(res);
01168     Cudd_IterDerefBdd(manager, T);
01169     Cudd_IterDerefBdd(manager, E);
01170 
01171     /* Do not keep the result if the reference count is only 1, since
01172     ** it will not be visited again.
01173     */
01174     if (N->ref != 1) {
01175         ptrint fanout = (ptrint) N->ref;
01176         cuddSatDec(fanout);
01177         if (!cuddHashTableInsert1(table,N,res,fanout)) {
01178             Cudd_IterDerefBdd(manager, res);
01179             return(NULL);
01180         }
01181     }
01182     cuddDeref(res);
01183     return(Cudd_NotCond(res,N != node));
01184 
01185 } /* end of cuddBddPermuteRecur */

static DdNode* cuddBddVarMapRecur ( DdManager manager,
DdNode f 
) [static]

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]

Definition at line 1201 of file cuddCompose.c.

01204 {
01205     DdNode      *F, *T, *E;
01206     DdNode      *res;
01207     int         index;
01208 
01209     statLine(manager);
01210     F = Cudd_Regular(f);
01211 
01212     /* Check for terminal case of constant node. */
01213     if (cuddIsConstant(F)) {
01214         return(f);
01215     }
01216 
01217     /* If problem already solved, look up answer and return. */
01218     if (F->ref != 1 &&
01219         (res = cuddCacheLookup1(manager,Cudd_bddVarMap,F)) != NULL) {
01220         return(Cudd_NotCond(res,F != f));
01221     }
01222 
01223     /* Split and recur on children of this node. */
01224     T = cuddBddVarMapRecur(manager,cuddT(F));
01225     if (T == NULL) return(NULL);
01226     cuddRef(T);
01227     E = cuddBddVarMapRecur(manager,cuddE(F));
01228     if (E == NULL) {
01229         Cudd_IterDerefBdd(manager, T);
01230         return(NULL);
01231     }
01232     cuddRef(E);
01233 
01234     /* Move variable that should be in this position to this position
01235     ** by retrieving the single var BDD for that variable, and calling
01236     ** cuddBddIteRecur with the T and E we just created.
01237     */
01238     index = manager->map[F->index];
01239     res = cuddBddIteRecur(manager,manager->vars[index],T,E);
01240     if (res == NULL) {
01241         Cudd_IterDerefBdd(manager, T);
01242         Cudd_IterDerefBdd(manager, E);
01243         return(NULL);
01244     }
01245     cuddRef(res);
01246     Cudd_IterDerefBdd(manager, T);
01247     Cudd_IterDerefBdd(manager, E);
01248 
01249     /* Do not keep the result if the reference count is only 1, since
01250     ** it will not be visited again.
01251     */
01252     if (F->ref != 1) {
01253         cuddCacheInsert1(manager,Cudd_bddVarMap,F,res);
01254     }
01255     cuddDeref(res);
01256     return(Cudd_NotCond(res,F != f));
01257 
01258 } /* end of cuddBddVarMapRecur */

static DdNode* cuddBddVectorComposeRecur ( DdManager dd,
DdHashTable table,
DdNode f,
DdNode **  vector,
int  deepest 
) [static]

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_bddVectorCompose.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1606 of file cuddCompose.c.

01612 {
01613     DdNode      *F,*T,*E;
01614     DdNode      *res;
01615 
01616     statLine(dd);
01617     F = Cudd_Regular(f);
01618 
01619     /* If we are past the deepest substitution, return f. */
01620     if (cuddI(dd,F->index) > deepest) {
01621         return(f);
01622     }
01623 
01624     /* If problem already solved, look up answer and return. */
01625     if ((res = cuddHashTableLookup1(table,F)) != NULL) {
01626 #ifdef DD_DEBUG
01627         bddVectorComposeHits++;
01628 #endif
01629         return(Cudd_NotCond(res,F != f));
01630     }
01631 
01632     /* Split and recur on children of this node. */
01633     T = cuddBddVectorComposeRecur(dd,table,cuddT(F),vector, deepest);
01634     if (T == NULL) return(NULL);
01635     cuddRef(T);
01636     E = cuddBddVectorComposeRecur(dd,table,cuddE(F),vector, deepest);
01637     if (E == NULL) {
01638         Cudd_IterDerefBdd(dd, T);
01639         return(NULL);
01640     }
01641     cuddRef(E);
01642 
01643     /* Call cuddBddIteRecur with the BDD that replaces the current top
01644     ** variable and the T and E we just created.
01645     */
01646     res = cuddBddIteRecur(dd,vector[F->index],T,E);
01647     if (res == NULL) {
01648         Cudd_IterDerefBdd(dd, T);
01649         Cudd_IterDerefBdd(dd, E);
01650         return(NULL);
01651     }
01652     cuddRef(res);
01653     Cudd_IterDerefBdd(dd, T);
01654     Cudd_IterDerefBdd(dd, E);   
01655 
01656     /* Do not keep the result if the reference count is only 1, since
01657     ** it will not be visited again.
01658     */
01659     if (F->ref != 1) {
01660         ptrint fanout = (ptrint) F->ref;
01661         cuddSatDec(fanout);
01662         if (!cuddHashTableInsert1(table,F,res,fanout)) {
01663             Cudd_IterDerefBdd(dd, res);
01664             return(NULL);
01665         }
01666     }
01667     cuddDeref(res);
01668     return(Cudd_NotCond(res,F != f));
01669 
01670 } /* end of cuddBddVectorComposeRecur */

static DD_INLINE int ddIsIthAddVar ( DdManager dd,
DdNode f,
unsigned int  i 
) [static]

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 []

Definition at line 1687 of file cuddCompose.c.

01691 {
01692     return(f->index == i && cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd));
01693 
01694 } /* end of ddIsIthAddVar */

static DD_INLINE int ddIsIthAddVarPair ( DdManager dd,
DdNode f,
DdNode g,
unsigned int  i 
) [static]

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 []

Definition at line 1712 of file cuddCompose.c.

01717 {
01718     return(f->index == i && g->index == i && 
01719            cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd) &&
01720            cuddT(g) == DD_ZERO(dd) && cuddE(g) == DD_ONE(dd));
01721 
01722 } /* end of ddIsIthAddVarPair */


Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddCompose.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $" [static]

CFile***********************************************************************

FileName [cuddCompose.c]

PackageName [cudd]

Synopsis [Functional composition and variable permutation of DDs.]

Description [External procedures included in this module:

Internal procedures included in this module:

Static procedures included in this module:

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.]

Definition at line 79 of file cuddCompose.c.


Generated on Tue Jan 5 12:18:54 2010 for abc70930 by  doxygen 1.6.1