src/cuBdd/cuddUtil.c File Reference

#include "util.h"
#include "cuddInt.h"
Include dependency graph for cuddUtil.c:

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 DdNodecuddUniqueLookup (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)
DdNodeCudd_Support (DdManager *dd, DdNode *f)
int * Cudd_SupportIndex (DdManager *dd, DdNode *f)
int Cudd_SupportSize (DdManager *dd, DdNode *f)
DdNodeCudd_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)
DdNodeCudd_bddPickOneMinterm (DdManager *dd, DdNode *f, DdNode **vars, int n)
DdNode ** Cudd_bddPickArbitraryMinterms (DdManager *dd, DdNode *f, DdNode **vars, int n, int k)
DdNodeCudd_SubsetWithMaskVars (DdManager *dd, DdNode *f, DdNode **vars, int nvars, DdNode **maskVars, int mvars)
DdGenCudd_FirstCube (DdManager *dd, DdNode *f, int **cube, CUDD_VALUE_TYPE *value)
int Cudd_NextCube (DdGen *gen, int **cube, CUDD_VALUE_TYPE *value)
DdGenCudd_FirstPrime (DdManager *dd, DdNode *l, DdNode *u, int **cube)
int Cudd_NextPrime (DdGen *gen, int **cube)
DdNodeCudd_bddComputeCube (DdManager *dd, DdNode **vars, int *phase, int n)
DdNodeCudd_addComputeCube (DdManager *dd, DdNode **vars, int *phase, int n)
DdNodeCudd_CubeArrayToBdd (DdManager *dd, int *array)
int Cudd_BddToCubeArray (DdManager *dd, DdNode *cube, int *array)
DdGenCudd_FirstNode (DdManager *dd, DdNode *f, DdNode **node)
int Cudd_NextNode (DdGen *gen, DdNode **node)
int Cudd_GenFree (DdGen *gen)
int Cudd_IsGenEmpty (DdGen *gen)
DdNodeCudd_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)
DdNodePtrcuddNodeArray (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 DdNodebackground
static DdNodezero
static long cuddRand = 0
static long cuddRand2
static long shuffleSelect
static long shuffleTable [STAB_SIZE]

Define Documentation

#define bang (  )     ((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 Documentation

DdNode* Cudd_addComputeCube ( DdManager dd,
DdNode **  vars,
int *  phase,
int  n 
)

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 */

DdNode* Cudd_bddComputeCube ( DdManager dd,
DdNode **  vars,
int *  phase,
int  n 
)

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 */

DdNode** Cudd_bddPickArbitraryMinterms ( DdManager dd,
DdNode f,
DdNode **  vars,
int  n,
int  k 
)

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:

  • It may run out of memory;
  • the function f may be the constant 0;
  • the minterms may not be contained in 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 */

int Cudd_bddPickOneCube ( DdManager ddm,
DdNode node,
char *  string 
)

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 */

DdNode* Cudd_bddPickOneMinterm ( DdManager dd,
DdNode f,
DdNode **  vars,
int  n 
)

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:

  • It may run out of memory;
  • the function f may be the constant 0;
  • the minterm may not be contained in 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 */

int Cudd_bddPrintCover ( DdManager dd,
DdNode l,
DdNode u 
)

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 */

int Cudd_BddToCubeArray ( DdManager dd,
DdNode cube,
int *  array 
)

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 */

double Cudd_CountMinterm ( DdManager manager,
DdNode node,
int  nvars 
)

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 */

DdNode* Cudd_CubeArrayToBdd ( DdManager dd,
int *  array 
)

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 */

double Cudd_Density ( DdManager dd,
DdNode f,
int  nvars 
)

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 */

int Cudd_EpdCountMinterm ( DdManager manager,
DdNode node,
int  nvars,
EpDouble epd 
)

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 */

int Cudd_EstimateCofactor ( DdManager dd,
DdNode f,
int  i,
int  phase 
)

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 */

DdGen* Cudd_FirstCube ( DdManager dd,
DdNode f,
int **  cube,
CUDD_VALUE_TYPE *  value 
)

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 */

DdGen* Cudd_FirstNode ( DdManager dd,
DdNode f,
DdNode **  node 
)

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 */

DdGen* Cudd_FirstPrime ( DdManager dd,
DdNode l,
DdNode u,
int **  cube 
)

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 */

DdNode* Cudd_IndicesToCube ( DdManager dd,
int *  array,
int  n 
)

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 */

int Cudd_NextNode ( DdGen gen,
DdNode **  node 
)

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 */

int Cudd_PrintDebug ( DdManager dd,
DdNode f,
int  n,
int  pr 
)

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:

  • pr = 0 : prints nothing
  • pr = 1 : prints counts of nodes and minterms
  • pr = 2 : prints counts + disjoint sum of product
  • pr = 3 : prints counts + list of nodes
  • pr > 3 : prints counts + disjoint sum of product + list of nodes

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 */

int Cudd_PrintMinterm ( DdManager manager,
DdNode node 
)

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 */

DdNode* Cudd_Support ( DdManager dd,
DdNode f 
)

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 */

int* Cudd_SupportIndex ( DdManager dd,
DdNode f 
)

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 */

int Cudd_SupportSize ( DdManager dd,
DdNode f 
)

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 */

DdNode* Cudd_VectorSupport ( DdManager dd,
DdNode **  F,
int  n 
)

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 */

int* Cudd_VectorSupportIndex ( DdManager dd,
DdNode **  F,
int  n 
)

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 */

int Cudd_VectorSupportSize ( DdManager dd,
DdNode **  F,
int  n 
)

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 */

int cuddCollectNodes ( DdNode f,
st_table visited 
)

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 */

DdNodePtr* cuddNodeArray ( DdNode f,
int *  n 
)

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 */

static int cuddNodeArrayRecur ( DdNode f,
DdNodePtr table,
int  index 
) [static]

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 */

int cuddP ( DdManager dd,
DdNode f 
)

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 */

static DdNode * cuddUniqueLookup ( DdManager unique,
int  index,
DdNode T,
DdNode E 
) [static]

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 */

static double ddCountPathAux ( DdNode node,
st_table table 
) [static]

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 */

static double ddCountPathsToNonZero ( DdNode N,
st_table table 
) [static]

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 */

static void ddPrintMintermAux ( DdManager dd,
DdNode node,
int *  list 
) [static]

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 */

static int dp2 ( DdManager dd,
DdNode f,
st_table t 
) [static]

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 */


Variable Documentation

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.

DdNode * zero [static]

Definition at line 144 of file cuddUtil.c.


Generated on Tue Jan 12 13:57:21 2010 for glu-2.2 by  doxygen 1.6.1