#include "util_hack.h"
#include "cuddInt.h"
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)) |
DdNode * | Cudd_bddCompose (DdManager *dd, DdNode *f, DdNode *g, int v) |
DdNode * | Cudd_addCompose (DdManager *dd, DdNode *f, DdNode *g, int v) |
DdNode * | Cudd_addPermute (DdManager *manager, DdNode *node, int *permut) |
DdNode * | Cudd_addSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n) |
DdNode * | Cudd_bddPermute (DdManager *manager, DdNode *node, int *permut) |
DdNode * | Cudd_bddVarMap (DdManager *manager, DdNode *f) |
int | Cudd_SetVarMap (DdManager *manager, DdNode **x, DdNode **y, int n) |
DdNode * | Cudd_bddSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n) |
DdNode * | Cudd_bddAdjPermuteX (DdManager *dd, DdNode *B, DdNode **x, int n) |
DdNode * | Cudd_addVectorCompose (DdManager *dd, DdNode *f, DdNode **vector) |
DdNode * | Cudd_addGeneralVectorCompose (DdManager *dd, DdNode *f, DdNode **vectorOn, DdNode **vectorOff) |
DdNode * | Cudd_addNonSimCompose (DdManager *dd, DdNode *f, DdNode **vector) |
DdNode * | Cudd_bddVectorCompose (DdManager *dd, DdNode *f, DdNode **vector) |
DdNode * | cuddBddComposeRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *proj) |
DdNode * | cuddAddComposeRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *proj) |
static DdNode * | cuddAddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut) |
static DdNode * | cuddBddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut) |
static DdNode * | cuddBddVarMapRecur (DdManager *manager, DdNode *f) |
static DdNode * | cuddAddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest) |
static DdNode * | cuddAddGeneralVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest) |
static DdNode * | cuddAddNonSimComposeRecur (DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub) |
static DdNode * | cuddBddVectorComposeRecur (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 $" |
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 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 *cuddBddPermuteRecur ARGS | ( | (DdManager *manager, DdHashTable *table, DdNode *node, int *permut) | ) | [static] |
AutomaticStart
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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.
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 */
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 */
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 */
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 */
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 */
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.
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.
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.