#include "util.h"
#include "cuddInt.h"
Go to the source code of this file.
Defines | |
#define | MODULUS1 2147483563 |
#define | LEQA1 40014 |
#define | LEQQ1 53668 |
#define | LEQR1 12211 |
#define | MODULUS2 2147483399 |
#define | LEQA2 40692 |
#define | LEQQ2 52774 |
#define | LEQR2 3791 |
#define | STAB_SIZE 64 |
#define | STAB_DIV (1 + (MODULUS1 - 1) / STAB_SIZE) |
#define | bang(f) ((Cudd_IsComplement(f)) ? '!' : ' ') |
Functions | |
static int | dp2 (DdManager *dd, DdNode *f, st_table *t) |
static void | ddPrintMintermAux (DdManager *dd, DdNode *node, int *list) |
static int | ddDagInt (DdNode *n) |
static int | cuddNodeArrayRecur (DdNode *f, DdNodePtr *table, int index) |
static int | cuddEstimateCofactor (DdManager *dd, st_table *table, DdNode *node, int i, int phase, DdNode **ptr) |
static DdNode * | cuddUniqueLookup (DdManager *unique, int index, DdNode *T, DdNode *E) |
static int | cuddEstimateCofactorSimple (DdNode *node, int i) |
static double | ddCountMintermAux (DdNode *node, double max, DdHashTable *table) |
static int | ddEpdCountMintermAux (DdNode *node, EpDouble *max, EpDouble *epd, st_table *table) |
static double | ddCountPathAux (DdNode *node, st_table *table) |
static double | ddCountPathsToNonZero (DdNode *N, st_table *table) |
static void | ddSupportStep (DdNode *f, int *support) |
static void | ddClearFlag (DdNode *f) |
static int | ddLeavesInt (DdNode *n) |
static int | ddPickArbitraryMinterms (DdManager *dd, DdNode *node, int nvars, int nminterms, char **string) |
static int | ddPickRepresentativeCube (DdManager *dd, DdNode *node, double *weight, char *string) |
static enum st_retval | ddEpdFree (char *key, char *value, char *arg) |
int | Cudd_PrintMinterm (DdManager *manager, DdNode *node) |
int | Cudd_bddPrintCover (DdManager *dd, DdNode *l, DdNode *u) |
int | Cudd_PrintDebug (DdManager *dd, DdNode *f, int n, int pr) |
int | Cudd_DagSize (DdNode *node) |
int | Cudd_EstimateCofactor (DdManager *dd, DdNode *f, int i, int phase) |
int | Cudd_EstimateCofactorSimple (DdNode *node, int i) |
int | Cudd_SharingSize (DdNode **nodeArray, int n) |
double | Cudd_CountMinterm (DdManager *manager, DdNode *node, int nvars) |
double | Cudd_CountPath (DdNode *node) |
int | Cudd_EpdCountMinterm (DdManager *manager, DdNode *node, int nvars, EpDouble *epd) |
double | Cudd_CountPathsToNonZero (DdNode *node) |
DdNode * | Cudd_Support (DdManager *dd, DdNode *f) |
int * | Cudd_SupportIndex (DdManager *dd, DdNode *f) |
int | Cudd_SupportSize (DdManager *dd, DdNode *f) |
DdNode * | Cudd_VectorSupport (DdManager *dd, DdNode **F, int n) |
int * | Cudd_VectorSupportIndex (DdManager *dd, DdNode **F, int n) |
int | Cudd_VectorSupportSize (DdManager *dd, DdNode **F, int n) |
int | Cudd_ClassifySupport (DdManager *dd, DdNode *f, DdNode *g, DdNode **common, DdNode **onlyF, DdNode **onlyG) |
int | Cudd_CountLeaves (DdNode *node) |
int | Cudd_bddPickOneCube (DdManager *ddm, DdNode *node, char *string) |
DdNode * | Cudd_bddPickOneMinterm (DdManager *dd, DdNode *f, DdNode **vars, int n) |
DdNode ** | Cudd_bddPickArbitraryMinterms (DdManager *dd, DdNode *f, DdNode **vars, int n, int k) |
DdNode * | Cudd_SubsetWithMaskVars (DdManager *dd, DdNode *f, DdNode **vars, int nvars, DdNode **maskVars, int mvars) |
DdGen * | Cudd_FirstCube (DdManager *dd, DdNode *f, int **cube, CUDD_VALUE_TYPE *value) |
int | Cudd_NextCube (DdGen *gen, int **cube, CUDD_VALUE_TYPE *value) |
DdGen * | Cudd_FirstPrime (DdManager *dd, DdNode *l, DdNode *u, int **cube) |
int | Cudd_NextPrime (DdGen *gen, int **cube) |
DdNode * | Cudd_bddComputeCube (DdManager *dd, DdNode **vars, int *phase, int n) |
DdNode * | Cudd_addComputeCube (DdManager *dd, DdNode **vars, int *phase, int n) |
DdNode * | Cudd_CubeArrayToBdd (DdManager *dd, int *array) |
int | Cudd_BddToCubeArray (DdManager *dd, DdNode *cube, int *array) |
DdGen * | Cudd_FirstNode (DdManager *dd, DdNode *f, DdNode **node) |
int | Cudd_NextNode (DdGen *gen, DdNode **node) |
int | Cudd_GenFree (DdGen *gen) |
int | Cudd_IsGenEmpty (DdGen *gen) |
DdNode * | Cudd_IndicesToCube (DdManager *dd, int *array, int n) |
void | Cudd_PrintVersion (FILE *fp) |
double | Cudd_AverageDistance (DdManager *dd) |
long | Cudd_Random (void) |
void | Cudd_Srandom (long seed) |
double | Cudd_Density (DdManager *dd, DdNode *f, int nvars) |
void | Cudd_OutOfMem (long size) |
int | cuddP (DdManager *dd, DdNode *f) |
enum st_retval | cuddStCountfree (char *key, char *value, char *arg) |
int | cuddCollectNodes (DdNode *f, st_table *visited) |
DdNodePtr * | cuddNodeArray (DdNode *f, int *n) |
Variables | |
static char rcsid[] | DD_UNUSED = "$Id: cuddUtil.c,v 1.81 2009/03/08 02:49:02 fabio Exp $" |
static DdNode * | background |
static DdNode * | zero |
static long | cuddRand = 0 |
static long | cuddRand2 |
static long | shuffleSelect |
static long | shuffleTable [STAB_SIZE] |
#define bang | ( | f | ) | ((Cudd_IsComplement(f)) ? '!' : ' ') |
Definition at line 155 of file cuddUtil.c.
#define LEQA1 40014 |
Definition at line 117 of file cuddUtil.c.
#define LEQA2 40692 |
Definition at line 121 of file cuddUtil.c.
#define LEQQ1 53668 |
Definition at line 118 of file cuddUtil.c.
#define LEQQ2 52774 |
Definition at line 122 of file cuddUtil.c.
#define LEQR1 12211 |
Definition at line 119 of file cuddUtil.c.
#define LEQR2 3791 |
Definition at line 123 of file cuddUtil.c.
#define MODULUS1 2147483563 |
CFile***********************************************************************
FileName [cuddUtil.c]
PackageName [cudd]
Synopsis [Utility functions.]
Description [External procedures included in this module:
Internal procedures included in this module:
Static procedures included in this module:
]
Author [Fabio Somenzi]
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]
Definition at line 116 of file cuddUtil.c.
#define MODULUS2 2147483399 |
Definition at line 120 of file cuddUtil.c.
#define STAB_DIV (1 + (MODULUS1 - 1) / STAB_SIZE) |
Definition at line 125 of file cuddUtil.c.
#define STAB_SIZE 64 |
Definition at line 124 of file cuddUtil.c.
Function********************************************************************
Synopsis [Computes the cube of an array of ADD variables.]
Description [Computes the cube of an array of ADD variables. If non-null, the phase argument indicates which literal of each variable should appear in the cube. If phase\[i\] is nonzero, then the positive literal is used. If phase is NULL, the cube is positive unate. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [none]
SeeAlso [Cudd_bddComputeCube]
Definition at line 2242 of file cuddUtil.c.
02247 { 02248 DdNode *cube, *zero; 02249 DdNode *fn; 02250 int i; 02251 02252 cube = DD_ONE(dd); 02253 cuddRef(cube); 02254 zero = DD_ZERO(dd); 02255 02256 for (i = n - 1; i >= 0; i--) { 02257 if (phase == NULL || phase[i] != 0) { 02258 fn = Cudd_addIte(dd,vars[i],cube,zero); 02259 } else { 02260 fn = Cudd_addIte(dd,vars[i],zero,cube); 02261 } 02262 if (fn == NULL) { 02263 Cudd_RecursiveDeref(dd,cube); 02264 return(NULL); 02265 } 02266 cuddRef(fn); 02267 Cudd_RecursiveDeref(dd,cube); 02268 cube = fn; 02269 } 02270 cuddDeref(cube); 02271 02272 return(cube); 02273 02274 } /* end of Cudd_addComputeCube */
double Cudd_AverageDistance | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Computes the average distance between adjacent nodes.]
Description [Computes the average distance between adjacent nodes in the manager. Adjacent nodes are node pairs such that the second node is the then child, else child, or next node in the collision list.]
SideEffects [None]
SeeAlso []
Definition at line 2610 of file cuddUtil.c.
02612 { 02613 double tetotal, nexttotal; 02614 double tesubtotal, nextsubtotal; 02615 double temeasured, nextmeasured; 02616 int i, j; 02617 int slots, nvars; 02618 long diff; 02619 DdNode *scan; 02620 DdNodePtr *nodelist; 02621 DdNode *sentinel = &(dd->sentinel); 02622 02623 nvars = dd->size; 02624 if (nvars == 0) return(0.0); 02625 02626 /* Initialize totals. */ 02627 tetotal = 0.0; 02628 nexttotal = 0.0; 02629 temeasured = 0.0; 02630 nextmeasured = 0.0; 02631 02632 /* Scan the variable subtables. */ 02633 for (i = 0; i < nvars; i++) { 02634 nodelist = dd->subtables[i].nodelist; 02635 tesubtotal = 0.0; 02636 nextsubtotal = 0.0; 02637 slots = dd->subtables[i].slots; 02638 for (j = 0; j < slots; j++) { 02639 scan = nodelist[j]; 02640 while (scan != sentinel) { 02641 diff = (long) scan - (long) cuddT(scan); 02642 tesubtotal += (double) ddAbs(diff); 02643 diff = (long) scan - (long) Cudd_Regular(cuddE(scan)); 02644 tesubtotal += (double) ddAbs(diff); 02645 temeasured += 2.0; 02646 if (scan->next != sentinel) { 02647 diff = (long) scan - (long) scan->next; 02648 nextsubtotal += (double) ddAbs(diff); 02649 nextmeasured += 1.0; 02650 } 02651 scan = scan->next; 02652 } 02653 } 02654 tetotal += tesubtotal; 02655 nexttotal += nextsubtotal; 02656 } 02657 02658 /* Scan the constant table. */ 02659 nodelist = dd->constants.nodelist; 02660 nextsubtotal = 0.0; 02661 slots = dd->constants.slots; 02662 for (j = 0; j < slots; j++) { 02663 scan = nodelist[j]; 02664 while (scan != NULL) { 02665 if (scan->next != NULL) { 02666 diff = (long) scan - (long) scan->next; 02667 nextsubtotal += (double) ddAbs(diff); 02668 nextmeasured += 1.0; 02669 } 02670 scan = scan->next; 02671 } 02672 } 02673 nexttotal += nextsubtotal; 02674 02675 return((tetotal + nexttotal) / (temeasured + nextmeasured)); 02676 02677 } /* end of Cudd_AverageDistance */
Function********************************************************************
Synopsis [Computes the cube of an array of BDD variables.]
Description [Computes the cube of an array of BDD variables. If non-null, the phase argument indicates which literal of each variable should appear in the cube. If phase\[i\] is nonzero, then the positive literal is used. If phase is NULL, the cube is positive unate. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addComputeCube Cudd_IndicesToCube Cudd_CubeArrayToBdd]
Definition at line 2192 of file cuddUtil.c.
02197 { 02198 DdNode *cube; 02199 DdNode *fn; 02200 int i; 02201 02202 cube = DD_ONE(dd); 02203 cuddRef(cube); 02204 02205 for (i = n - 1; i >= 0; i--) { 02206 if (phase == NULL || phase[i] != 0) { 02207 fn = Cudd_bddAnd(dd,vars[i],cube); 02208 } else { 02209 fn = Cudd_bddAnd(dd,Cudd_Not(vars[i]),cube); 02210 } 02211 if (fn == NULL) { 02212 Cudd_RecursiveDeref(dd,cube); 02213 return(NULL); 02214 } 02215 cuddRef(fn); 02216 Cudd_RecursiveDeref(dd,cube); 02217 cube = fn; 02218 } 02219 cuddDeref(cube); 02220 02221 return(cube); 02222 02223 } /* end of Cudd_bddComputeCube */
Function********************************************************************
Synopsis [Picks k on-set minterms evenly distributed from given DD.]
Description [Picks k on-set minterms evenly distributed from given DD. The minterms are in terms of vars
. The array vars
should contain at least all variables in the support of f
; if this condition is not met the minterms built by this procedure may not be contained in f
. Builds an array of BDDs for the minterms and returns a pointer to it if successful; NULL otherwise. There are three reasons why the procedure may fail:
f
may be the constant 0; f
. ]
SideEffects [None]
SeeAlso [Cudd_bddPickOneMinterm Cudd_bddPickOneCube]
Definition at line 1389 of file cuddUtil.c.
01395 { 01396 char **string; 01397 int i, j, l, size; 01398 int *indices; 01399 int result; 01400 DdNode **old, *neW; 01401 double minterms; 01402 char *saveString; 01403 int saveFlag, savePoint, isSame; 01404 01405 minterms = Cudd_CountMinterm(dd,f,n); 01406 if ((double)k > minterms) { 01407 return(NULL); 01408 } 01409 01410 size = dd->size; 01411 string = ALLOC(char *, k); 01412 if (string == NULL) { 01413 dd->errorCode = CUDD_MEMORY_OUT; 01414 return(NULL); 01415 } 01416 for (i = 0; i < k; i++) { 01417 string[i] = ALLOC(char, size + 1); 01418 if (string[i] == NULL) { 01419 for (j = 0; j < i; j++) 01420 FREE(string[i]); 01421 FREE(string); 01422 dd->errorCode = CUDD_MEMORY_OUT; 01423 return(NULL); 01424 } 01425 for (j = 0; j < size; j++) string[i][j] = '2'; 01426 string[i][size] = '\0'; 01427 } 01428 indices = ALLOC(int,n); 01429 if (indices == NULL) { 01430 dd->errorCode = CUDD_MEMORY_OUT; 01431 for (i = 0; i < k; i++) 01432 FREE(string[i]); 01433 FREE(string); 01434 return(NULL); 01435 } 01436 01437 for (i = 0; i < n; i++) { 01438 indices[i] = vars[i]->index; 01439 } 01440 01441 result = ddPickArbitraryMinterms(dd,f,n,k,string); 01442 if (result == 0) { 01443 for (i = 0; i < k; i++) 01444 FREE(string[i]); 01445 FREE(string); 01446 FREE(indices); 01447 return(NULL); 01448 } 01449 01450 old = ALLOC(DdNode *, k); 01451 if (old == NULL) { 01452 dd->errorCode = CUDD_MEMORY_OUT; 01453 for (i = 0; i < k; i++) 01454 FREE(string[i]); 01455 FREE(string); 01456 FREE(indices); 01457 return(NULL); 01458 } 01459 saveString = ALLOC(char, size + 1); 01460 if (saveString == NULL) { 01461 dd->errorCode = CUDD_MEMORY_OUT; 01462 for (i = 0; i < k; i++) 01463 FREE(string[i]); 01464 FREE(string); 01465 FREE(indices); 01466 FREE(old); 01467 return(NULL); 01468 } 01469 saveFlag = 0; 01470 01471 /* Build result BDD array. */ 01472 for (i = 0; i < k; i++) { 01473 isSame = 0; 01474 if (!saveFlag) { 01475 for (j = i + 1; j < k; j++) { 01476 if (strcmp(string[i], string[j]) == 0) { 01477 savePoint = i; 01478 strcpy(saveString, string[i]); 01479 saveFlag = 1; 01480 break; 01481 } 01482 } 01483 } else { 01484 if (strcmp(string[i], saveString) == 0) { 01485 isSame = 1; 01486 } else { 01487 saveFlag = 0; 01488 for (j = i + 1; j < k; j++) { 01489 if (strcmp(string[i], string[j]) == 0) { 01490 savePoint = i; 01491 strcpy(saveString, string[i]); 01492 saveFlag = 1; 01493 break; 01494 } 01495 } 01496 } 01497 } 01498 /* Randomize choice for don't cares. */ 01499 for (j = 0; j < n; j++) { 01500 if (string[i][indices[j]] == '2') 01501 string[i][indices[j]] = 01502 (char) ((Cudd_Random() & 0x20) ? '1' : '0'); 01503 } 01504 01505 while (isSame) { 01506 isSame = 0; 01507 for (j = savePoint; j < i; j++) { 01508 if (strcmp(string[i], string[j]) == 0) { 01509 isSame = 1; 01510 break; 01511 } 01512 } 01513 if (isSame) { 01514 strcpy(string[i], saveString); 01515 /* Randomize choice for don't cares. */ 01516 for (j = 0; j < n; j++) { 01517 if (string[i][indices[j]] == '2') 01518 string[i][indices[j]] = 01519 (char) ((Cudd_Random() & 0x20) ? '1' : '0'); 01520 } 01521 } 01522 } 01523 01524 old[i] = Cudd_ReadOne(dd); 01525 cuddRef(old[i]); 01526 01527 for (j = 0; j < n; j++) { 01528 if (string[i][indices[j]] == '0') { 01529 neW = Cudd_bddAnd(dd,old[i],Cudd_Not(vars[j])); 01530 } else { 01531 neW = Cudd_bddAnd(dd,old[i],vars[j]); 01532 } 01533 if (neW == NULL) { 01534 FREE(saveString); 01535 for (l = 0; l < k; l++) 01536 FREE(string[l]); 01537 FREE(string); 01538 FREE(indices); 01539 for (l = 0; l <= i; l++) 01540 Cudd_RecursiveDeref(dd,old[l]); 01541 FREE(old); 01542 return(NULL); 01543 } 01544 cuddRef(neW); 01545 Cudd_RecursiveDeref(dd,old[i]); 01546 old[i] = neW; 01547 } 01548 01549 /* Test. */ 01550 if (!Cudd_bddLeq(dd,old[i],f)) { 01551 FREE(saveString); 01552 for (l = 0; l < k; l++) 01553 FREE(string[l]); 01554 FREE(string); 01555 FREE(indices); 01556 for (l = 0; l <= i; l++) 01557 Cudd_RecursiveDeref(dd,old[l]); 01558 FREE(old); 01559 return(NULL); 01560 } 01561 } 01562 01563 FREE(saveString); 01564 for (i = 0; i < k; i++) { 01565 cuddDeref(old[i]); 01566 FREE(string[i]); 01567 } 01568 FREE(string); 01569 FREE(indices); 01570 return(old); 01571 01572 } /* end of Cudd_bddPickArbitraryMinterms */
Function********************************************************************
Synopsis [Picks one on-set cube randomly from the given DD.]
Description [Picks one on-set cube randomly from the given DD. The cube is written into an array of characters. The array must have at least as many entries as there are variables. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddPickOneMinterm]
Definition at line 1217 of file cuddUtil.c.
01221 { 01222 DdNode *N, *T, *E; 01223 DdNode *one, *bzero; 01224 char dir; 01225 int i; 01226 01227 if (string == NULL || node == NULL) return(0); 01228 01229 /* The constant 0 function has no on-set cubes. */ 01230 one = DD_ONE(ddm); 01231 bzero = Cudd_Not(one); 01232 if (node == bzero) return(0); 01233 01234 for (i = 0; i < ddm->size; i++) string[i] = 2; 01235 01236 for (;;) { 01237 01238 if (node == one) break; 01239 01240 N = Cudd_Regular(node); 01241 01242 T = cuddT(N); E = cuddE(N); 01243 if (Cudd_IsComplement(node)) { 01244 T = Cudd_Not(T); E = Cudd_Not(E); 01245 } 01246 if (T == bzero) { 01247 string[N->index] = 0; 01248 node = E; 01249 } else if (E == bzero) { 01250 string[N->index] = 1; 01251 node = T; 01252 } else { 01253 dir = (char) ((Cudd_Random() & 0x2000) >> 13); 01254 string[N->index] = dir; 01255 node = dir ? T : E; 01256 } 01257 } 01258 return(1); 01259 01260 } /* end of Cudd_bddPickOneCube */
Function********************************************************************
Synopsis [Picks one on-set minterm randomly from the given DD.]
Description [Picks one on-set minterm randomly from the given DD. The minterm is in terms of vars
. The array vars
should contain at least all variables in the support of f
; if this condition is not met the minterm built by this procedure may not be contained in f
. Builds a BDD for the minterm and returns a pointer to it if successful; NULL otherwise. There are three reasons why the procedure may fail:
f
may be the constant 0; f
. ]
SideEffects [None]
SeeAlso [Cudd_bddPickOneCube]
Definition at line 1287 of file cuddUtil.c.
01292 { 01293 char *string; 01294 int i, size; 01295 int *indices; 01296 int result; 01297 DdNode *old, *neW; 01298 01299 size = dd->size; 01300 string = ALLOC(char, size); 01301 if (string == NULL) { 01302 dd->errorCode = CUDD_MEMORY_OUT; 01303 return(NULL); 01304 } 01305 indices = ALLOC(int,n); 01306 if (indices == NULL) { 01307 dd->errorCode = CUDD_MEMORY_OUT; 01308 FREE(string); 01309 return(NULL); 01310 } 01311 01312 for (i = 0; i < n; i++) { 01313 indices[i] = vars[i]->index; 01314 } 01315 01316 result = Cudd_bddPickOneCube(dd,f,string); 01317 if (result == 0) { 01318 FREE(string); 01319 FREE(indices); 01320 return(NULL); 01321 } 01322 01323 /* Randomize choice for don't cares. */ 01324 for (i = 0; i < n; i++) { 01325 if (string[indices[i]] == 2) 01326 string[indices[i]] = (char) ((Cudd_Random() & 0x20) >> 5); 01327 } 01328 01329 /* Build result BDD. */ 01330 old = Cudd_ReadOne(dd); 01331 cuddRef(old); 01332 01333 for (i = n-1; i >= 0; i--) { 01334 neW = Cudd_bddAnd(dd,old,Cudd_NotCond(vars[i],string[indices[i]]==0)); 01335 if (neW == NULL) { 01336 FREE(string); 01337 FREE(indices); 01338 Cudd_RecursiveDeref(dd,old); 01339 return(NULL); 01340 } 01341 cuddRef(neW); 01342 Cudd_RecursiveDeref(dd,old); 01343 old = neW; 01344 } 01345 01346 #ifdef DD_DEBUG 01347 /* Test. */ 01348 if (Cudd_bddLeq(dd,old,f)) { 01349 cuddDeref(old); 01350 } else { 01351 Cudd_RecursiveDeref(dd,old); 01352 old = NULL; 01353 } 01354 #else 01355 cuddDeref(old); 01356 #endif 01357 01358 FREE(string); 01359 FREE(indices); 01360 return(old); 01361 01362 } /* end of Cudd_bddPickOneMinterm */
Function********************************************************************
Synopsis [Prints a sum of prime implicants of a BDD.]
Description [Prints a sum of product cover for an incompletely specified function given by a lower bound and an upper bound. Each product is a prime implicant obtained by expanding the product corresponding to a path from node to the constant one. Uses the package default output file. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_PrintMinterm]
Definition at line 249 of file cuddUtil.c.
00253 { 00254 int *array; 00255 int q, result; 00256 DdNode *lb; 00257 #ifdef DD_DEBUG 00258 DdNode *cover; 00259 #endif 00260 00261 array = ALLOC(int, Cudd_ReadSize(dd)); 00262 if (array == NULL) return(0); 00263 lb = l; 00264 cuddRef(lb); 00265 #ifdef DD_DEBUG 00266 cover = Cudd_ReadLogicZero(dd); 00267 cuddRef(cover); 00268 #endif 00269 while (lb != Cudd_ReadLogicZero(dd)) { 00270 DdNode *implicant, *prime, *tmp; 00271 int length; 00272 implicant = Cudd_LargestCube(dd,lb,&length); 00273 if (implicant == NULL) { 00274 Cudd_RecursiveDeref(dd,lb); 00275 FREE(array); 00276 return(0); 00277 } 00278 cuddRef(implicant); 00279 prime = Cudd_bddMakePrime(dd,implicant,u); 00280 if (prime == NULL) { 00281 Cudd_RecursiveDeref(dd,lb); 00282 Cudd_RecursiveDeref(dd,implicant); 00283 FREE(array); 00284 return(0); 00285 } 00286 cuddRef(prime); 00287 Cudd_RecursiveDeref(dd,implicant); 00288 tmp = Cudd_bddAnd(dd,lb,Cudd_Not(prime)); 00289 if (tmp == NULL) { 00290 Cudd_RecursiveDeref(dd,lb); 00291 Cudd_RecursiveDeref(dd,prime); 00292 FREE(array); 00293 return(0); 00294 } 00295 cuddRef(tmp); 00296 Cudd_RecursiveDeref(dd,lb); 00297 lb = tmp; 00298 result = Cudd_BddToCubeArray(dd,prime,array); 00299 if (result == 0) { 00300 Cudd_RecursiveDeref(dd,lb); 00301 Cudd_RecursiveDeref(dd,prime); 00302 FREE(array); 00303 return(0); 00304 } 00305 for (q = 0; q < dd->size; q++) { 00306 switch (array[q]) { 00307 case 0: 00308 (void) fprintf(dd->out, "0"); 00309 break; 00310 case 1: 00311 (void) fprintf(dd->out, "1"); 00312 break; 00313 case 2: 00314 (void) fprintf(dd->out, "-"); 00315 break; 00316 default: 00317 (void) fprintf(dd->out, "?"); 00318 } 00319 } 00320 (void) fprintf(dd->out, " 1\n"); 00321 #ifdef DD_DEBUG 00322 tmp = Cudd_bddOr(dd,prime,cover); 00323 if (tmp == NULL) { 00324 Cudd_RecursiveDeref(dd,cover); 00325 Cudd_RecursiveDeref(dd,lb); 00326 Cudd_RecursiveDeref(dd,prime); 00327 FREE(array); 00328 return(0); 00329 } 00330 cuddRef(tmp); 00331 Cudd_RecursiveDeref(dd,cover); 00332 cover = tmp; 00333 #endif 00334 Cudd_RecursiveDeref(dd,prime); 00335 } 00336 (void) fprintf(dd->out, "\n"); 00337 Cudd_RecursiveDeref(dd,lb); 00338 FREE(array); 00339 #ifdef DD_DEBUG 00340 if (!Cudd_bddLeq(dd,cover,u) || !Cudd_bddLeq(dd,l,cover)) { 00341 Cudd_RecursiveDeref(dd,cover); 00342 return(0); 00343 } 00344 Cudd_RecursiveDeref(dd,cover); 00345 #endif 00346 return(1); 00347 00348 } /* end of Cudd_bddPrintCover */
Function********************************************************************
Synopsis [Builds a positional array from the BDD of a cube.]
Description [Builds a positional array from the BDD of a cube. Array must have one entry for each BDD variable. The positional array has 1 in i-th position if the variable of index i appears in true form in the cube; it has 0 in i-th position if the variable of index i appears in complemented form in the cube; finally, it has 2 in i-th position if the variable of index i does not appear in the cube. Returns 1 if successful (the BDD is indeed a cube); 0 otherwise.]
SideEffects [The result is in the array passed by reference.]
SeeAlso [Cudd_CubeArrayToBdd]
Definition at line 2342 of file cuddUtil.c.
02346 { 02347 DdNode *scan, *t, *e; 02348 int i; 02349 int size = Cudd_ReadSize(dd); 02350 DdNode *zero = Cudd_Not(DD_ONE(dd)); 02351 02352 for (i = size-1; i >= 0; i--) { 02353 array[i] = 2; 02354 } 02355 scan = cube; 02356 while (!Cudd_IsConstant(scan)) { 02357 int index = Cudd_Regular(scan)->index; 02358 cuddGetBranches(scan,&t,&e); 02359 if (t == zero) { 02360 array[index] = 0; 02361 scan = e; 02362 } else if (e == zero) { 02363 array[index] = 1; 02364 scan = t; 02365 } else { 02366 return(0); /* cube is not a cube */ 02367 } 02368 } 02369 if (scan == zero) { 02370 return(0); 02371 } else { 02372 return(1); 02373 } 02374 02375 } /* end of Cudd_BddToCubeArray */
int Cudd_ClassifySupport | ( | DdManager * | dd, | |
DdNode * | f, | |||
DdNode * | g, | |||
DdNode ** | common, | |||
DdNode ** | onlyF, | |||
DdNode ** | onlyG | |||
) |
Function********************************************************************
Synopsis [Classifies the variables in the support of two DDs.]
Description [Classifies the variables in the support of two DDs f
and g
, depending on whther they appear in both DDs, only in f
, or only in g
. Returns 1 if successful; 0 otherwise.]
SideEffects [The cubes of the three classes of variables are returned as side effects.]
SeeAlso [Cudd_Support Cudd_VectorSupport]
Definition at line 1081 of file cuddUtil.c.
01088 { 01089 int *supportF, *supportG; 01090 DdNode *tmp, *var; 01091 int i,j; 01092 int size; 01093 01094 /* Allocate and initialize support arrays for ddSupportStep. */ 01095 size = ddMax(dd->size, dd->sizeZ); 01096 supportF = ALLOC(int,size); 01097 if (supportF == NULL) { 01098 dd->errorCode = CUDD_MEMORY_OUT; 01099 return(0); 01100 } 01101 supportG = ALLOC(int,size); 01102 if (supportG == NULL) { 01103 dd->errorCode = CUDD_MEMORY_OUT; 01104 FREE(supportF); 01105 return(0); 01106 } 01107 for (i = 0; i < size; i++) { 01108 supportF[i] = 0; 01109 supportG[i] = 0; 01110 } 01111 01112 /* Compute supports and clean up markers. */ 01113 ddSupportStep(Cudd_Regular(f),supportF); 01114 ddClearFlag(Cudd_Regular(f)); 01115 ddSupportStep(Cudd_Regular(g),supportG); 01116 ddClearFlag(Cudd_Regular(g)); 01117 01118 /* Classify variables and create cubes. */ 01119 *common = *onlyF = *onlyG = DD_ONE(dd); 01120 cuddRef(*common); cuddRef(*onlyF); cuddRef(*onlyG); 01121 for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ 01122 i = (j >= dd->size) ? j : dd->invperm[j]; 01123 if (supportF[i] == 0 && supportG[i] == 0) continue; 01124 var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); 01125 cuddRef(var); 01126 if (supportG[i] == 0) { 01127 tmp = Cudd_bddAnd(dd,*onlyF,var); 01128 if (tmp == NULL) { 01129 Cudd_RecursiveDeref(dd,*common); 01130 Cudd_RecursiveDeref(dd,*onlyF); 01131 Cudd_RecursiveDeref(dd,*onlyG); 01132 Cudd_RecursiveDeref(dd,var); 01133 FREE(supportF); FREE(supportG); 01134 return(0); 01135 } 01136 cuddRef(tmp); 01137 Cudd_RecursiveDeref(dd,*onlyF); 01138 *onlyF = tmp; 01139 } else if (supportF[i] == 0) { 01140 tmp = Cudd_bddAnd(dd,*onlyG,var); 01141 if (tmp == NULL) { 01142 Cudd_RecursiveDeref(dd,*common); 01143 Cudd_RecursiveDeref(dd,*onlyF); 01144 Cudd_RecursiveDeref(dd,*onlyG); 01145 Cudd_RecursiveDeref(dd,var); 01146 FREE(supportF); FREE(supportG); 01147 return(0); 01148 } 01149 cuddRef(tmp); 01150 Cudd_RecursiveDeref(dd,*onlyG); 01151 *onlyG = tmp; 01152 } else { 01153 tmp = Cudd_bddAnd(dd,*common,var); 01154 if (tmp == NULL) { 01155 Cudd_RecursiveDeref(dd,*common); 01156 Cudd_RecursiveDeref(dd,*onlyF); 01157 Cudd_RecursiveDeref(dd,*onlyG); 01158 Cudd_RecursiveDeref(dd,var); 01159 FREE(supportF); FREE(supportG); 01160 return(0); 01161 } 01162 cuddRef(tmp); 01163 Cudd_RecursiveDeref(dd,*common); 01164 *common = tmp; 01165 } 01166 Cudd_RecursiveDeref(dd,var); 01167 } 01168 01169 FREE(supportF); FREE(supportG); 01170 cuddDeref(*common); cuddDeref(*onlyF); cuddDeref(*onlyG); 01171 return(1); 01172 01173 } /* end of Cudd_ClassifySupport */
int Cudd_CountLeaves | ( | DdNode * | node | ) |
Function********************************************************************
Synopsis [Counts the number of leaves in a DD.]
Description [Counts the number of leaves in a DD. Returns the number of leaves in the DD rooted at node if successful; CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_PrintDebug]
Definition at line 1190 of file cuddUtil.c.
01192 { 01193 int i; 01194 01195 i = ddLeavesInt(Cudd_Regular(node)); 01196 ddClearFlag(Cudd_Regular(node)); 01197 return(i); 01198 01199 } /* end of Cudd_CountLeaves */
Function********************************************************************
Synopsis [Counts the number of minterms of a DD.]
Description [Counts the number of minterms of a DD. The function is assumed to depend on nvars variables. The minterm count is represented as a double, to allow for a larger number of variables. Returns the number of minterms of the function rooted at node if successful; (double) CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_PrintDebug Cudd_CountPath]
Definition at line 574 of file cuddUtil.c.
00578 { 00579 double max; 00580 DdHashTable *table; 00581 double res; 00582 CUDD_VALUE_TYPE epsilon; 00583 00584 background = manager->background; 00585 zero = Cudd_Not(manager->one); 00586 00587 max = pow(2.0,(double)nvars); 00588 table = cuddHashTableInit(manager,1,2); 00589 if (table == NULL) { 00590 return((double)CUDD_OUT_OF_MEM); 00591 } 00592 epsilon = Cudd_ReadEpsilon(manager); 00593 Cudd_SetEpsilon(manager,(CUDD_VALUE_TYPE)0.0); 00594 res = ddCountMintermAux(node,max,table); 00595 cuddHashTableQuit(table); 00596 Cudd_SetEpsilon(manager,epsilon); 00597 00598 return(res); 00599 00600 } /* end of Cudd_CountMinterm */
double Cudd_CountPath | ( | DdNode * | node | ) |
Function********************************************************************
Synopsis [Counts the number of paths of a DD.]
Description [Counts the number of paths of a DD. Paths to all terminal nodes are counted. The path count is represented as a double, to allow for a larger number of variables. Returns the number of paths of the function rooted at node if successful; (double) CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_CountMinterm]
Definition at line 619 of file cuddUtil.c.
00621 { 00622 00623 st_table *table; 00624 double i; 00625 00626 table = st_init_table(st_ptrcmp,st_ptrhash); 00627 if (table == NULL) { 00628 return((double)CUDD_OUT_OF_MEM); 00629 } 00630 i = ddCountPathAux(Cudd_Regular(node),table); 00631 st_foreach(table, cuddStCountfree, NULL); 00632 st_free_table(table); 00633 return(i); 00634 00635 } /* end of Cudd_CountPath */
double Cudd_CountPathsToNonZero | ( | DdNode * | node | ) |
Function********************************************************************
Synopsis [Counts the number of paths to a non-zero terminal of a DD.]
Description [Counts the number of paths to a non-zero terminal of a DD. The path count is represented as a double, to allow for a larger number of variables. Returns the number of paths of the function rooted at node.]
SideEffects [None]
SeeAlso [Cudd_CountMinterm Cudd_CountPath]
Definition at line 703 of file cuddUtil.c.
00705 { 00706 00707 st_table *table; 00708 double i; 00709 00710 table = st_init_table(st_ptrcmp,st_ptrhash); 00711 if (table == NULL) { 00712 return((double)CUDD_OUT_OF_MEM); 00713 } 00714 i = ddCountPathsToNonZero(node,table); 00715 st_foreach(table, cuddStCountfree, NULL); 00716 st_free_table(table); 00717 return(i); 00718 00719 } /* end of Cudd_CountPathsToNonZero */
Function********************************************************************
Synopsis [Builds the BDD of a cube from a positional array.]
Description [Builds a cube from a positional array. The array must have one integer entry for each BDD variable. If the i-th entry is 1, the variable of index i appears in true form in the cube; If the i-th entry is 0, the variable of index i appears complemented in the cube; otherwise the variable does not appear in the cube. Returns a pointer to the BDD for the cube if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddComputeCube Cudd_IndicesToCube Cudd_BddToCubeArray]
Definition at line 2294 of file cuddUtil.c.
02297 { 02298 DdNode *cube, *var, *tmp; 02299 int i; 02300 int size = Cudd_ReadSize(dd); 02301 02302 cube = DD_ONE(dd); 02303 cuddRef(cube); 02304 for (i = size - 1; i >= 0; i--) { 02305 if ((array[i] & ~1) == 0) { 02306 var = Cudd_bddIthVar(dd,i); 02307 tmp = Cudd_bddAnd(dd,cube,Cudd_NotCond(var,array[i]==0)); 02308 if (tmp == NULL) { 02309 Cudd_RecursiveDeref(dd,cube); 02310 return(NULL); 02311 } 02312 cuddRef(tmp); 02313 Cudd_RecursiveDeref(dd,cube); 02314 cube = tmp; 02315 } 02316 } 02317 cuddDeref(cube); 02318 return(cube); 02319 02320 } /* end of Cudd_CubeArrayToBdd */
int Cudd_DagSize | ( | DdNode * | node | ) |
Function********************************************************************
Synopsis [Counts the number of nodes in a DD.]
Description [Counts the number of nodes in a DD. Returns the number of nodes in the graph rooted at node.]
SideEffects [None]
SeeAlso [Cudd_SharingSize Cudd_PrintDebug]
Definition at line 438 of file cuddUtil.c.
00440 { 00441 int i; 00442 00443 i = ddDagInt(Cudd_Regular(node)); 00444 ddClearFlag(Cudd_Regular(node)); 00445 00446 return(i); 00447 00448 } /* end of Cudd_DagSize */
Function********************************************************************
Synopsis [Computes the density of a BDD or ADD.]
Description [Computes the density of a BDD or ADD. The density is the ratio of the number of minterms to the number of nodes. If 0 is passed as number of variables, the number of variables existing in the manager is used. Returns the density if successful; (double) CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_CountMinterm Cudd_DagSize]
Definition at line 2798 of file cuddUtil.c.
02802 { 02803 double minterms; 02804 int nodes; 02805 double density; 02806 02807 if (nvars == 0) nvars = dd->size; 02808 minterms = Cudd_CountMinterm(dd,f,nvars); 02809 if (minterms == (double) CUDD_OUT_OF_MEM) return(minterms); 02810 nodes = Cudd_DagSize(f); 02811 density = minterms / (double) nodes; 02812 return(density); 02813 02814 } /* end of Cudd_Density */
Function********************************************************************
Synopsis [Counts the number of minterms of a DD with extended precision.]
Description [Counts the number of minterms of a DD with extended precision. The function is assumed to depend on nvars variables. The minterm count is represented as an EpDouble, to allow any number of variables. Returns 0 if successful; CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_PrintDebug Cudd_CountPath]
Definition at line 653 of file cuddUtil.c.
00658 { 00659 EpDouble max, tmp; 00660 st_table *table; 00661 int status; 00662 00663 background = manager->background; 00664 zero = Cudd_Not(manager->one); 00665 00666 EpdPow2(nvars, &max); 00667 table = st_init_table(EpdCmp, st_ptrhash); 00668 if (table == NULL) { 00669 EpdMakeZero(epd, 0); 00670 return(CUDD_OUT_OF_MEM); 00671 } 00672 status = ddEpdCountMintermAux(Cudd_Regular(node),&max,epd,table); 00673 st_foreach(table, ddEpdFree, NULL); 00674 st_free_table(table); 00675 if (status == CUDD_OUT_OF_MEM) { 00676 EpdMakeZero(epd, 0); 00677 return(CUDD_OUT_OF_MEM); 00678 } 00679 if (Cudd_IsComplement(node)) { 00680 EpdSubtract3(&max, epd, &tmp); 00681 EpdCopy(&tmp, epd); 00682 } 00683 return(0); 00684 00685 } /* end of Cudd_EpdCountMinterm */
Function********************************************************************
Synopsis [Estimates the number of nodes in a cofactor of a DD.]
Description [Estimates the number of nodes in a cofactor of a DD. Returns an estimate of the number of nodes in a cofactor of the graph rooted at node with respect to the variable whose index is i. In case of failure, returns CUDD_OUT_OF_MEM. This function uses a refinement of the algorithm of Cabodi et al. (ICCAD96). The refinement allows the procedure to account for part of the recombination that may occur in the part of the cofactor above the cofactoring variable. This procedure does no create any new node. It does keep a small table of results; therefore it may run out of memory. If this is a concern, one should use Cudd_EstimateCofactorSimple, which is faster, does not allocate any memory, but is less accurate.]
SideEffects [None]
SeeAlso [Cudd_DagSize Cudd_EstimateCofactorSimple]
Definition at line 473 of file cuddUtil.c.
00477 : positive; 0: negative */ 00478 ) 00479 { 00480 int val; 00481 DdNode *ptr; 00482 st_table *table; 00483 00484 table = st_init_table(st_ptrcmp,st_ptrhash); 00485 if (table == NULL) return(CUDD_OUT_OF_MEM); 00486 val = cuddEstimateCofactor(dd,table,Cudd_Regular(f),i,phase,&ptr); 00487 ddClearFlag(Cudd_Regular(f)); 00488 st_free_table(table); 00489 00490 return(val); 00491 00492 } /* end of Cudd_EstimateCofactor */
int Cudd_EstimateCofactorSimple | ( | DdNode * | node, | |
int | i | |||
) |
Function********************************************************************
Synopsis [Estimates the number of nodes in a cofactor of a DD.]
Description [Estimates the number of nodes in a cofactor of a DD. Returns an estimate of the number of nodes in the positive cofactor of the graph rooted at node with respect to the variable whose index is i. This procedure implements with minor changes the algorithm of Cabodi et al. (ICCAD96). It does not allocate any memory, it does not change the state of the manager, and it is fast. However, it has been observed to overestimate the size of the cofactor by as much as a factor of 2.]
SideEffects [None]
SeeAlso [Cudd_DagSize]
Definition at line 513 of file cuddUtil.c.
00516 { 00517 int val; 00518 00519 val = cuddEstimateCofactorSimple(Cudd_Regular(node),i); 00520 ddClearFlag(Cudd_Regular(node)); 00521 00522 return(val); 00523 00524 } /* end of Cudd_EstimateCofactorSimple */
Function********************************************************************
Synopsis [Finds the first cube of a decision diagram.]
Description [Defines an iterator on the onset of a decision diagram and finds its first cube. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise.
A cube is represented as an array of literals, which are integers in {0, 1, 2}; 0 represents a complemented literal, 1 represents an uncomplemented literal, and 2 stands for don't care. The enumeration produces a disjoint cover of the function associated with the diagram. The size of the array equals the number of variables in the manager at the time Cudd_FirstCube is called.
For each cube, a value is also returned. This value is always 1 for a BDD, while it may be different from 1 for an ADD. For BDDs, the offset is the set of cubes whose value is the logical zero. For ADDs, the offset is the set of cubes whose value is the background value. The cubes of the offset are not enumerated.]
SideEffects [The first cube and its value are returned as side effects.]
SeeAlso [Cudd_ForeachCube Cudd_NextCube Cudd_GenFree Cudd_IsGenEmpty Cudd_FirstNode]
Definition at line 1794 of file cuddUtil.c.
01799 { 01800 DdGen *gen; 01801 DdNode *top, *treg, *next, *nreg, *prev, *preg; 01802 int i; 01803 int nvars; 01804 01805 /* Sanity Check. */ 01806 if (dd == NULL || f == NULL) return(NULL); 01807 01808 /* Allocate generator an initialize it. */ 01809 gen = ALLOC(DdGen,1); 01810 if (gen == NULL) { 01811 dd->errorCode = CUDD_MEMORY_OUT; 01812 return(NULL); 01813 } 01814 01815 gen->manager = dd; 01816 gen->type = CUDD_GEN_CUBES; 01817 gen->status = CUDD_GEN_EMPTY; 01818 gen->gen.cubes.cube = NULL; 01819 gen->gen.cubes.value = DD_ZERO_VAL; 01820 gen->stack.sp = 0; 01821 gen->stack.stack = NULL; 01822 gen->node = NULL; 01823 01824 nvars = dd->size; 01825 gen->gen.cubes.cube = ALLOC(int,nvars); 01826 if (gen->gen.cubes.cube == NULL) { 01827 dd->errorCode = CUDD_MEMORY_OUT; 01828 FREE(gen); 01829 return(NULL); 01830 } 01831 for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; 01832 01833 /* The maximum stack depth is one plus the number of variables. 01834 ** because a path may have nodes at all levels, including the 01835 ** constant level. 01836 */ 01837 gen->stack.stack = ALLOC(DdNodePtr, nvars+1); 01838 if (gen->stack.stack == NULL) { 01839 dd->errorCode = CUDD_MEMORY_OUT; 01840 FREE(gen->gen.cubes.cube); 01841 FREE(gen); 01842 return(NULL); 01843 } 01844 for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; 01845 01846 /* Find the first cube of the onset. */ 01847 gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; 01848 01849 while (1) { 01850 top = gen->stack.stack[gen->stack.sp-1]; 01851 treg = Cudd_Regular(top); 01852 if (!cuddIsConstant(treg)) { 01853 /* Take the else branch first. */ 01854 gen->gen.cubes.cube[treg->index] = 0; 01855 next = cuddE(treg); 01856 if (top != treg) next = Cudd_Not(next); 01857 gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; 01858 } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { 01859 /* Backtrack */ 01860 while (1) { 01861 if (gen->stack.sp == 1) { 01862 /* The current node has no predecessor. */ 01863 gen->status = CUDD_GEN_EMPTY; 01864 gen->stack.sp--; 01865 goto done; 01866 } 01867 prev = gen->stack.stack[gen->stack.sp-2]; 01868 preg = Cudd_Regular(prev); 01869 nreg = cuddT(preg); 01870 if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} 01871 if (next != top) { /* follow the then branch next */ 01872 gen->gen.cubes.cube[preg->index] = 1; 01873 gen->stack.stack[gen->stack.sp-1] = next; 01874 break; 01875 } 01876 /* Pop the stack and try again. */ 01877 gen->gen.cubes.cube[preg->index] = 2; 01878 gen->stack.sp--; 01879 top = gen->stack.stack[gen->stack.sp-1]; 01880 treg = Cudd_Regular(top); 01881 } 01882 } else { 01883 gen->status = CUDD_GEN_NONEMPTY; 01884 gen->gen.cubes.value = cuddV(top); 01885 goto done; 01886 } 01887 } 01888 01889 done: 01890 *cube = gen->gen.cubes.cube; 01891 *value = gen->gen.cubes.value; 01892 return(gen); 01893 01894 } /* end of Cudd_FirstCube */
Function********************************************************************
Synopsis [Finds the first node of a decision diagram.]
Description [Defines an iterator on the nodes of a decision diagram and finds its first node. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise. The nodes are enumerated in a reverse topological order, so that a node is always preceded in the enumeration by its descendants.]
SideEffects [The first node is returned as a side effect.]
SeeAlso [Cudd_ForeachNode Cudd_NextNode Cudd_GenFree Cudd_IsGenEmpty Cudd_FirstCube]
Definition at line 2396 of file cuddUtil.c.
02400 { 02401 DdGen *gen; 02402 int size; 02403 02404 /* Sanity Check. */ 02405 if (dd == NULL || f == NULL) return(NULL); 02406 02407 /* Allocate generator an initialize it. */ 02408 gen = ALLOC(DdGen,1); 02409 if (gen == NULL) { 02410 dd->errorCode = CUDD_MEMORY_OUT; 02411 return(NULL); 02412 } 02413 02414 gen->manager = dd; 02415 gen->type = CUDD_GEN_NODES; 02416 gen->status = CUDD_GEN_EMPTY; 02417 gen->stack.sp = 0; 02418 gen->node = NULL; 02419 02420 /* Collect all the nodes on the generator stack for later perusal. */ 02421 gen->stack.stack = cuddNodeArray(Cudd_Regular(f), &size); 02422 if (gen->stack.stack == NULL) { 02423 FREE(gen); 02424 dd->errorCode = CUDD_MEMORY_OUT; 02425 return(NULL); 02426 } 02427 gen->gen.nodes.size = size; 02428 02429 /* Find the first node. */ 02430 if (gen->stack.sp < gen->gen.nodes.size) { 02431 gen->status = CUDD_GEN_NONEMPTY; 02432 gen->node = gen->stack.stack[gen->stack.sp]; 02433 *node = gen->node; 02434 } 02435 02436 return(gen); 02437 02438 } /* end of Cudd_FirstNode */
Function********************************************************************
Synopsis [Finds the first prime of a Boolean function.]
Description [Defines an iterator on a pair of BDDs describing a (possibly incompletely specified) Boolean functions and finds the first cube of a cover of the function. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise.
The two argument BDDs are the lower and upper bounds of an interval. It is a mistake to call this function with a lower bound that is not less than or equal to the upper bound.
A cube is represented as an array of literals, which are integers in {0, 1, 2}; 0 represents a complemented literal, 1 represents an uncomplemented literal, and 2 stands for don't care. The enumeration produces a prime and irredundant cover of the function associated with the two BDDs. The size of the array equals the number of variables in the manager at the time Cudd_FirstCube is called.
This iterator can only be used on BDDs.]
SideEffects [The first cube is returned as side effect.]
SeeAlso [Cudd_ForeachPrime Cudd_NextPrime Cudd_GenFree Cudd_IsGenEmpty Cudd_FirstCube Cudd_FirstNode]
Definition at line 2024 of file cuddUtil.c.
02029 { 02030 DdGen *gen; 02031 DdNode *implicant, *prime, *tmp; 02032 int length, result; 02033 02034 /* Sanity Check. */ 02035 if (dd == NULL || l == NULL || u == NULL) return(NULL); 02036 02037 /* Allocate generator an initialize it. */ 02038 gen = ALLOC(DdGen,1); 02039 if (gen == NULL) { 02040 dd->errorCode = CUDD_MEMORY_OUT; 02041 return(NULL); 02042 } 02043 02044 gen->manager = dd; 02045 gen->type = CUDD_GEN_PRIMES; 02046 gen->status = CUDD_GEN_EMPTY; 02047 gen->gen.primes.cube = NULL; 02048 gen->gen.primes.ub = u; 02049 gen->stack.sp = 0; 02050 gen->stack.stack = NULL; 02051 gen->node = l; 02052 cuddRef(l); 02053 02054 gen->gen.primes.cube = ALLOC(int,dd->size); 02055 if (gen->gen.primes.cube == NULL) { 02056 dd->errorCode = CUDD_MEMORY_OUT; 02057 FREE(gen); 02058 return(NULL); 02059 } 02060 02061 if (gen->node == Cudd_ReadLogicZero(dd)) { 02062 gen->status = CUDD_GEN_EMPTY; 02063 } else { 02064 implicant = Cudd_LargestCube(dd,gen->node,&length); 02065 if (implicant == NULL) { 02066 Cudd_RecursiveDeref(dd,gen->node); 02067 FREE(gen->gen.primes.cube); 02068 FREE(gen); 02069 return(NULL); 02070 } 02071 cuddRef(implicant); 02072 prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); 02073 if (prime == NULL) { 02074 Cudd_RecursiveDeref(dd,gen->node); 02075 Cudd_RecursiveDeref(dd,implicant); 02076 FREE(gen->gen.primes.cube); 02077 FREE(gen); 02078 return(NULL); 02079 } 02080 cuddRef(prime); 02081 Cudd_RecursiveDeref(dd,implicant); 02082 tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); 02083 if (tmp == NULL) { 02084 Cudd_RecursiveDeref(dd,gen->node); 02085 Cudd_RecursiveDeref(dd,prime); 02086 FREE(gen->gen.primes.cube); 02087 FREE(gen); 02088 return(NULL); 02089 } 02090 cuddRef(tmp); 02091 Cudd_RecursiveDeref(dd,gen->node); 02092 gen->node = tmp; 02093 result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); 02094 if (result == 0) { 02095 Cudd_RecursiveDeref(dd,gen->node); 02096 Cudd_RecursiveDeref(dd,prime); 02097 FREE(gen->gen.primes.cube); 02098 FREE(gen); 02099 return(NULL); 02100 } 02101 Cudd_RecursiveDeref(dd,prime); 02102 gen->status = CUDD_GEN_NONEMPTY; 02103 } 02104 *cube = gen->gen.primes.cube; 02105 return(gen); 02106 02107 } /* end of Cudd_FirstPrime */
int Cudd_GenFree | ( | DdGen * | gen | ) |
Function********************************************************************
Synopsis [Frees a CUDD generator.]
Description [Frees a CUDD generator. Always returns 0, so that it can be used in mis-like foreach constructs.]
SideEffects [None]
SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_FirstNode Cudd_NextNode Cudd_IsGenEmpty]
Definition at line 2487 of file cuddUtil.c.
02489 { 02490 if (gen == NULL) return(0); 02491 switch (gen->type) { 02492 case CUDD_GEN_CUBES: 02493 case CUDD_GEN_ZDD_PATHS: 02494 FREE(gen->gen.cubes.cube); 02495 FREE(gen->stack.stack); 02496 break; 02497 case CUDD_GEN_PRIMES: 02498 FREE(gen->gen.primes.cube); 02499 Cudd_RecursiveDeref(gen->manager,gen->node); 02500 break; 02501 case CUDD_GEN_NODES: 02502 FREE(gen->stack.stack); 02503 break; 02504 default: 02505 return(0); 02506 } 02507 FREE(gen); 02508 return(0); 02509 02510 } /* end of Cudd_GenFree */
Function********************************************************************
Synopsis [Builds a cube of BDD variables from an array of indices.]
Description [Builds a cube of BDD variables from an array of indices. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddComputeCube Cudd_CubeArrayToBdd]
Definition at line 2549 of file cuddUtil.c.
02553 { 02554 DdNode *cube, *tmp; 02555 int i; 02556 02557 cube = DD_ONE(dd); 02558 cuddRef(cube); 02559 for (i = n - 1; i >= 0; i--) { 02560 tmp = Cudd_bddAnd(dd,Cudd_bddIthVar(dd,array[i]),cube); 02561 if (tmp == NULL) { 02562 Cudd_RecursiveDeref(dd,cube); 02563 return(NULL); 02564 } 02565 cuddRef(tmp); 02566 Cudd_RecursiveDeref(dd,cube); 02567 cube = tmp; 02568 } 02569 02570 cuddDeref(cube); 02571 return(cube); 02572 02573 } /* end of Cudd_IndicesToCube */
int Cudd_IsGenEmpty | ( | DdGen * | gen | ) |
Function********************************************************************
Synopsis [Queries the status of a generator.]
Description [Queries the status of a generator. Returns 1 if the generator is empty or NULL; 0 otherswise.]
SideEffects [None]
SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_FirstNode Cudd_NextNode Cudd_GenFree]
Definition at line 2527 of file cuddUtil.c.
02529 { 02530 if (gen == NULL) return(1); 02531 return(gen->status == CUDD_GEN_EMPTY); 02532 02533 } /* end of Cudd_IsGenEmpty */
int Cudd_NextCube | ( | DdGen * | gen, | |
int ** | cube, | |||
CUDD_VALUE_TYPE * | value | |||
) |
Function********************************************************************
Synopsis [Generates the next cube of a decision diagram onset.]
Description [Generates the next cube of a decision diagram onset, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]
SideEffects [The cube and its value are returned as side effects. The generator is modified.]
SeeAlso [Cudd_ForeachCube Cudd_FirstCube Cudd_GenFree Cudd_IsGenEmpty Cudd_NextNode]
Definition at line 1913 of file cuddUtil.c.
01917 { 01918 DdNode *top, *treg, *next, *nreg, *prev, *preg; 01919 DdManager *dd = gen->manager; 01920 01921 /* Backtrack from previously reached terminal node. */ 01922 while (1) { 01923 if (gen->stack.sp == 1) { 01924 /* The current node has no predecessor. */ 01925 gen->status = CUDD_GEN_EMPTY; 01926 gen->stack.sp--; 01927 goto done; 01928 } 01929 top = gen->stack.stack[gen->stack.sp-1]; 01930 treg = Cudd_Regular(top); 01931 prev = gen->stack.stack[gen->stack.sp-2]; 01932 preg = Cudd_Regular(prev); 01933 nreg = cuddT(preg); 01934 if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} 01935 if (next != top) { /* follow the then branch next */ 01936 gen->gen.cubes.cube[preg->index] = 1; 01937 gen->stack.stack[gen->stack.sp-1] = next; 01938 break; 01939 } 01940 /* Pop the stack and try again. */ 01941 gen->gen.cubes.cube[preg->index] = 2; 01942 gen->stack.sp--; 01943 } 01944 01945 while (1) { 01946 top = gen->stack.stack[gen->stack.sp-1]; 01947 treg = Cudd_Regular(top); 01948 if (!cuddIsConstant(treg)) { 01949 /* Take the else branch first. */ 01950 gen->gen.cubes.cube[treg->index] = 0; 01951 next = cuddE(treg); 01952 if (top != treg) next = Cudd_Not(next); 01953 gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; 01954 } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { 01955 /* Backtrack */ 01956 while (1) { 01957 if (gen->stack.sp == 1) { 01958 /* The current node has no predecessor. */ 01959 gen->status = CUDD_GEN_EMPTY; 01960 gen->stack.sp--; 01961 goto done; 01962 } 01963 prev = gen->stack.stack[gen->stack.sp-2]; 01964 preg = Cudd_Regular(prev); 01965 nreg = cuddT(preg); 01966 if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} 01967 if (next != top) { /* follow the then branch next */ 01968 gen->gen.cubes.cube[preg->index] = 1; 01969 gen->stack.stack[gen->stack.sp-1] = next; 01970 break; 01971 } 01972 /* Pop the stack and try again. */ 01973 gen->gen.cubes.cube[preg->index] = 2; 01974 gen->stack.sp--; 01975 top = gen->stack.stack[gen->stack.sp-1]; 01976 treg = Cudd_Regular(top); 01977 } 01978 } else { 01979 gen->status = CUDD_GEN_NONEMPTY; 01980 gen->gen.cubes.value = cuddV(top); 01981 goto done; 01982 } 01983 } 01984 01985 done: 01986 if (gen->status == CUDD_GEN_EMPTY) return(0); 01987 *cube = gen->gen.cubes.cube; 01988 *value = gen->gen.cubes.value; 01989 return(1); 01990 01991 } /* end of Cudd_NextCube */
Function********************************************************************
Synopsis [Finds the next node of a decision diagram.]
Description [Finds the node of a decision diagram, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]
SideEffects [The next node is returned as a side effect.]
SeeAlso [Cudd_ForeachNode Cudd_FirstNode Cudd_GenFree Cudd_IsGenEmpty Cudd_NextCube]
Definition at line 2455 of file cuddUtil.c.
02458 { 02459 /* Find the next node. */ 02460 gen->stack.sp++; 02461 if (gen->stack.sp < gen->gen.nodes.size) { 02462 gen->node = gen->stack.stack[gen->stack.sp]; 02463 *node = gen->node; 02464 return(1); 02465 } else { 02466 gen->status = CUDD_GEN_EMPTY; 02467 return(0); 02468 } 02469 02470 } /* end of Cudd_NextNode */
int Cudd_NextPrime | ( | DdGen * | gen, | |
int ** | cube | |||
) |
Function********************************************************************
Synopsis [Generates the next prime of a Boolean function.]
Description [Generates the next cube of a Boolean function, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]
SideEffects [The cube and is returned as side effects. The generator is modified.]
SeeAlso [Cudd_ForeachPrime Cudd_FirstPrime Cudd_GenFree Cudd_IsGenEmpty Cudd_NextCube Cudd_NextNode]
Definition at line 2126 of file cuddUtil.c.
02129 { 02130 DdNode *implicant, *prime, *tmp; 02131 DdManager *dd = gen->manager; 02132 int length, result; 02133 02134 if (gen->node == Cudd_ReadLogicZero(dd)) { 02135 gen->status = CUDD_GEN_EMPTY; 02136 } else { 02137 implicant = Cudd_LargestCube(dd,gen->node,&length); 02138 if (implicant == NULL) { 02139 gen->status = CUDD_GEN_EMPTY; 02140 return(0); 02141 } 02142 cuddRef(implicant); 02143 prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); 02144 if (prime == NULL) { 02145 Cudd_RecursiveDeref(dd,implicant); 02146 gen->status = CUDD_GEN_EMPTY; 02147 return(0); 02148 } 02149 cuddRef(prime); 02150 Cudd_RecursiveDeref(dd,implicant); 02151 tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); 02152 if (tmp == NULL) { 02153 Cudd_RecursiveDeref(dd,prime); 02154 gen->status = CUDD_GEN_EMPTY; 02155 return(0); 02156 } 02157 cuddRef(tmp); 02158 Cudd_RecursiveDeref(dd,gen->node); 02159 gen->node = tmp; 02160 result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); 02161 if (result == 0) { 02162 Cudd_RecursiveDeref(dd,prime); 02163 gen->status = CUDD_GEN_EMPTY; 02164 return(0); 02165 } 02166 Cudd_RecursiveDeref(dd,prime); 02167 gen->status = CUDD_GEN_NONEMPTY; 02168 } 02169 if (gen->status == CUDD_GEN_EMPTY) return(0); 02170 *cube = gen->gen.primes.cube; 02171 return(1); 02172 02173 } /* end of Cudd_NextPrime */
void Cudd_OutOfMem | ( | long | size | ) |
Function********************************************************************
Synopsis [Warns that a memory allocation failed.]
Description [Warns that a memory allocation failed. This function can be used as replacement of MMout_of_memory to prevent the safe_mem functions of the util package from exiting when malloc returns NULL. One possible use is in case of discretionary allocations; for instance, the allocation of memory to enlarge the computed table.]
SideEffects [None]
SeeAlso []
Definition at line 2833 of file cuddUtil.c.
02835 { 02836 (void) fflush(stdout); 02837 (void) fprintf(stderr, "\nunable to allocate %ld bytes\n", size); 02838 return; 02839 02840 } /* end of Cudd_OutOfMem */
Function********************************************************************
Synopsis [Prints to the standard output a DD and its statistics.]
Description [Prints to the standard output a DD and its statistics. The statistics include the number of nodes, the number of leaves, and the number of minterms. (The number of minterms is the number of assignments to the variables that cause the function to be different from the logical zero (for BDDs) and from the background value (for ADDs.) The statistics are printed if pr > 0. Specifically:
For the purpose of counting the number of minterms, the function is supposed to depend on n variables. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_DagSize Cudd_CountLeaves Cudd_CountMinterm Cudd_PrintMinterm]
Definition at line 378 of file cuddUtil.c.
00383 { 00384 DdNode *azero, *bzero; 00385 int nodes; 00386 int leaves; 00387 double minterms; 00388 int retval = 1; 00389 00390 if (f == NULL) { 00391 (void) fprintf(dd->out,": is the NULL DD\n"); 00392 (void) fflush(dd->out); 00393 return(0); 00394 } 00395 azero = DD_ZERO(dd); 00396 bzero = Cudd_Not(DD_ONE(dd)); 00397 if ((f == azero || f == bzero) && pr > 0){ 00398 (void) fprintf(dd->out,": is the zero DD\n"); 00399 (void) fflush(dd->out); 00400 return(1); 00401 } 00402 if (pr > 0) { 00403 nodes = Cudd_DagSize(f); 00404 if (nodes == CUDD_OUT_OF_MEM) retval = 0; 00405 leaves = Cudd_CountLeaves(f); 00406 if (leaves == CUDD_OUT_OF_MEM) retval = 0; 00407 minterms = Cudd_CountMinterm(dd, f, n); 00408 if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; 00409 (void) fprintf(dd->out,": %d nodes %d leaves %g minterms\n", 00410 nodes, leaves, minterms); 00411 if (pr > 2) { 00412 if (!cuddP(dd, f)) retval = 0; 00413 } 00414 if (pr == 2 || pr > 3) { 00415 if (!Cudd_PrintMinterm(dd,f)) retval = 0; 00416 (void) fprintf(dd->out,"\n"); 00417 } 00418 (void) fflush(dd->out); 00419 } 00420 return(retval); 00421 00422 } /* end of Cudd_PrintDebug */
AutomaticEnd Function********************************************************************
Synopsis [Prints a disjoint sum of products.]
Description [Prints a disjoint sum of product cover for the function rooted at node. Each product corresponds to a path from node to a leaf node different from the logical zero, and different from the background value. Uses the package default output file. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_PrintDebug Cudd_bddPrintCover]
Definition at line 212 of file cuddUtil.c.
00215 { 00216 int i, *list; 00217 00218 background = manager->background; 00219 zero = Cudd_Not(manager->one); 00220 list = ALLOC(int,manager->size); 00221 if (list == NULL) { 00222 manager->errorCode = CUDD_MEMORY_OUT; 00223 return(0); 00224 } 00225 for (i = 0; i < manager->size; i++) list[i] = 2; 00226 ddPrintMintermAux(manager,node,list); 00227 FREE(list); 00228 return(1); 00229 00230 } /* end of Cudd_PrintMinterm */
void Cudd_PrintVersion | ( | FILE * | fp | ) |
Function********************************************************************
Synopsis [Prints the package version number.]
Description []
SideEffects [None]
SeeAlso []
Definition at line 2588 of file cuddUtil.c.
02590 { 02591 (void) fprintf(fp, "%s\n", CUDD_VERSION); 02592 02593 } /* end of Cudd_PrintVersion */
long Cudd_Random | ( | void | ) |
Function********************************************************************
Synopsis [Portable random number generator.]
Description [Portable number generator based on ran2 from "Numerical Recipes in C." It is a long period (> 2 * 10^18) random number generator of L'Ecuyer with Bays-Durham shuffle. Returns a long integer uniformly distributed between 0 and 2147483561 (inclusive of the endpoint values). The random generator can be explicitly initialized by calling Cudd_Srandom. If no explicit initialization is performed, then the seed 1 is assumed.]
SideEffects [None]
SeeAlso [Cudd_Srandom]
Definition at line 2698 of file cuddUtil.c.
02699 { 02700 int i; /* index in the shuffle table */ 02701 long int w; /* work variable */ 02702 02703 /* cuddRand == 0 if the geneartor has not been initialized yet. */ 02704 if (cuddRand == 0) Cudd_Srandom(1); 02705 02706 /* Compute cuddRand = (cuddRand * LEQA1) % MODULUS1 avoiding 02707 ** overflows by Schrage's method. 02708 */ 02709 w = cuddRand / LEQQ1; 02710 cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; 02711 cuddRand += (cuddRand < 0) * MODULUS1; 02712 02713 /* Compute cuddRand2 = (cuddRand2 * LEQA2) % MODULUS2 avoiding 02714 ** overflows by Schrage's method. 02715 */ 02716 w = cuddRand2 / LEQQ2; 02717 cuddRand2 = LEQA2 * (cuddRand2 - w * LEQQ2) - w * LEQR2; 02718 cuddRand2 += (cuddRand2 < 0) * MODULUS2; 02719 02720 /* cuddRand is shuffled with the Bays-Durham algorithm. 02721 ** shuffleSelect and cuddRand2 are combined to generate the output. 02722 */ 02723 02724 /* Pick one element from the shuffle table; "i" will be in the range 02725 ** from 0 to STAB_SIZE-1. 02726 */ 02727 i = (int) (shuffleSelect / STAB_DIV); 02728 /* Mix the element of the shuffle table with the current iterate of 02729 ** the second sub-generator, and replace the chosen element of the 02730 ** shuffle table with the current iterate of the first sub-generator. 02731 */ 02732 shuffleSelect = shuffleTable[i] - cuddRand2; 02733 shuffleTable[i] = cuddRand; 02734 shuffleSelect += (shuffleSelect < 1) * (MODULUS1 - 1); 02735 /* Since shuffleSelect != 0, and we want to be able to return 0, 02736 ** here we subtract 1 before returning. 02737 */ 02738 return(shuffleSelect - 1); 02739 02740 } /* end of Cudd_Random */
int Cudd_SharingSize | ( | DdNode ** | nodeArray, | |
int | n | |||
) |
Function********************************************************************
Synopsis [Counts the number of nodes in an array of DDs.]
Description [Counts the number of nodes in an array of DDs. Shared nodes are counted only once. Returns the total number of nodes.]
SideEffects [None]
SeeAlso [Cudd_DagSize]
Definition at line 540 of file cuddUtil.c.
00543 { 00544 int i,j; 00545 00546 i = 0; 00547 for (j = 0; j < n; j++) { 00548 i += ddDagInt(Cudd_Regular(nodeArray[j])); 00549 } 00550 for (j = 0; j < n; j++) { 00551 ddClearFlag(Cudd_Regular(nodeArray[j])); 00552 } 00553 return(i); 00554 00555 } /* end of Cudd_SharingSize */
void Cudd_Srandom | ( | long | seed | ) |
Function********************************************************************
Synopsis [Initializer for the portable random number generator.]
Description [Initializer for the portable number generator based on ran2 in "Numerical Recipes in C." The input is the seed for the generator. If it is negative, its absolute value is taken as seed. If it is 0, then 1 is taken as seed. The initialized sets up the two recurrences used to generate a long-period stream, and sets up the shuffle table.]
SideEffects [None]
SeeAlso [Cudd_Random]
Definition at line 2760 of file cuddUtil.c.
02762 { 02763 int i; 02764 02765 if (seed < 0) cuddRand = -seed; 02766 else if (seed == 0) cuddRand = 1; 02767 else cuddRand = seed; 02768 cuddRand2 = cuddRand; 02769 /* Load the shuffle table (after 11 warm-ups). */ 02770 for (i = 0; i < STAB_SIZE + 11; i++) { 02771 long int w; 02772 w = cuddRand / LEQQ1; 02773 cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; 02774 cuddRand += (cuddRand < 0) * MODULUS1; 02775 shuffleTable[i % STAB_SIZE] = cuddRand; 02776 } 02777 shuffleSelect = shuffleTable[1 % STAB_SIZE]; 02778 02779 } /* end of Cudd_Srandom */
DdNode* Cudd_SubsetWithMaskVars | ( | DdManager * | dd, | |
DdNode * | f, | |||
DdNode ** | vars, | |||
int | nvars, | |||
DdNode ** | maskVars, | |||
int | mvars | |||
) |
Function********************************************************************
Synopsis [Extracts a subset from a BDD.]
Description [Extracts a subset from a BDD in the following procedure. 1. Compute the weight for each mask variable by counting the number of minterms for both positive and negative cofactors of the BDD with respect to each mask variable. (weight = positive - negative) 2. Find a representative cube of the BDD by using the weight. From the top variable of the BDD, for each variable, if the weight is greater than 0.0, choose THEN branch, othereise ELSE branch, until meeting the constant 1. 3. Quantify out the variables not in maskVars from the representative cube and if a variable in maskVars is don't care, replace the variable with a constant(1 or 0) depending on the weight. 4. Make a subset of the BDD by multiplying with the modified cube.]
SideEffects [None]
SeeAlso []
Definition at line 1598 of file cuddUtil.c.
01605 { 01606 double *weight; 01607 char *string; 01608 int i, size; 01609 int *indices, *mask; 01610 int result; 01611 DdNode *zero, *cube, *newCube, *subset; 01612 DdNode *cof; 01613 01614 DdNode *support; 01615 support = Cudd_Support(dd,f); 01616 cuddRef(support); 01617 Cudd_RecursiveDeref(dd,support); 01618 01619 zero = Cudd_Not(dd->one); 01620 size = dd->size; 01621 01622 weight = ALLOC(double,size); 01623 if (weight == NULL) { 01624 dd->errorCode = CUDD_MEMORY_OUT; 01625 return(NULL); 01626 } 01627 for (i = 0; i < size; i++) { 01628 weight[i] = 0.0; 01629 } 01630 for (i = 0; i < mvars; i++) { 01631 cof = Cudd_Cofactor(dd, f, maskVars[i]); 01632 cuddRef(cof); 01633 weight[i] = Cudd_CountMinterm(dd, cof, nvars); 01634 Cudd_RecursiveDeref(dd,cof); 01635 01636 cof = Cudd_Cofactor(dd, f, Cudd_Not(maskVars[i])); 01637 cuddRef(cof); 01638 weight[i] -= Cudd_CountMinterm(dd, cof, nvars); 01639 Cudd_RecursiveDeref(dd,cof); 01640 } 01641 01642 string = ALLOC(char, size + 1); 01643 if (string == NULL) { 01644 dd->errorCode = CUDD_MEMORY_OUT; 01645 FREE(weight); 01646 return(NULL); 01647 } 01648 mask = ALLOC(int, size); 01649 if (mask == NULL) { 01650 dd->errorCode = CUDD_MEMORY_OUT; 01651 FREE(weight); 01652 FREE(string); 01653 return(NULL); 01654 } 01655 for (i = 0; i < size; i++) { 01656 string[i] = '2'; 01657 mask[i] = 0; 01658 } 01659 string[size] = '\0'; 01660 indices = ALLOC(int,nvars); 01661 if (indices == NULL) { 01662 dd->errorCode = CUDD_MEMORY_OUT; 01663 FREE(weight); 01664 FREE(string); 01665 FREE(mask); 01666 return(NULL); 01667 } 01668 for (i = 0; i < nvars; i++) { 01669 indices[i] = vars[i]->index; 01670 } 01671 01672 result = ddPickRepresentativeCube(dd,f,weight,string); 01673 if (result == 0) { 01674 FREE(weight); 01675 FREE(string); 01676 FREE(mask); 01677 FREE(indices); 01678 return(NULL); 01679 } 01680 01681 cube = Cudd_ReadOne(dd); 01682 cuddRef(cube); 01683 zero = Cudd_Not(Cudd_ReadOne(dd)); 01684 for (i = 0; i < nvars; i++) { 01685 if (string[indices[i]] == '0') { 01686 newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); 01687 } else if (string[indices[i]] == '1') { 01688 newCube = Cudd_bddIte(dd,cube,vars[i],zero); 01689 } else 01690 continue; 01691 if (newCube == NULL) { 01692 FREE(weight); 01693 FREE(string); 01694 FREE(mask); 01695 FREE(indices); 01696 Cudd_RecursiveDeref(dd,cube); 01697 return(NULL); 01698 } 01699 cuddRef(newCube); 01700 Cudd_RecursiveDeref(dd,cube); 01701 cube = newCube; 01702 } 01703 Cudd_RecursiveDeref(dd,cube); 01704 01705 for (i = 0; i < mvars; i++) { 01706 mask[maskVars[i]->index] = 1; 01707 } 01708 for (i = 0; i < nvars; i++) { 01709 if (mask[indices[i]]) { 01710 if (string[indices[i]] == '2') { 01711 if (weight[indices[i]] >= 0.0) 01712 string[indices[i]] = '1'; 01713 else 01714 string[indices[i]] = '0'; 01715 } 01716 } else { 01717 string[indices[i]] = '2'; 01718 } 01719 } 01720 01721 cube = Cudd_ReadOne(dd); 01722 cuddRef(cube); 01723 zero = Cudd_Not(Cudd_ReadOne(dd)); 01724 01725 /* Build result BDD. */ 01726 for (i = 0; i < nvars; i++) { 01727 if (string[indices[i]] == '0') { 01728 newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); 01729 } else if (string[indices[i]] == '1') { 01730 newCube = Cudd_bddIte(dd,cube,vars[i],zero); 01731 } else 01732 continue; 01733 if (newCube == NULL) { 01734 FREE(weight); 01735 FREE(string); 01736 FREE(mask); 01737 FREE(indices); 01738 Cudd_RecursiveDeref(dd,cube); 01739 return(NULL); 01740 } 01741 cuddRef(newCube); 01742 Cudd_RecursiveDeref(dd,cube); 01743 cube = newCube; 01744 } 01745 01746 subset = Cudd_bddAnd(dd,f,cube); 01747 cuddRef(subset); 01748 Cudd_RecursiveDeref(dd,cube); 01749 01750 /* Test. */ 01751 if (Cudd_bddLeq(dd,subset,f)) { 01752 cuddDeref(subset); 01753 } else { 01754 Cudd_RecursiveDeref(dd,subset); 01755 subset = NULL; 01756 } 01757 01758 FREE(weight); 01759 FREE(string); 01760 FREE(mask); 01761 FREE(indices); 01762 return(subset); 01763 01764 } /* end of Cudd_SubsetWithMaskVars */
Function********************************************************************
Synopsis [Finds the variables on which a DD depends.]
Description [Finds the variables on which a DD depends. Returns a BDD consisting of the product of the variables if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_VectorSupport Cudd_ClassifySupport]
Definition at line 736 of file cuddUtil.c.
00739 { 00740 int *support; 00741 DdNode *res, *tmp, *var; 00742 int i,j; 00743 int size; 00744 00745 /* Allocate and initialize support array for ddSupportStep. */ 00746 size = ddMax(dd->size, dd->sizeZ); 00747 support = ALLOC(int,size); 00748 if (support == NULL) { 00749 dd->errorCode = CUDD_MEMORY_OUT; 00750 return(NULL); 00751 } 00752 for (i = 0; i < size; i++) { 00753 support[i] = 0; 00754 } 00755 00756 /* Compute support and clean up markers. */ 00757 ddSupportStep(Cudd_Regular(f),support); 00758 ddClearFlag(Cudd_Regular(f)); 00759 00760 /* Transform support from array to cube. */ 00761 do { 00762 dd->reordered = 0; 00763 res = DD_ONE(dd); 00764 cuddRef(res); 00765 for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ 00766 i = (j >= dd->size) ? j : dd->invperm[j]; 00767 if (support[i] == 1) { 00768 /* The following call to cuddUniqueInter is guaranteed 00769 ** not to trigger reordering because the node we look up 00770 ** already exists. */ 00771 var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); 00772 cuddRef(var); 00773 tmp = cuddBddAndRecur(dd,res,var); 00774 if (tmp == NULL) { 00775 Cudd_RecursiveDeref(dd,res); 00776 Cudd_RecursiveDeref(dd,var); 00777 res = NULL; 00778 break; 00779 } 00780 cuddRef(tmp); 00781 Cudd_RecursiveDeref(dd,res); 00782 Cudd_RecursiveDeref(dd,var); 00783 res = tmp; 00784 } 00785 } 00786 } while (dd->reordered == 1); 00787 00788 FREE(support); 00789 if (res != NULL) cuddDeref(res); 00790 return(res); 00791 00792 } /* end of Cudd_Support */
Function********************************************************************
Synopsis [Finds the variables on which a DD depends.]
Description [Finds the variables on which a DD depends. Returns an index array of the variables if successful; NULL otherwise. The size of the array equals the number of variables in the manager. Each entry of the array is 1 if the corresponding variable is in the support of the DD and 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_Support Cudd_VectorSupport Cudd_ClassifySupport]
Definition at line 811 of file cuddUtil.c.
00814 { 00815 int *support; 00816 int i; 00817 int size; 00818 00819 /* Allocate and initialize support array for ddSupportStep. */ 00820 size = ddMax(dd->size, dd->sizeZ); 00821 support = ALLOC(int,size); 00822 if (support == NULL) { 00823 dd->errorCode = CUDD_MEMORY_OUT; 00824 return(NULL); 00825 } 00826 for (i = 0; i < size; i++) { 00827 support[i] = 0; 00828 } 00829 00830 /* Compute support and clean up markers. */ 00831 ddSupportStep(Cudd_Regular(f),support); 00832 ddClearFlag(Cudd_Regular(f)); 00833 00834 return(support); 00835 00836 } /* end of Cudd_SupportIndex */
Function********************************************************************
Synopsis [Counts the variables on which a DD depends.]
Description [Counts the variables on which a DD depends. Returns the number of the variables if successful; CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_Support]
Definition at line 853 of file cuddUtil.c.
00856 { 00857 int *support; 00858 int i; 00859 int size; 00860 int count; 00861 00862 /* Allocate and initialize support array for ddSupportStep. */ 00863 size = ddMax(dd->size, dd->sizeZ); 00864 support = ALLOC(int,size); 00865 if (support == NULL) { 00866 dd->errorCode = CUDD_MEMORY_OUT; 00867 return(CUDD_OUT_OF_MEM); 00868 } 00869 for (i = 0; i < size; i++) { 00870 support[i] = 0; 00871 } 00872 00873 /* Compute support and clean up markers. */ 00874 ddSupportStep(Cudd_Regular(f),support); 00875 ddClearFlag(Cudd_Regular(f)); 00876 00877 /* Count support variables. */ 00878 count = 0; 00879 for (i = 0; i < size; i++) { 00880 if (support[i] == 1) count++; 00881 } 00882 00883 FREE(support); 00884 return(count); 00885 00886 } /* end of Cudd_SupportSize */
Function********************************************************************
Synopsis [Finds the variables on which a set of DDs depends.]
Description [Finds the variables on which a set of DDs depends. The set must contain either BDDs and ADDs, or ZDDs. Returns a BDD consisting of the product of the variables if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_Support Cudd_ClassifySupport]
Definition at line 904 of file cuddUtil.c.
00908 { 00909 int *support; 00910 DdNode *res, *tmp, *var; 00911 int i,j; 00912 int size; 00913 00914 /* Allocate and initialize support array for ddSupportStep. */ 00915 size = ddMax(dd->size, dd->sizeZ); 00916 support = ALLOC(int,size); 00917 if (support == NULL) { 00918 dd->errorCode = CUDD_MEMORY_OUT; 00919 return(NULL); 00920 } 00921 for (i = 0; i < size; i++) { 00922 support[i] = 0; 00923 } 00924 00925 /* Compute support and clean up markers. */ 00926 for (i = 0; i < n; i++) { 00927 ddSupportStep(Cudd_Regular(F[i]),support); 00928 } 00929 for (i = 0; i < n; i++) { 00930 ddClearFlag(Cudd_Regular(F[i])); 00931 } 00932 00933 /* Transform support from array to cube. */ 00934 res = DD_ONE(dd); 00935 cuddRef(res); 00936 for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ 00937 i = (j >= dd->size) ? j : dd->invperm[j]; 00938 if (support[i] == 1) { 00939 var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); 00940 cuddRef(var); 00941 tmp = Cudd_bddAnd(dd,res,var); 00942 if (tmp == NULL) { 00943 Cudd_RecursiveDeref(dd,res); 00944 Cudd_RecursiveDeref(dd,var); 00945 FREE(support); 00946 return(NULL); 00947 } 00948 cuddRef(tmp); 00949 Cudd_RecursiveDeref(dd,res); 00950 Cudd_RecursiveDeref(dd,var); 00951 res = tmp; 00952 } 00953 } 00954 00955 FREE(support); 00956 cuddDeref(res); 00957 return(res); 00958 00959 } /* end of Cudd_VectorSupport */
Function********************************************************************
Synopsis [Finds the variables on which a set of DDs depends.]
Description [Finds the variables on which a set of DDs depends. The set must contain either BDDs and ADDs, or ZDDs. Returns an index array of the variables if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_SupportIndex Cudd_VectorSupport Cudd_ClassifySupport]
Definition at line 976 of file cuddUtil.c.
00980 { 00981 int *support; 00982 int i; 00983 int size; 00984 00985 /* Allocate and initialize support array for ddSupportStep. */ 00986 size = ddMax(dd->size, dd->sizeZ); 00987 support = ALLOC(int,size); 00988 if (support == NULL) { 00989 dd->errorCode = CUDD_MEMORY_OUT; 00990 return(NULL); 00991 } 00992 for (i = 0; i < size; i++) { 00993 support[i] = 0; 00994 } 00995 00996 /* Compute support and clean up markers. */ 00997 for (i = 0; i < n; i++) { 00998 ddSupportStep(Cudd_Regular(F[i]),support); 00999 } 01000 for (i = 0; i < n; i++) { 01001 ddClearFlag(Cudd_Regular(F[i])); 01002 } 01003 01004 return(support); 01005 01006 } /* end of Cudd_VectorSupportIndex */
Function********************************************************************
Synopsis [Counts the variables on which a set of DDs depends.]
Description [Counts the variables on which a set of DDs depends. The set must contain either BDDs and ADDs, or ZDDs. Returns the number of the variables if successful; CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_VectorSupport Cudd_SupportSize]
Definition at line 1024 of file cuddUtil.c.
01028 { 01029 int *support; 01030 int i; 01031 int size; 01032 int count; 01033 01034 /* Allocate and initialize support array for ddSupportStep. */ 01035 size = ddMax(dd->size, dd->sizeZ); 01036 support = ALLOC(int,size); 01037 if (support == NULL) { 01038 dd->errorCode = CUDD_MEMORY_OUT; 01039 return(CUDD_OUT_OF_MEM); 01040 } 01041 for (i = 0; i < size; i++) { 01042 support[i] = 0; 01043 } 01044 01045 /* Compute support and clean up markers. */ 01046 for (i = 0; i < n; i++) { 01047 ddSupportStep(Cudd_Regular(F[i]),support); 01048 } 01049 for (i = 0; i < n; i++) { 01050 ddClearFlag(Cudd_Regular(F[i])); 01051 } 01052 01053 /* Count vriables in support. */ 01054 count = 0; 01055 for (i = 0; i < size; i++) { 01056 if (support[i] == 1) count++; 01057 } 01058 01059 FREE(support); 01060 return(count); 01061 01062 } /* end of Cudd_VectorSupportSize */
Function********************************************************************
Synopsis [Recursively collects all the nodes of a DD in a symbol table.]
Description [Traverses the DD f and collects all its nodes in a symbol table. f is assumed to be a regular pointer and cuddCollectNodes guarantees this assumption in the recursive calls. Returns 1 in case of success; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 2921 of file cuddUtil.c.
02924 { 02925 DdNode *T, *E; 02926 int retval; 02927 02928 #ifdef DD_DEBUG 02929 assert(!Cudd_IsComplement(f)); 02930 #endif 02931 02932 /* If already visited, nothing to do. */ 02933 if (st_is_member(visited, (char *) f) == 1) 02934 return(1); 02935 02936 /* Check for abnormal condition that should never happen. */ 02937 if (f == NULL) 02938 return(0); 02939 02940 /* Mark node as visited. */ 02941 if (st_add_direct(visited, (char *) f, NULL) == ST_OUT_OF_MEM) 02942 return(0); 02943 02944 /* Check terminal case. */ 02945 if (cuddIsConstant(f)) 02946 return(1); 02947 02948 /* Recursive calls. */ 02949 T = cuddT(f); 02950 retval = cuddCollectNodes(T,visited); 02951 if (retval != 1) return(retval); 02952 E = Cudd_Regular(cuddE(f)); 02953 retval = cuddCollectNodes(E,visited); 02954 return(retval); 02955 02956 } /* end of cuddCollectNodes */
static int cuddEstimateCofactor | ( | DdManager * | dd, | |
st_table * | table, | |||
DdNode * | node, | |||
int | i, | |||
int | phase, | |||
DdNode ** | ptr | |||
) | [static] |
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_CofactorEstimate.]
Description [Performs the recursive step of Cudd_CofactorEstimate. Returns an estimate of the number of nodes in the DD of a cofactor of node. Uses the least significant bit of the next field as visited flag. node is supposed to be regular; the invariant is maintained by this procedure.]
SideEffects [None]
SeeAlso []
Definition at line 3236 of file cuddUtil.c.
03243 { 03244 int tval, eval, val; 03245 DdNode *ptrT, *ptrE; 03246 03247 if (Cudd_IsComplement(node->next)) { 03248 if (!st_lookup(table,(char *)node,(char **)ptr)) { 03249 if (st_add_direct(table,(char *)node,(char *)node) == 03250 ST_OUT_OF_MEM) 03251 return(CUDD_OUT_OF_MEM); 03252 *ptr = node; 03253 } 03254 return(0); 03255 } 03256 node->next = Cudd_Not(node->next); 03257 if (cuddIsConstant(node)) { 03258 *ptr = node; 03259 if (st_add_direct(table,(char *)node,(char *)node) == ST_OUT_OF_MEM) 03260 return(CUDD_OUT_OF_MEM); 03261 return(1); 03262 } 03263 if ((int) node->index == i) { 03264 if (phase == 1) { 03265 *ptr = cuddT(node); 03266 val = ddDagInt(cuddT(node)); 03267 } else { 03268 *ptr = cuddE(node); 03269 val = ddDagInt(Cudd_Regular(cuddE(node))); 03270 } 03271 if (node->ref > 1) { 03272 if (st_add_direct(table,(char *)node,(char *)*ptr) == 03273 ST_OUT_OF_MEM) 03274 return(CUDD_OUT_OF_MEM); 03275 } 03276 return(val); 03277 } 03278 if (dd->perm[node->index] > dd->perm[i]) { 03279 *ptr = node; 03280 tval = ddDagInt(cuddT(node)); 03281 eval = ddDagInt(Cudd_Regular(cuddE(node))); 03282 if (node->ref > 1) { 03283 if (st_add_direct(table,(char *)node,(char *)node) == 03284 ST_OUT_OF_MEM) 03285 return(CUDD_OUT_OF_MEM); 03286 } 03287 val = 1 + tval + eval; 03288 return(val); 03289 } 03290 tval = cuddEstimateCofactor(dd,table,cuddT(node),i,phase,&ptrT); 03291 eval = cuddEstimateCofactor(dd,table,Cudd_Regular(cuddE(node)),i, 03292 phase,&ptrE); 03293 ptrE = Cudd_NotCond(ptrE,Cudd_IsComplement(cuddE(node))); 03294 if (ptrT == ptrE) { /* recombination */ 03295 *ptr = ptrT; 03296 val = tval; 03297 if (node->ref > 1) { 03298 if (st_add_direct(table,(char *)node,(char *)*ptr) == 03299 ST_OUT_OF_MEM) 03300 return(CUDD_OUT_OF_MEM); 03301 } 03302 } else if ((ptrT != cuddT(node) || ptrE != cuddE(node)) && 03303 (*ptr = cuddUniqueLookup(dd,node->index,ptrT,ptrE)) != NULL) { 03304 if (Cudd_IsComplement((*ptr)->next)) { 03305 val = 0; 03306 } else { 03307 val = 1 + tval + eval; 03308 } 03309 if (node->ref > 1) { 03310 if (st_add_direct(table,(char *)node,(char *)*ptr) == 03311 ST_OUT_OF_MEM) 03312 return(CUDD_OUT_OF_MEM); 03313 } 03314 } else { 03315 *ptr = node; 03316 val = 1 + tval + eval; 03317 } 03318 return(val); 03319 03320 } /* end of cuddEstimateCofactor */
static int cuddEstimateCofactorSimple | ( | DdNode * | node, | |
int | i | |||
) | [static] |
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_CofactorEstimateSimple.]
Description [Performs the recursive step of Cudd_CofactorEstimateSimple. Returns an estimate of the number of nodes in the DD of the positive cofactor of node. Uses the least significant bit of the next field as visited flag. node is supposed to be regular; the invariant is maintained by this procedure.]
SideEffects [None]
SeeAlso []
Definition at line 3395 of file cuddUtil.c.
03398 { 03399 int tval, eval; 03400 03401 if (Cudd_IsComplement(node->next)) { 03402 return(0); 03403 } 03404 node->next = Cudd_Not(node->next); 03405 if (cuddIsConstant(node)) { 03406 return(1); 03407 } 03408 tval = cuddEstimateCofactorSimple(cuddT(node),i); 03409 if ((int) node->index == i) return(tval); 03410 eval = cuddEstimateCofactorSimple(Cudd_Regular(cuddE(node)),i); 03411 return(1 + tval + eval); 03412 03413 } /* end of cuddEstimateCofactorSimple */
Function********************************************************************
Synopsis [Recursively collects all the nodes of a DD in an array.]
Description [Traverses the DD f and collects all its nodes in an array. The caller should free the array returned by cuddNodeArray. Returns a pointer to the array of nodes in case of success; NULL otherwise. The nodes are collected in reverse topological order, so that a node is always preceded in the array by all its descendants.]
SideEffects [The number of nodes is returned as a side effect.]
SeeAlso [Cudd_FirstNode]
Definition at line 2975 of file cuddUtil.c.
02978 { 02979 DdNodePtr *table; 02980 int size, retval; 02981 02982 size = ddDagInt(Cudd_Regular(f)); 02983 table = ALLOC(DdNodePtr, size); 02984 if (table == NULL) { 02985 ddClearFlag(Cudd_Regular(f)); 02986 return(NULL); 02987 } 02988 02989 retval = cuddNodeArrayRecur(f, table, 0); 02990 assert(retval == size); 02991 02992 *n = size; 02993 return(table); 02994 02995 } /* cuddNodeArray */
Function********************************************************************
Synopsis [Performs the recursive step of cuddNodeArray.]
Description [Performs the recursive step of cuddNodeArray. Returns an the number of nodes in the DD. Clear the least significant bit of the next field that was used as visited flag by cuddNodeArrayRecur when counting the nodes. node is supposed to be regular; the invariant is maintained by this procedure.]
SideEffects [None]
SeeAlso []
Definition at line 3196 of file cuddUtil.c.
03200 { 03201 int tindex, eindex; 03202 03203 if (!Cudd_IsComplement(f->next)) { 03204 return(index); 03205 } 03206 /* Clear visited flag. */ 03207 f->next = Cudd_Regular(f->next); 03208 if (cuddIsConstant(f)) { 03209 table[index] = f; 03210 return(index + 1); 03211 } 03212 tindex = cuddNodeArrayRecur(cuddT(f), table, index); 03213 eindex = cuddNodeArrayRecur(Cudd_Regular(cuddE(f)), table, tindex); 03214 table[eindex] = f; 03215 return(eindex + 1); 03216 03217 } /* end of cuddNodeArrayRecur */
Function********************************************************************
Synopsis [Prints a DD to the standard output. One line per node is printed.]
Description [Prints a DD to the standard output. One line per node is printed. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_PrintDebug]
Definition at line 2862 of file cuddUtil.c.
02865 { 02866 int retval; 02867 st_table *table = st_init_table(st_ptrcmp,st_ptrhash); 02868 02869 if (table == NULL) return(0); 02870 02871 retval = dp2(dd,f,table); 02872 st_free_table(table); 02873 (void) fputc('\n',dd->out); 02874 return(retval); 02875 02876 } /* end of cuddP */
enum st_retval cuddStCountfree | ( | char * | key, | |
char * | value, | |||
char * | arg | |||
) |
Function********************************************************************
Synopsis [Frees the memory used to store the minterm counts recorded in the visited table.]
Description [Frees the memory used to store the minterm counts recorded in the visited table. Returns ST_CONTINUE.]
SideEffects [None]
Definition at line 2891 of file cuddUtil.c.
02895 { 02896 double *d; 02897 02898 d = (double *)value; 02899 FREE(d); 02900 return(ST_CONTINUE); 02901 02902 } /* end of cuddStCountfree */
Function********************************************************************
Synopsis [Checks the unique table for the existence of an internal node.]
Description [Checks the unique table for the existence of an internal node. Returns a pointer to the node if it is in the table; NULL otherwise.]
SideEffects [None]
SeeAlso [cuddUniqueInter]
Definition at line 3336 of file cuddUtil.c.
03341 { 03342 int posn; 03343 unsigned int level; 03344 DdNodePtr *nodelist; 03345 DdNode *looking; 03346 DdSubtable *subtable; 03347 03348 if (index >= unique->size) { 03349 return(NULL); 03350 } 03351 03352 level = unique->perm[index]; 03353 subtable = &(unique->subtables[level]); 03354 03355 #ifdef DD_DEBUG 03356 assert(level < (unsigned) cuddI(unique,T->index)); 03357 assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index)); 03358 #endif 03359 03360 posn = ddHash(T, E, subtable->shift); 03361 nodelist = subtable->nodelist; 03362 looking = nodelist[posn]; 03363 03364 while (T < cuddT(looking)) { 03365 looking = Cudd_Regular(looking->next); 03366 } 03367 while (T == cuddT(looking) && E < cuddE(looking)) { 03368 looking = Cudd_Regular(looking->next); 03369 } 03370 if (cuddT(looking) == T && cuddE(looking) == E) { 03371 return(looking); 03372 } 03373 03374 return(NULL); 03375 03376 } /* end of cuddUniqueLookup */
static void ddClearFlag | ( | DdNode * | f | ) | [static] |
Function********************************************************************
Synopsis [Performs a DFS from f, clearing the LSB of the next pointers.]
Description []
SideEffects [None]
SeeAlso [ddSupportStep ddDagInt]
Definition at line 3731 of file cuddUtil.c.
03733 { 03734 if (!Cudd_IsComplement(f->next)) { 03735 return; 03736 } 03737 /* Clear visited flag. */ 03738 f->next = Cudd_Regular(f->next); 03739 if (cuddIsConstant(f)) { 03740 return; 03741 } 03742 ddClearFlag(cuddT(f)); 03743 ddClearFlag(Cudd_Regular(cuddE(f))); 03744 return; 03745 03746 } /* end of ddClearFlag */
static double ddCountMintermAux | ( | DdNode * | node, | |
double | max, | |||
DdHashTable * | table | |||
) | [static] |
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_CountMinterm.]
Description [Performs the recursive step of Cudd_CountMinterm. It is based on the following identity. Let |f| be the number of minterms of f. Then: <xmp> |f| = (|f0|+|f1|)/2 </xmp> where f0 and f1 are the two cofactors of f. Does not use the identity |f'| = max - |f|, to minimize loss of accuracy due to roundoff. Returns the number of minterms of the function rooted at node.]
SideEffects [None]
Definition at line 3435 of file cuddUtil.c.
03439 { 03440 DdNode *N, *Nt, *Ne; 03441 double min, minT, minE; 03442 DdNode *res; 03443 03444 N = Cudd_Regular(node); 03445 03446 if (cuddIsConstant(N)) { 03447 if (node == background || node == zero) { 03448 return(0.0); 03449 } else { 03450 return(max); 03451 } 03452 } 03453 if (N->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { 03454 min = cuddV(res); 03455 if (res->ref == 0) { 03456 table->manager->dead++; 03457 table->manager->constants.dead++; 03458 } 03459 return(min); 03460 } 03461 03462 Nt = cuddT(N); Ne = cuddE(N); 03463 if (Cudd_IsComplement(node)) { 03464 Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); 03465 } 03466 03467 minT = ddCountMintermAux(Nt,max,table); 03468 if (minT == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); 03469 minT *= 0.5; 03470 minE = ddCountMintermAux(Ne,max,table); 03471 if (minE == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); 03472 minE *= 0.5; 03473 min = minT + minE; 03474 03475 if (N->ref != 1) { 03476 ptrint fanout = (ptrint) N->ref; 03477 cuddSatDec(fanout); 03478 res = cuddUniqueConst(table->manager,min); 03479 if (!cuddHashTableInsert1(table,node,res,fanout)) { 03480 cuddRef(res); Cudd_RecursiveDeref(table->manager, res); 03481 return((double)CUDD_OUT_OF_MEM); 03482 } 03483 } 03484 03485 return(min); 03486 03487 } /* end of ddCountMintermAux */
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_CountPath.]
Description [Performs the recursive step of Cudd_CountPath. It is based on the following identity. Let |f| be the number of paths of f. Then: <xmp> |f| = |f0|+|f1| </xmp> where f0 and f1 are the two cofactors of f. Uses the identity |f'| = |f|, to improve the utilization of the (local) cache. Returns the number of paths of the function rooted at node.]
SideEffects [None]
Definition at line 3508 of file cuddUtil.c.
03511 { 03512 03513 DdNode *Nv, *Nnv; 03514 double paths, *ppaths, paths1, paths2; 03515 double *dummy; 03516 03517 03518 if (cuddIsConstant(node)) { 03519 return(1.0); 03520 } 03521 if (st_lookup(table, node, &dummy)) { 03522 paths = *dummy; 03523 return(paths); 03524 } 03525 03526 Nv = cuddT(node); Nnv = cuddE(node); 03527 03528 paths1 = ddCountPathAux(Nv,table); 03529 if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); 03530 paths2 = ddCountPathAux(Cudd_Regular(Nnv),table); 03531 if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); 03532 paths = paths1 + paths2; 03533 03534 ppaths = ALLOC(double,1); 03535 if (ppaths == NULL) { 03536 return((double)CUDD_OUT_OF_MEM); 03537 } 03538 03539 *ppaths = paths; 03540 03541 if (st_add_direct(table,(char *)node, (char *)ppaths) == ST_OUT_OF_MEM) { 03542 FREE(ppaths); 03543 return((double)CUDD_OUT_OF_MEM); 03544 } 03545 return(paths); 03546 03547 } /* end of ddCountPathAux */
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_CountPathsToNonZero.]
Description [Performs the recursive step of Cudd_CountPathsToNonZero. It is based on the following identity. Let |f| be the number of paths of f. Then: <xmp> |f| = |f0|+|f1| </xmp> where f0 and f1 are the two cofactors of f. Returns the number of paths of the function rooted at node.]
SideEffects [None]
Definition at line 3641 of file cuddUtil.c.
03644 { 03645 03646 DdNode *node, *Nt, *Ne; 03647 double paths, *ppaths, paths1, paths2; 03648 double *dummy; 03649 03650 node = Cudd_Regular(N); 03651 if (cuddIsConstant(node)) { 03652 return((double) !(Cudd_IsComplement(N) || cuddV(node)==DD_ZERO_VAL)); 03653 } 03654 if (st_lookup(table, N, &dummy)) { 03655 paths = *dummy; 03656 return(paths); 03657 } 03658 03659 Nt = cuddT(node); Ne = cuddE(node); 03660 if (node != N) { 03661 Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); 03662 } 03663 03664 paths1 = ddCountPathsToNonZero(Nt,table); 03665 if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); 03666 paths2 = ddCountPathsToNonZero(Ne,table); 03667 if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); 03668 paths = paths1 + paths2; 03669 03670 ppaths = ALLOC(double,1); 03671 if (ppaths == NULL) { 03672 return((double)CUDD_OUT_OF_MEM); 03673 } 03674 03675 *ppaths = paths; 03676 03677 if (st_add_direct(table,(char *)N, (char *)ppaths) == ST_OUT_OF_MEM) { 03678 FREE(ppaths); 03679 return((double)CUDD_OUT_OF_MEM); 03680 } 03681 return(paths); 03682 03683 } /* end of ddCountPathsToNonZero */
static int ddDagInt | ( | DdNode * | n | ) | [static] |
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_DagSize.]
Description [Performs the recursive step of Cudd_DagSize. Returns the number of nodes in the graph rooted at n.]
SideEffects [None]
Definition at line 3161 of file cuddUtil.c.
03163 { 03164 int tval, eval; 03165 03166 if (Cudd_IsComplement(n->next)) { 03167 return(0); 03168 } 03169 n->next = Cudd_Not(n->next); 03170 if (cuddIsConstant(n)) { 03171 return(1); 03172 } 03173 tval = ddDagInt(cuddT(n)); 03174 eval = ddDagInt(Cudd_Regular(cuddE(n))); 03175 return(1 + tval + eval); 03176 03177 } /* end of ddDagInt */
static int ddEpdCountMintermAux | ( | DdNode * | node, | |
EpDouble * | max, | |||
EpDouble * | epd, | |||
st_table * | table | |||
) | [static] |
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_EpdCountMinterm.]
Description [Performs the recursive step of Cudd_EpdCountMinterm. It is based on the following identity. Let |f| be the number of minterms of f. Then: <xmp> |f| = (|f0|+|f1|)/2 </xmp> where f0 and f1 are the two cofactors of f. Does not use the identity |f'| = max - |f|, to minimize loss of accuracy due to roundoff. Returns the number of minterms of the function rooted at node.]
SideEffects [None]
Definition at line 3569 of file cuddUtil.c.
03574 { 03575 DdNode *Nt, *Ne; 03576 EpDouble *min, minT, minE; 03577 EpDouble *res; 03578 int status; 03579 03580 /* node is assumed to be regular */ 03581 if (cuddIsConstant(node)) { 03582 if (node == background || node == zero) { 03583 EpdMakeZero(epd, 0); 03584 } else { 03585 EpdCopy(max, epd); 03586 } 03587 return(0); 03588 } 03589 if (node->ref != 1 && st_lookup(table, node, &res)) { 03590 EpdCopy(res, epd); 03591 return(0); 03592 } 03593 03594 Nt = cuddT(node); Ne = cuddE(node); 03595 03596 status = ddEpdCountMintermAux(Nt,max,&minT,table); 03597 if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); 03598 EpdMultiply(&minT, (double)0.5); 03599 status = ddEpdCountMintermAux(Cudd_Regular(Ne),max,&minE,table); 03600 if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); 03601 if (Cudd_IsComplement(Ne)) { 03602 EpdSubtract3(max, &minE, epd); 03603 EpdCopy(epd, &minE); 03604 } 03605 EpdMultiply(&minE, (double)0.5); 03606 EpdAdd3(&minT, &minE, epd); 03607 03608 if (node->ref > 1) { 03609 min = EpdAlloc(); 03610 if (!min) 03611 return(CUDD_OUT_OF_MEM); 03612 EpdCopy(epd, min); 03613 if (st_insert(table, (char *)node, (char *)min) == ST_OUT_OF_MEM) { 03614 EpdFree(min); 03615 return(CUDD_OUT_OF_MEM); 03616 } 03617 } 03618 03619 return(0); 03620 03621 } /* end of ddEpdCountMintermAux */
static enum st_retval ddEpdFree | ( | char * | key, | |
char * | value, | |||
char * | arg | |||
) | [static] |
Function********************************************************************
Synopsis [Frees the memory used to store the minterm counts recorded in the visited table.]
Description [Frees the memory used to store the minterm counts recorded in the visited table. Returns ST_CONTINUE.]
SideEffects [None]
Definition at line 3918 of file cuddUtil.c.
03922 { 03923 EpDouble *epd; 03924 03925 epd = (EpDouble *) value; 03926 EpdFree(epd); 03927 return(ST_CONTINUE); 03928 03929 } /* end of ddEpdFree */
static int ddLeavesInt | ( | DdNode * | n | ) | [static] |
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_CountLeaves.]
Description [Performs the recursive step of Cudd_CountLeaves. Returns the number of leaves in the DD rooted at n.]
SideEffects [None]
SeeAlso [Cudd_CountLeaves]
Definition at line 3762 of file cuddUtil.c.
03764 { 03765 int tval, eval; 03766 03767 if (Cudd_IsComplement(n->next)) { 03768 return(0); 03769 } 03770 n->next = Cudd_Not(n->next); 03771 if (cuddIsConstant(n)) { 03772 return(1); 03773 } 03774 tval = ddLeavesInt(cuddT(n)); 03775 eval = ddLeavesInt(Cudd_Regular(cuddE(n))); 03776 return(tval + eval); 03777 03778 } /* end of ddLeavesInt */
static int ddPickArbitraryMinterms | ( | DdManager * | dd, | |
DdNode * | node, | |||
int | nvars, | |||
int | nminterms, | |||
char ** | string | |||
) | [static] |
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_bddPickArbitraryMinterms.]
Description [Performs the recursive step of Cudd_bddPickArbitraryMinterms. Returns 1 if successful; 0 otherwise.]
SideEffects [none]
SeeAlso [Cudd_bddPickArbitraryMinterms]
Definition at line 3794 of file cuddUtil.c.
03800 { 03801 DdNode *N, *T, *E; 03802 DdNode *one, *bzero; 03803 int i, t, result; 03804 double min1, min2; 03805 03806 if (string == NULL || node == NULL) return(0); 03807 03808 /* The constant 0 function has no on-set cubes. */ 03809 one = DD_ONE(dd); 03810 bzero = Cudd_Not(one); 03811 if (nminterms == 0 || node == bzero) return(1); 03812 if (node == one) { 03813 return(1); 03814 } 03815 03816 N = Cudd_Regular(node); 03817 T = cuddT(N); E = cuddE(N); 03818 if (Cudd_IsComplement(node)) { 03819 T = Cudd_Not(T); E = Cudd_Not(E); 03820 } 03821 03822 min1 = Cudd_CountMinterm(dd, T, nvars) / 2.0; 03823 if (min1 == (double)CUDD_OUT_OF_MEM) return(0); 03824 min2 = Cudd_CountMinterm(dd, E, nvars) / 2.0; 03825 if (min2 == (double)CUDD_OUT_OF_MEM) return(0); 03826 03827 t = (int)((double)nminterms * min1 / (min1 + min2) + 0.5); 03828 for (i = 0; i < t; i++) 03829 string[i][N->index] = '1'; 03830 for (i = t; i < nminterms; i++) 03831 string[i][N->index] = '0'; 03832 03833 result = ddPickArbitraryMinterms(dd,T,nvars,t,&string[0]); 03834 if (result == 0) 03835 return(0); 03836 result = ddPickArbitraryMinterms(dd,E,nvars,nminterms-t,&string[t]); 03837 return(result); 03838 03839 } /* end of ddPickArbitraryMinterms */
static int ddPickRepresentativeCube | ( | DdManager * | dd, | |
DdNode * | node, | |||
double * | weight, | |||
char * | string | |||
) | [static] |
Function********************************************************************
Synopsis [Finds a representative cube of a BDD.]
Description [Finds a representative cube of a BDD with the weight of each variable. From the top variable, if the weight is greater than or equal to 0.0, choose THEN branch unless the child is the constant 0. Otherwise, choose ELSE branch unless the child is the constant 0.]
SideEffects [Cudd_SubsetWithMaskVars Cudd_bddPickOneCube]
Definition at line 3855 of file cuddUtil.c.
03860 { 03861 DdNode *N, *T, *E; 03862 DdNode *one, *bzero; 03863 03864 if (string == NULL || node == NULL) return(0); 03865 03866 /* The constant 0 function has no on-set cubes. */ 03867 one = DD_ONE(dd); 03868 bzero = Cudd_Not(one); 03869 if (node == bzero) return(0); 03870 03871 if (node == DD_ONE(dd)) return(1); 03872 03873 for (;;) { 03874 N = Cudd_Regular(node); 03875 if (N == one) 03876 break; 03877 T = cuddT(N); 03878 E = cuddE(N); 03879 if (Cudd_IsComplement(node)) { 03880 T = Cudd_Not(T); 03881 E = Cudd_Not(E); 03882 } 03883 if (weight[N->index] >= 0.0) { 03884 if (T == bzero) { 03885 node = E; 03886 string[N->index] = '0'; 03887 } else { 03888 node = T; 03889 string[N->index] = '1'; 03890 } 03891 } else { 03892 if (E == bzero) { 03893 node = T; 03894 string[N->index] = '1'; 03895 } else { 03896 node = E; 03897 string[N->index] = '0'; 03898 } 03899 } 03900 } 03901 return(1); 03902 03903 } /* end of ddPickRepresentativeCube */
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_PrintMinterm.]
Description []
SideEffects [None]
Definition at line 3107 of file cuddUtil.c.
03111 { 03112 DdNode *N,*Nv,*Nnv; 03113 int i,v,index; 03114 03115 N = Cudd_Regular(node); 03116 03117 if (cuddIsConstant(N)) { 03118 /* Terminal case: Print one cube based on the current recursion 03119 ** path, unless we have reached the background value (ADDs) or 03120 ** the logical zero (BDDs). 03121 */ 03122 if (node != background && node != zero) { 03123 for (i = 0; i < dd->size; i++) { 03124 v = list[i]; 03125 if (v == 0) (void) fprintf(dd->out,"0"); 03126 else if (v == 1) (void) fprintf(dd->out,"1"); 03127 else (void) fprintf(dd->out,"-"); 03128 } 03129 (void) fprintf(dd->out," % g\n", cuddV(node)); 03130 } 03131 } else { 03132 Nv = cuddT(N); 03133 Nnv = cuddE(N); 03134 if (Cudd_IsComplement(node)) { 03135 Nv = Cudd_Not(Nv); 03136 Nnv = Cudd_Not(Nnv); 03137 } 03138 index = N->index; 03139 list[index] = 0; 03140 ddPrintMintermAux(dd,Nnv,list); 03141 list[index] = 1; 03142 ddPrintMintermAux(dd,Nv,list); 03143 list[index] = 2; 03144 } 03145 return; 03146 03147 } /* end of ddPrintMintermAux */
static void ddSupportStep | ( | DdNode * | f, | |
int * | support | |||
) | [static] |
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_Support.]
Description [Performs the recursive step of Cudd_Support. Performs a DFS from f. The support is accumulated in supp as a side effect. Uses the LSB of the then pointer as visited flag.]
SideEffects [None]
SeeAlso [ddClearFlag]
Definition at line 3700 of file cuddUtil.c.
03703 { 03704 if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) { 03705 return; 03706 } 03707 03708 support[f->index] = 1; 03709 ddSupportStep(cuddT(f),support); 03710 ddSupportStep(Cudd_Regular(cuddE(f)),support); 03711 /* Mark as visited. */ 03712 f->next = Cudd_Not(f->next); 03713 return; 03714 03715 } /* end of ddSupportStep */
AutomaticStart
Function********************************************************************
Synopsis [Performs the recursive step of cuddP.]
Description [Performs the recursive step of cuddP. Returns 1 in case of success; 0 otherwise.]
SideEffects [None]
Definition at line 3014 of file cuddUtil.c.
03018 { 03019 DdNode *g, *n, *N; 03020 int T,E; 03021 03022 if (f == NULL) { 03023 return(0); 03024 } 03025 g = Cudd_Regular(f); 03026 if (cuddIsConstant(g)) { 03027 #if SIZEOF_VOID_P == 8 03028 (void) fprintf(dd->out,"ID = %c0x%lx\tvalue = %-9g\n", bang(f), 03029 (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g)); 03030 #else 03031 (void) fprintf(dd->out,"ID = %c0x%x\tvalue = %-9g\n", bang(f), 03032 (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g)); 03033 #endif 03034 return(1); 03035 } 03036 if (st_is_member(t,(char *) g) == 1) { 03037 return(1); 03038 } 03039 if (st_add_direct(t,(char *) g,NULL) == ST_OUT_OF_MEM) 03040 return(0); 03041 #ifdef DD_STATS 03042 #if SIZEOF_VOID_P == 8 03043 (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %d\tr = %d\t", bang(f), 03044 (ptruint) g / (ptruint) sizeof(DdNode), g->index, g->ref); 03045 #else 03046 (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\tr = %d\t", bang(f), 03047 (ptruint) g / (ptruint) sizeof(DdNode),g->index,g->ref); 03048 #endif 03049 #else 03050 #if SIZEOF_VOID_P == 8 03051 (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %u\t", bang(f), 03052 (ptruint) g / (ptruint) sizeof(DdNode),g->index); 03053 #else 03054 (void) fprintf(dd->out,"ID = %c0x%x\tindex = %hu\t", bang(f), 03055 (ptruint) g / (ptruint) sizeof(DdNode),g->index); 03056 #endif 03057 #endif 03058 n = cuddT(g); 03059 if (cuddIsConstant(n)) { 03060 (void) fprintf(dd->out,"T = %-9g\t",cuddV(n)); 03061 T = 1; 03062 } else { 03063 #if SIZEOF_VOID_P == 8 03064 (void) fprintf(dd->out,"T = 0x%lx\t",(ptruint) n / (ptruint) sizeof(DdNode)); 03065 #else 03066 (void) fprintf(dd->out,"T = 0x%x\t",(ptruint) n / (ptruint) sizeof(DdNode)); 03067 #endif 03068 T = 0; 03069 } 03070 03071 n = cuddE(g); 03072 N = Cudd_Regular(n); 03073 if (cuddIsConstant(N)) { 03074 (void) fprintf(dd->out,"E = %c%-9g\n",bang(n),cuddV(N)); 03075 E = 1; 03076 } else { 03077 #if SIZEOF_VOID_P == 8 03078 (void) fprintf(dd->out,"E = %c0x%lx\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode)); 03079 #else 03080 (void) fprintf(dd->out,"E = %c0x%x\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode)); 03081 #endif 03082 E = 0; 03083 } 03084 if (E == 0) { 03085 if (dp2(dd,N,t) == 0) 03086 return(0); 03087 } 03088 if (T == 0) { 03089 if (dp2(dd,cuddT(g),t) == 0) 03090 return(0); 03091 } 03092 return(1); 03093 03094 } /* end of dp2 */
DdNode* background [static] |
Definition at line 144 of file cuddUtil.c.
long cuddRand = 0 [static] |
Definition at line 146 of file cuddUtil.c.
long cuddRand2 [static] |
Definition at line 147 of file cuddUtil.c.
char rcsid [] DD_UNUSED = "$Id: cuddUtil.c,v 1.81 2009/03/08 02:49:02 fabio Exp $" [static] |
Definition at line 141 of file cuddUtil.c.
long shuffleSelect [static] |
Definition at line 148 of file cuddUtil.c.
long shuffleTable[STAB_SIZE] [static] |
Definition at line 149 of file cuddUtil.c.
Definition at line 144 of file cuddUtil.c.