summaryrefslogtreecommitdiffstats
path: root/abc70930/src/bdd/cudd/cuddUtil.c
diff options
context:
space:
mode:
Diffstat (limited to 'abc70930/src/bdd/cudd/cuddUtil.c')
-rw-r--r--abc70930/src/bdd/cudd/cuddUtil.c3633
1 files changed, 0 insertions, 3633 deletions
diff --git a/abc70930/src/bdd/cudd/cuddUtil.c b/abc70930/src/bdd/cudd/cuddUtil.c
deleted file mode 100644
index d5fa18e2..00000000
--- a/abc70930/src/bdd/cudd/cuddUtil.c
+++ /dev/null
@@ -1,3633 +0,0 @@
-/**CFile***********************************************************************
-
- FileName [cuddUtil.c]
-
- PackageName [cudd]
-
- Synopsis [Utility functions.]
-
- Description [External procedures included in this module:
- <ul>
- <li> Cudd_PrintMinterm()
- <li> Cudd_PrintDebug()
- <li> Cudd_DagSize()
- <li> Cudd_EstimateCofactor()
- <li> Cudd_EstimateCofactorSimple()
- <li> Cudd_SharingSize()
- <li> Cudd_CountMinterm()
- <li> Cudd_EpdCountMinterm()
- <li> Cudd_CountPath()
- <li> Cudd_CountPathsToNonZero()
- <li> Cudd_Support()
- <li> Cudd_SupportIndex()
- <li> Cudd_SupportSize()
- <li> Cudd_VectorSupport()
- <li> Cudd_VectorSupportIndex()
- <li> Cudd_VectorSupportSize()
- <li> Cudd_ClassifySupport()
- <li> Cudd_CountLeaves()
- <li> Cudd_bddPickOneCube()
- <li> Cudd_bddPickOneMinterm()
- <li> Cudd_bddPickArbitraryMinterms()
- <li> Cudd_SubsetWithMaskVars()
- <li> Cudd_FirstCube()
- <li> Cudd_NextCube()
- <li> Cudd_bddComputeCube()
- <li> Cudd_addComputeCube()
- <li> Cudd_FirstNode()
- <li> Cudd_NextNode()
- <li> Cudd_GenFree()
- <li> Cudd_IsGenEmpty()
- <li> Cudd_IndicesToCube()
- <li> Cudd_PrintVersion()
- <li> Cudd_AverageDistance()
- <li> Cudd_Random()
- <li> Cudd_Srandom()
- <li> Cudd_Density()
- </ul>
- Internal procedures included in this module:
- <ul>
- <li> cuddP()
- <li> cuddStCountfree()
- <li> cuddCollectNodes()
- </ul>
- Static procedures included in this module:
- <ul>
- <li> dp2()
- <li> ddPrintMintermAux()
- <li> ddDagInt()
- <li> ddCountMintermAux()
- <li> ddEpdCountMintermAux()
- <li> ddCountPathAux()
- <li> ddSupportStep()
- <li> ddClearFlag()
- <li> ddLeavesInt()
- <li> ddPickArbitraryMinterms()
- <li> ddPickRepresentativeCube()
- <li> ddEpdFree()
- </ul>]
-
- Author [Fabio Somenzi]
-
- Copyright [This file was created at the University of Colorado at
- Boulder. The University of Colorado at Boulder makes no warranty
- about the suitability of this software for any purpose. It is
- presented on an AS IS basis.]
-
-******************************************************************************/
-
-#include "util_hack.h"
-#include "cuddInt.h"
-
-/*---------------------------------------------------------------------------*/
-/* Constant declarations */
-/*---------------------------------------------------------------------------*/
-
-/* Random generator constants. */
-#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)
-
-/*---------------------------------------------------------------------------*/
-/* Stucture declarations */
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-/* Type declarations */
-/*---------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------*/
-/* Variable declarations */
-/*---------------------------------------------------------------------------*/
-
-#ifndef lint
-static char rcsid[] DD_UNUSED = "$Id: cuddUtil.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $";
-#endif
-
-static DdNode *background, *zero;
-
-static long cuddRand = 0;
-static long cuddRand2;
-static long shuffleSelect;
-static long shuffleTable[STAB_SIZE];
-
-/*---------------------------------------------------------------------------*/
-/* Macro declarations */
-/*---------------------------------------------------------------------------*/
-
-#define bang(f) ((Cudd_IsComplement(f)) ? '!' : ' ')
-
-/**AutomaticStart*************************************************************/
-
-/*---------------------------------------------------------------------------*/
-/* Static function prototypes */
-/*---------------------------------------------------------------------------*/
-
-static int dp2 ARGS((DdManager *dd, DdNode *f, st_table *t));
-static void ddPrintMintermAux ARGS((DdManager *dd, DdNode *node, int *list));
-static int ddDagInt ARGS((DdNode *n));
-static int cuddEstimateCofactor ARGS((DdManager *dd, st_table *table, DdNode * node, int i, int phase, DdNode ** ptr));
-static DdNode * cuddUniqueLookup ARGS((DdManager * unique, int index, DdNode * T, DdNode * E));
-static int cuddEstimateCofactorSimple ARGS((DdNode * node, int i));
-static double ddCountMintermAux ARGS((DdNode *node, double max, DdHashTable *table));
-static int ddEpdCountMintermAux ARGS((DdNode *node, EpDouble *max, EpDouble *epd, st_table *table));
-static double ddCountPathAux ARGS((DdNode *node, st_table *table));
-static double ddCountPathsToNonZero ARGS((DdNode * N, st_table * table));
-static void ddSupportStep ARGS((DdNode *f, int *support));
-static void ddClearFlag ARGS((DdNode *f));
-static int ddLeavesInt ARGS((DdNode *n));
-static int ddPickArbitraryMinterms ARGS((DdManager *dd, DdNode *node, int nvars, int nminterms, char **string));
-static int ddPickRepresentativeCube ARGS((DdManager *dd, DdNode *node, int nvars, double *weight, char *string));
-static enum st_retval ddEpdFree ARGS((char * key, char * value, char * arg));
-
-/**AutomaticEnd***************************************************************/
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of exported functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_PrintMinterm(
- DdManager * manager,
- DdNode * node)
-{
- int i, *list;
-
- background = manager->background;
- zero = Cudd_Not(manager->one);
- list = ALLOC(int,manager->size);
- if (list == NULL) {
- manager->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- for (i = 0; i < manager->size; i++) list[i] = 2;
- ddPrintMintermAux(manager,node,list);
- FREE(list);
- return(1);
-
-} /* end of Cudd_PrintMinterm */
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_bddPrintCover(
- DdManager *dd,
- DdNode *l,
- DdNode *u)
-{
- int *array;
- int q, result;
- DdNode *lb;
-#ifdef DD_DEBUG
- DdNode *cover;
-#endif
-
- array = ALLOC(int, Cudd_ReadSize(dd));
- if (array == NULL) return(0);
- lb = l;
- cuddRef(lb);
-#ifdef DD_DEBUG
- cover = Cudd_ReadLogicZero(dd);
- cuddRef(cover);
-#endif
- while (lb != Cudd_ReadLogicZero(dd)) {
- DdNode *implicant, *prime, *tmp;
- int length;
- implicant = Cudd_LargestCube(dd,lb,&length);
- if (implicant == NULL) {
- Cudd_RecursiveDeref(dd,lb);
- FREE(array);
- return(0);
- }
- cuddRef(implicant);
- prime = Cudd_bddMakePrime(dd,implicant,u);
- if (prime == NULL) {
- Cudd_RecursiveDeref(dd,lb);
- Cudd_RecursiveDeref(dd,implicant);
- FREE(array);
- return(0);
- }
- cuddRef(prime);
- Cudd_RecursiveDeref(dd,implicant);
- tmp = Cudd_bddAnd(dd,lb,Cudd_Not(prime));
- if (tmp == NULL) {
- Cudd_RecursiveDeref(dd,lb);
- Cudd_RecursiveDeref(dd,prime);
- FREE(array);
- return(0);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,lb);
- lb = tmp;
- result = Cudd_BddToCubeArray(dd,prime,array);
- if (result == 0) {
- Cudd_RecursiveDeref(dd,lb);
- Cudd_RecursiveDeref(dd,prime);
- FREE(array);
- return(0);
- }
- for (q = 0; q < dd->size; q++) {
- switch (array[q]) {
- case 0:
- (void) fprintf(dd->out, "0");
- break;
- case 1:
- (void) fprintf(dd->out, "1");
- break;
- case 2:
- (void) fprintf(dd->out, "-");
- break;
- default:
- (void) fprintf(dd->out, "?");
- }
- }
- (void) fprintf(dd->out, " 1\n");
-#ifdef DD_DEBUG
- tmp = Cudd_bddOr(dd,prime,cover);
- if (tmp == NULL) {
- Cudd_RecursiveDeref(dd,cover);
- Cudd_RecursiveDeref(dd,lb);
- Cudd_RecursiveDeref(dd,prime);
- FREE(array);
- return(0);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,cover);
- cover = tmp;
-#endif
- Cudd_RecursiveDeref(dd,prime);
- }
- (void) fprintf(dd->out, "\n");
- Cudd_RecursiveDeref(dd,lb);
- FREE(array);
-#ifdef DD_DEBUG
- if (!Cudd_bddLeq(dd,cover,u) || !Cudd_bddLeq(dd,l,cover)) {
- Cudd_RecursiveDeref(dd,cover);
- return(0);
- }
- Cudd_RecursiveDeref(dd,cover);
-#endif
- return(1);
-
-} /* end of Cudd_bddPrintCover */
-
-
-/**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 &gt; 0. Specifically:
- <ul>
- <li> pr = 0 : prints nothing
- <li> pr = 1 : prints counts of nodes and minterms
- <li> pr = 2 : prints counts + disjoint sum of product
- <li> pr = 3 : prints counts + list of nodes
- <li> pr &gt; 3 : prints counts + disjoint sum of product + list of nodes
- </ul>
- 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]
-
-******************************************************************************/
-int
-Cudd_PrintDebug(
- DdManager * dd,
- DdNode * f,
- int n,
- int pr)
-{
- DdNode *azero, *bzero;
- int nodes;
- int leaves;
- double minterms;
- int retval = 1;
-
- if (f == NULL) {
- (void) fprintf(dd->out,": is the NULL DD\n");
- (void) fflush(dd->out);
- return(0);
- }
- azero = DD_ZERO(dd);
- bzero = Cudd_Not(DD_ONE(dd));
- if ((f == azero || f == bzero) && pr > 0){
- (void) fprintf(dd->out,": is the zero DD\n");
- (void) fflush(dd->out);
- return(1);
- }
- if (pr > 0) {
- nodes = Cudd_DagSize(f);
- if (nodes == CUDD_OUT_OF_MEM) retval = 0;
- leaves = Cudd_CountLeaves(f);
- if (leaves == CUDD_OUT_OF_MEM) retval = 0;
- minterms = Cudd_CountMinterm(dd, f, n);
- if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0;
- (void) fprintf(dd->out,": %d nodes %d leaves %g minterms\n",
- nodes, leaves, minterms);
- if (pr > 2) {
- if (!cuddP(dd, f)) retval = 0;
- }
- if (pr == 2 || pr > 3) {
- if (!Cudd_PrintMinterm(dd,f)) retval = 0;
- (void) fprintf(dd->out,"\n");
- }
- (void) fflush(dd->out);
- }
- return(retval);
-
-} /* end of Cudd_PrintDebug */
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_DagSize(
- DdNode * node)
-{
- int i;
-
- i = ddDagInt(Cudd_Regular(node));
- ddClearFlag(Cudd_Regular(node));
-
- return(i);
-
-} /* end of Cudd_DagSize */
-
-
-/**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 itmay 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]
-
-******************************************************************************/
-int
-Cudd_EstimateCofactor(
- DdManager *dd /* manager */,
- DdNode * f /* function */,
- int i /* index of variable */,
- int phase /* 1: positive; 0: negative */
- )
-{
- int val;
- DdNode *ptr;
- st_table *table;
-
- table = st_init_table(st_ptrcmp,st_ptrhash);
- if (table == NULL) return(CUDD_OUT_OF_MEM);
- val = cuddEstimateCofactor(dd,table,Cudd_Regular(f),i,phase,&ptr);
- ddClearFlag(Cudd_Regular(f));
- st_free_table(table);
-
- return(val);
-
-} /* end of Cudd_EstimateCofactor */
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_EstimateCofactorSimple(
- DdNode * node,
- int i)
-{
- int val;
-
- val = cuddEstimateCofactorSimple(Cudd_Regular(node),i);
- ddClearFlag(Cudd_Regular(node));
-
- return(val);
-
-} /* end of Cudd_EstimateCofactorSimple */
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_SharingSize(
- DdNode ** nodeArray,
- int n)
-{
- int i,j;
-
- i = 0;
- for (j = 0; j < n; j++) {
- i += ddDagInt(Cudd_Regular(nodeArray[j]));
- }
- for (j = 0; j < n; j++) {
- ddClearFlag(Cudd_Regular(nodeArray[j]));
- }
- return(i);
-
-} /* end of Cudd_SharingSize */
-
-
-/**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]
-
-******************************************************************************/
-double
-Cudd_CountMinterm(
- DdManager * manager,
- DdNode * node,
- int nvars)
-{
- double max;
- DdHashTable *table;
- double res;
- CUDD_VALUE_TYPE epsilon;
-
- background = manager->background;
- zero = Cudd_Not(manager->one);
-
- max = pow(2.0,(double)nvars);
- table = cuddHashTableInit(manager,1,2);
- if (table == NULL) {
- return((double)CUDD_OUT_OF_MEM);
- }
- epsilon = Cudd_ReadEpsilon(manager);
- Cudd_SetEpsilon(manager,(CUDD_VALUE_TYPE)0.0);
- res = ddCountMintermAux(node,max,table);
- cuddHashTableQuit(table);
- Cudd_SetEpsilon(manager,epsilon);
-
- return(res);
-
-} /* end of Cudd_CountMinterm */
-
-
-/**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]
-
-******************************************************************************/
-double
-Cudd_CountPath(
- DdNode * node)
-{
-
- st_table *table;
- double i;
-
- table = st_init_table(st_ptrcmp,st_ptrhash);
- if (table == NULL) {
- return((double)CUDD_OUT_OF_MEM);
- }
- i = ddCountPathAux(Cudd_Regular(node),table);
- st_foreach(table, cuddStCountfree, NULL);
- st_free_table(table);
- return(i);
-
-} /* end of Cudd_CountPath */
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_EpdCountMinterm(
- DdManager * manager,
- DdNode * node,
- int nvars,
- EpDouble * epd)
-{
- EpDouble max, tmp;
- st_table *table;
- int status;
-
- background = manager->background;
- zero = Cudd_Not(manager->one);
-
- EpdPow2(nvars, &max);
- table = st_init_table(EpdCmp, st_ptrhash);
- if (table == NULL) {
- EpdMakeZero(epd, 0);
- return(CUDD_OUT_OF_MEM);
- }
- status = ddEpdCountMintermAux(Cudd_Regular(node),&max,epd,table);
- st_foreach(table, ddEpdFree, NULL);
- st_free_table(table);
- if (status == CUDD_OUT_OF_MEM) {
- EpdMakeZero(epd, 0);
- return(CUDD_OUT_OF_MEM);
- }
- if (Cudd_IsComplement(node)) {
- EpdSubtract3(&max, epd, &tmp);
- EpdCopy(&tmp, epd);
- }
- return(0);
-
-} /* end of Cudd_EpdCountMinterm */
-
-
-/**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]
-
-******************************************************************************/
-double
-Cudd_CountPathsToNonZero(
- DdNode * node)
-{
-
- st_table *table;
- double i;
-
- table = st_init_table(st_ptrcmp,st_ptrhash);
- if (table == NULL) {
- return((double)CUDD_OUT_OF_MEM);
- }
- i = ddCountPathsToNonZero(node,table);
- st_foreach(table, cuddStCountfree, NULL);
- st_free_table(table);
- return(i);
-
-} /* end of Cudd_CountPathsToNonZero */
-
-
-/**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]
-
-******************************************************************************/
-DdNode *
-Cudd_Support(
- DdManager * dd /* manager */,
- DdNode * f /* DD whose support is sought */)
-{
- int *support;
- DdNode *res, *tmp, *var;
- int i,j;
- int size;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- support = ALLOC(int,size);
- if (support == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < size; i++) {
- support[i] = 0;
- }
-
- /* Compute support and clean up markers. */
- ddSupportStep(Cudd_Regular(f),support);
- ddClearFlag(Cudd_Regular(f));
-
- /* Transform support from array to cube. */
- do {
- dd->reordered = 0;
- res = DD_ONE(dd);
- cuddRef(res);
- for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */
- i = (j >= dd->size) ? j : dd->invperm[j];
- if (support[i] == 1) {
- var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one));
- cuddRef(var);
- tmp = cuddBddAndRecur(dd,res,var);
- if (tmp == NULL) {
- Cudd_RecursiveDeref(dd,res);
- Cudd_RecursiveDeref(dd,var);
- res = NULL;
- break;
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,res);
- Cudd_RecursiveDeref(dd,var);
- res = tmp;
- }
- }
- } while (dd->reordered == 1);
-
- FREE(support);
- if (res != NULL) cuddDeref(res);
- return(res);
-
-} /* end of Cudd_Support */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the variables on which a DD depends.]
-
- Description [Finds the variables on which a DD depends.
- Returns an index array of the variables if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Support Cudd_VectorSupport Cudd_ClassifySupport]
-
-******************************************************************************/
-int *
-Cudd_SupportIndex(
- DdManager * dd /* manager */,
- DdNode * f /* DD whose support is sought */)
-{
- int *support;
- int i;
- int size;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- support = ALLOC(int,size);
- if (support == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < size; i++) {
- support[i] = 0;
- }
-
- /* Compute support and clean up markers. */
- ddSupportStep(Cudd_Regular(f),support);
- ddClearFlag(Cudd_Regular(f));
-
- return(support);
-
-} /* end of Cudd_SupportIndex */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the variables on which a DD depends.]
-
- Description [Counts the variables on which a DD depends.
- Returns the number of the variables if successful; CUDD_OUT_OF_MEM
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Support]
-
-******************************************************************************/
-int
-Cudd_SupportSize(
- DdManager * dd /* manager */,
- DdNode * f /* DD whose support size is sought */)
-{
- int *support;
- int i;
- int size;
- int count;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- support = ALLOC(int,size);
- if (support == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(CUDD_OUT_OF_MEM);
- }
- for (i = 0; i < size; i++) {
- support[i] = 0;
- }
-
- /* Compute support and clean up markers. */
- ddSupportStep(Cudd_Regular(f),support);
- ddClearFlag(Cudd_Regular(f));
-
- /* Count support variables. */
- count = 0;
- for (i = 0; i < size; i++) {
- if (support[i] == 1) count++;
- }
-
- FREE(support);
- return(count);
-
-} /* end of Cudd_SupportSize */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the variables on which a set of DDs depends.]
-
- Description [Finds the variables on which a set of DDs depends.
- The set must contain either BDDs and ADDs, or ZDDs.
- Returns a BDD consisting of the product of the variables if
- successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_Support Cudd_ClassifySupport]
-
-******************************************************************************/
-DdNode *
-Cudd_VectorSupport(
- DdManager * dd /* manager */,
- DdNode ** F /* array of DDs whose support is sought */,
- int n /* size of the array */)
-{
- int *support;
- DdNode *res, *tmp, *var;
- int i,j;
- int size;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- support = ALLOC(int,size);
- if (support == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < size; i++) {
- support[i] = 0;
- }
-
- /* Compute support and clean up markers. */
- for (i = 0; i < n; i++) {
- ddSupportStep(Cudd_Regular(F[i]),support);
- }
- for (i = 0; i < n; i++) {
- ddClearFlag(Cudd_Regular(F[i]));
- }
-
- /* Transform support from array to cube. */
- res = DD_ONE(dd);
- cuddRef(res);
- for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */
- i = (j >= dd->size) ? j : dd->invperm[j];
- if (support[i] == 1) {
- var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one));
- cuddRef(var);
- tmp = Cudd_bddAnd(dd,res,var);
- if (tmp == NULL) {
- Cudd_RecursiveDeref(dd,res);
- Cudd_RecursiveDeref(dd,var);
- FREE(support);
- return(NULL);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,res);
- Cudd_RecursiveDeref(dd,var);
- res = tmp;
- }
- }
-
- FREE(support);
- cuddDeref(res);
- return(res);
-
-} /* end of Cudd_VectorSupport */
-
-
-/**Function********************************************************************
-
- Synopsis [Finds the variables on which a set of DDs depends.]
-
- Description [Finds the variables on which a set of DDs depends.
- The set must contain either BDDs and ADDs, or ZDDs.
- Returns an index array of the variables if successful; NULL otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_SupportIndex Cudd_VectorSupport Cudd_ClassifySupport]
-
-******************************************************************************/
-int *
-Cudd_VectorSupportIndex(
- DdManager * dd /* manager */,
- DdNode ** F /* array of DDs whose support is sought */,
- int n /* size of the array */)
-{
- int *support;
- int i;
- int size;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- support = ALLOC(int,size);
- if (support == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < size; i++) {
- support[i] = 0;
- }
-
- /* Compute support and clean up markers. */
- for (i = 0; i < n; i++) {
- ddSupportStep(Cudd_Regular(F[i]),support);
- }
- for (i = 0; i < n; i++) {
- ddClearFlag(Cudd_Regular(F[i]));
- }
-
- return(support);
-
-} /* end of Cudd_VectorSupportIndex */
-
-
-/**Function********************************************************************
-
- Synopsis [Counts the variables on which a set of DDs depends.]
-
- Description [Counts the variables on which a set of DDs depends.
- The set must contain either BDDs and ADDs, or ZDDs.
- Returns the number of the variables if successful; CUDD_OUT_OF_MEM
- otherwise.]
-
- SideEffects [None]
-
- SeeAlso [Cudd_VectorSupport Cudd_SupportSize]
-
-******************************************************************************/
-int
-Cudd_VectorSupportSize(
- DdManager * dd /* manager */,
- DdNode ** F /* array of DDs whose support is sought */,
- int n /* size of the array */)
-{
- int *support;
- int i;
- int size;
- int count;
-
- /* Allocate and initialize support array for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- support = ALLOC(int,size);
- if (support == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(CUDD_OUT_OF_MEM);
- }
- for (i = 0; i < size; i++) {
- support[i] = 0;
- }
-
- /* Compute support and clean up markers. */
- for (i = 0; i < n; i++) {
- ddSupportStep(Cudd_Regular(F[i]),support);
- }
- for (i = 0; i < n; i++) {
- ddClearFlag(Cudd_Regular(F[i]));
- }
-
- /* Count vriables in support. */
- count = 0;
- for (i = 0; i < size; i++) {
- if (support[i] == 1) count++;
- }
-
- FREE(support);
- return(count);
-
-} /* end of Cudd_VectorSupportSize */
-
-
-/**Function********************************************************************
-
- Synopsis [Classifies the variables in the support of two DDs.]
-
- Description [Classifies the variables in the support of two DDs
- <code>f</code> and <code>g</code>, depending on whther they appear
- in both DDs, only in <code>f</code>, or only in <code>g</code>.
- 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]
-
-******************************************************************************/
-int
-Cudd_ClassifySupport(
- DdManager * dd /* manager */,
- DdNode * f /* first DD */,
- DdNode * g /* second DD */,
- DdNode ** common /* cube of shared variables */,
- DdNode ** onlyF /* cube of variables only in f */,
- DdNode ** onlyG /* cube of variables only in g */)
-{
- int *supportF, *supportG;
- DdNode *tmp, *var;
- int i,j;
- int size;
-
- /* Allocate and initialize support arrays for ddSupportStep. */
- size = ddMax(dd->size, dd->sizeZ);
- supportF = ALLOC(int,size);
- if (supportF == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(0);
- }
- supportG = ALLOC(int,size);
- if (supportG == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(supportF);
- return(0);
- }
- for (i = 0; i < size; i++) {
- supportF[i] = 0;
- supportG[i] = 0;
- }
-
- /* Compute supports and clean up markers. */
- ddSupportStep(Cudd_Regular(f),supportF);
- ddClearFlag(Cudd_Regular(f));
- ddSupportStep(Cudd_Regular(g),supportG);
- ddClearFlag(Cudd_Regular(g));
-
- /* Classify variables and create cubes. */
- *common = *onlyF = *onlyG = DD_ONE(dd);
- cuddRef(*common); cuddRef(*onlyF); cuddRef(*onlyG);
- for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */
- i = (j >= dd->size) ? j : dd->invperm[j];
- if (supportF[i] == 0 && supportG[i] == 0) continue;
- var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one));
- cuddRef(var);
- if (supportG[i] == 0) {
- tmp = Cudd_bddAnd(dd,*onlyF,var);
- if (tmp == NULL) {
- Cudd_RecursiveDeref(dd,*common);
- Cudd_RecursiveDeref(dd,*onlyF);
- Cudd_RecursiveDeref(dd,*onlyG);
- Cudd_RecursiveDeref(dd,var);
- FREE(supportF); FREE(supportG);
- return(0);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,*onlyF);
- *onlyF = tmp;
- } else if (supportF[i] == 0) {
- tmp = Cudd_bddAnd(dd,*onlyG,var);
- if (tmp == NULL) {
- Cudd_RecursiveDeref(dd,*common);
- Cudd_RecursiveDeref(dd,*onlyF);
- Cudd_RecursiveDeref(dd,*onlyG);
- Cudd_RecursiveDeref(dd,var);
- FREE(supportF); FREE(supportG);
- return(0);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,*onlyG);
- *onlyG = tmp;
- } else {
- tmp = Cudd_bddAnd(dd,*common,var);
- if (tmp == NULL) {
- Cudd_RecursiveDeref(dd,*common);
- Cudd_RecursiveDeref(dd,*onlyF);
- Cudd_RecursiveDeref(dd,*onlyG);
- Cudd_RecursiveDeref(dd,var);
- FREE(supportF); FREE(supportG);
- return(0);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,*common);
- *common = tmp;
- }
- Cudd_RecursiveDeref(dd,var);
- }
-
- FREE(supportF); FREE(supportG);
- cuddDeref(*common); cuddDeref(*onlyF); cuddDeref(*onlyG);
- return(1);
-
-} /* end of Cudd_ClassifySupport */
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_CountLeaves(
- DdNode * node)
-{
- int i;
-
- i = ddLeavesInt(Cudd_Regular(node));
- ddClearFlag(Cudd_Regular(node));
- return(i);
-
-} /* end of Cudd_CountLeaves */
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_bddPickOneCube(
- DdManager * ddm,
- DdNode * node,
- char * string)
-{
- DdNode *N, *T, *E;
- DdNode *one, *bzero;
- char dir;
- int i;
-
- if (string == NULL || node == NULL) return(0);
-
- /* The constant 0 function has no on-set cubes. */
- one = DD_ONE(ddm);
- bzero = Cudd_Not(one);
- if (node == bzero) return(0);
-
- for (i = 0; i < ddm->size; i++) string[i] = 2;
-
- for (;;) {
-
- if (node == one) break;
-
- N = Cudd_Regular(node);
-
- T = cuddT(N); E = cuddE(N);
- if (Cudd_IsComplement(node)) {
- T = Cudd_Not(T); E = Cudd_Not(E);
- }
- if (T == bzero) {
- string[N->index] = 0;
- node = E;
- } else if (E == bzero) {
- string[N->index] = 1;
- node = T;
- } else {
- dir = (char) ((Cudd_Random() & 0x2000) >> 13);
- string[N->index] = dir;
- node = dir ? T : E;
- }
- }
- return(1);
-
-} /* end of Cudd_bddPickOneCube */
-
-
-/**Function********************************************************************
-
- Synopsis [Picks one on-set minterm randomly from the given DD.]
-
- Description [Picks one on-set minterm randomly from the given
- DD. The minterm is in terms of <code>vars</code>. The array
- <code>vars</code> should contain at least all variables in the
- support of <code>f</code>; if this condition is not met the minterm
- built by this procedure may not be contained in
- <code>f</code>. 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:
- <ul>
- <li> It may run out of memory;
- <li> the function <code>f</code> may be the constant 0;
- <li> the minterm may not be contained in <code>f</code>.
- </ul>]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddPickOneCube]
-
-******************************************************************************/
-DdNode *
-Cudd_bddPickOneMinterm(
- DdManager * dd /* manager */,
- DdNode * f /* function from which to pick one minterm */,
- DdNode ** vars /* array of variables */,
- int n /* size of <code>vars</code> */)
-{
- char *string;
- int i, size;
- int *indices;
- int result;
- DdNode *old, *neW;
-
- size = dd->size;
- string = ALLOC(char, size);
- if (string == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- indices = ALLOC(int,n);
- if (indices == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(string);
- return(NULL);
- }
-
- for (i = 0; i < n; i++) {
- indices[i] = vars[i]->index;
- }
-
- result = Cudd_bddPickOneCube(dd,f,string);
- if (result == 0) {
- FREE(string);
- FREE(indices);
- return(NULL);
- }
-
- /* Randomize choice for don't cares. */
- for (i = 0; i < n; i++) {
- if (string[indices[i]] == 2)
- string[indices[i]] = (char) ((Cudd_Random() & 0x20) >> 5);
- }
-
- /* Build result BDD. */
- old = Cudd_ReadOne(dd);
- cuddRef(old);
-
- for (i = n-1; i >= 0; i--) {
- neW = Cudd_bddAnd(dd,old,Cudd_NotCond(vars[i],string[indices[i]]==0));
- if (neW == NULL) {
- FREE(string);
- FREE(indices);
- Cudd_RecursiveDeref(dd,old);
- return(NULL);
- }
- cuddRef(neW);
- Cudd_RecursiveDeref(dd,old);
- old = neW;
- }
-
-#ifdef DD_DEBUG
- /* Test. */
- if (Cudd_bddLeq(dd,old,f)) {
- cuddDeref(old);
- } else {
- Cudd_RecursiveDeref(dd,old);
- old = NULL;
- }
-#else
- cuddDeref(old);
-#endif
-
- FREE(string);
- FREE(indices);
- return(old);
-
-} /* end of Cudd_bddPickOneMinterm */
-
-
-/**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 <code>vars</code>. The array
- <code>vars</code> should contain at least all variables in the
- support of <code>f</code>; if this condition is not met the minterms
- built by this procedure may not be contained in
- <code>f</code>. 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:
- <ul>
- <li> It may run out of memory;
- <li> the function <code>f</code> may be the constant 0;
- <li> the minterms may not be contained in <code>f</code>.
- </ul>]
-
- SideEffects [None]
-
- SeeAlso [Cudd_bddPickOneMinterm Cudd_bddPickOneCube]
-
-******************************************************************************/
-DdNode **
-Cudd_bddPickArbitraryMinterms(
- DdManager * dd /* manager */,
- DdNode * f /* function from which to pick k minterms */,
- DdNode ** vars /* array of variables */,
- int n /* size of <code>vars</code> */,
- int k /* number of minterms to find */)
-{
- char **string;
- int i, j, l, size;
- int *indices;
- int result;
- DdNode **old, *neW;
- double minterms;
- char *saveString;
- int saveFlag, savePoint, isSame;
-
- minterms = Cudd_CountMinterm(dd,f,n);
- if ((double)k > minterms) {
- return(NULL);
- }
-
- size = dd->size;
- string = ALLOC(char *, k);
- if (string == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < k; i++) {
- string[i] = ALLOC(char, size + 1);
- if (string[i] == NULL) {
- for (j = 0; j < i; j++)
- FREE(string[i]);
- FREE(string);
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (j = 0; j < size; j++) string[i][j] = '2';
- string[i][size] = '\0';
- }
- indices = ALLOC(int,n);
- if (indices == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- for (i = 0; i < k; i++)
- FREE(string[i]);
- FREE(string);
- return(NULL);
- }
-
- for (i = 0; i < n; i++) {
- indices[i] = vars[i]->index;
- }
-
- result = ddPickArbitraryMinterms(dd,f,n,k,string);
- if (result == 0) {
- for (i = 0; i < k; i++)
- FREE(string[i]);
- FREE(string);
- FREE(indices);
- return(NULL);
- }
-
- old = ALLOC(DdNode *, k);
- if (old == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- for (i = 0; i < k; i++)
- FREE(string[i]);
- FREE(string);
- FREE(indices);
- return(NULL);
- }
- saveString = ALLOC(char, size + 1);
- if (saveString == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- for (i = 0; i < k; i++)
- FREE(string[i]);
- FREE(string);
- FREE(indices);
- FREE(old);
- return(NULL);
- }
- saveFlag = 0;
-
- /* Build result BDD array. */
- for (i = 0; i < k; i++) {
- isSame = 0;
- if (!saveFlag) {
- for (j = i + 1; j < k; j++) {
- if (strcmp(string[i], string[j]) == 0) {
- savePoint = i;
- strcpy(saveString, string[i]);
- saveFlag = 1;
- break;
- }
- }
- } else {
- if (strcmp(string[i], saveString) == 0) {
- isSame = 1;
- } else {
- saveFlag = 0;
- for (j = i + 1; j < k; j++) {
- if (strcmp(string[i], string[j]) == 0) {
- savePoint = i;
- strcpy(saveString, string[i]);
- saveFlag = 1;
- break;
- }
- }
- }
- }
- /* Randomize choice for don't cares. */
- for (j = 0; j < n; j++) {
- if (string[i][indices[j]] == '2')
- string[i][indices[j]] = (Cudd_Random() & 0x20) ? '1' : '0';
- }
-
- while (isSame) {
- isSame = 0;
- for (j = savePoint; j < i; j++) {
- if (strcmp(string[i], string[j]) == 0) {
- isSame = 1;
- break;
- }
- }
- if (isSame) {
- strcpy(string[i], saveString);
- /* Randomize choice for don't cares. */
- for (j = 0; j < n; j++) {
- if (string[i][indices[j]] == '2')
- string[i][indices[j]] = (Cudd_Random() & 0x20) ?
- '1' : '0';
- }
- }
- }
-
- old[i] = Cudd_ReadOne(dd);
- cuddRef(old[i]);
-
- for (j = 0; j < n; j++) {
- if (string[i][indices[j]] == '0') {
- neW = Cudd_bddAnd(dd,old[i],Cudd_Not(vars[j]));
- } else {
- neW = Cudd_bddAnd(dd,old[i],vars[j]);
- }
- if (neW == NULL) {
- FREE(saveString);
- for (l = 0; l < k; l++)
- FREE(string[l]);
- FREE(string);
- FREE(indices);
- for (l = 0; l <= i; l++)
- Cudd_RecursiveDeref(dd,old[l]);
- FREE(old);
- return(NULL);
- }
- cuddRef(neW);
- Cudd_RecursiveDeref(dd,old[i]);
- old[i] = neW;
- }
-
- /* Test. */
- if (!Cudd_bddLeq(dd,old[i],f)) {
- FREE(saveString);
- for (l = 0; l < k; l++)
- FREE(string[l]);
- FREE(string);
- FREE(indices);
- for (l = 0; l <= i; l++)
- Cudd_RecursiveDeref(dd,old[l]);
- FREE(old);
- return(NULL);
- }
- }
-
- FREE(saveString);
- for (i = 0; i < k; i++) {
- cuddDeref(old[i]);
- FREE(string[i]);
- }
- FREE(string);
- FREE(indices);
- return(old);
-
-} /* end of Cudd_bddPickArbitraryMinterms */
-
-
-/**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 []
-
-******************************************************************************/
-DdNode *
-Cudd_SubsetWithMaskVars(
- DdManager * dd /* manager */,
- DdNode * f /* function from which to pick a cube */,
- DdNode ** vars /* array of variables */,
- int nvars /* size of <code>vars</code> */,
- DdNode ** maskVars /* array of variables */,
- int mvars /* size of <code>maskVars</code> */)
-{
- double *weight;
- char *string;
- int i, size;
- int *indices, *mask;
- int result;
- DdNode *zero, *cube, *newCube, *subset;
- DdNode *cof;
-
- DdNode *support;
- support = Cudd_Support(dd,f);
- cuddRef(support);
- Cudd_RecursiveDeref(dd,support);
-
- zero = Cudd_Not(dd->one);
- size = dd->size;
-
- weight = ALLOC(double,size);
- if (weight == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- for (i = 0; i < size; i++) {
- weight[i] = 0.0;
- }
- for (i = 0; i < mvars; i++) {
- cof = Cudd_Cofactor(dd, f, maskVars[i]);
- cuddRef(cof);
- weight[i] = Cudd_CountMinterm(dd, cof, nvars);
- Cudd_RecursiveDeref(dd,cof);
-
- cof = Cudd_Cofactor(dd, f, Cudd_Not(maskVars[i]));
- cuddRef(cof);
- weight[i] -= Cudd_CountMinterm(dd, cof, nvars);
- Cudd_RecursiveDeref(dd,cof);
- }
-
- string = ALLOC(char, size + 1);
- if (string == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
- mask = ALLOC(int, size);
- if (mask == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(string);
- return(NULL);
- }
- for (i = 0; i < size; i++) {
- string[i] = '2';
- mask[i] = 0;
- }
- string[size] = '\0';
- indices = ALLOC(int,nvars);
- if (indices == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(string);
- FREE(mask);
- return(NULL);
- }
- for (i = 0; i < nvars; i++) {
- indices[i] = vars[i]->index;
- }
-
- result = ddPickRepresentativeCube(dd,f,nvars,weight,string);
- if (result == 0) {
- FREE(string);
- FREE(mask);
- FREE(indices);
- return(NULL);
- }
-
- cube = Cudd_ReadOne(dd);
- cuddRef(cube);
- zero = Cudd_Not(Cudd_ReadOne(dd));
- for (i = 0; i < nvars; i++) {
- if (string[indices[i]] == '0') {
- newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero);
- } else if (string[indices[i]] == '1') {
- newCube = Cudd_bddIte(dd,cube,vars[i],zero);
- } else
- continue;
- if (newCube == NULL) {
- FREE(string);
- FREE(mask);
- FREE(indices);
- Cudd_RecursiveDeref(dd,cube);
- return(NULL);
- }
- cuddRef(newCube);
- Cudd_RecursiveDeref(dd,cube);
- cube = newCube;
- }
- Cudd_RecursiveDeref(dd,cube);
-
- for (i = 0; i < mvars; i++) {
- mask[maskVars[i]->index] = 1;
- }
- for (i = 0; i < nvars; i++) {
- if (mask[indices[i]]) {
- if (string[indices[i]] == '2') {
- if (weight[indices[i]] >= 0.0)
- string[indices[i]] = '1';
- else
- string[indices[i]] = '0';
- }
- } else {
- string[indices[i]] = '2';
- }
- }
-
- cube = Cudd_ReadOne(dd);
- cuddRef(cube);
- zero = Cudd_Not(Cudd_ReadOne(dd));
-
- /* Build result BDD. */
- for (i = 0; i < nvars; i++) {
- if (string[indices[i]] == '0') {
- newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero);
- } else if (string[indices[i]] == '1') {
- newCube = Cudd_bddIte(dd,cube,vars[i],zero);
- } else
- continue;
- if (newCube == NULL) {
- FREE(string);
- FREE(mask);
- FREE(indices);
- Cudd_RecursiveDeref(dd,cube);
- return(NULL);
- }
- cuddRef(newCube);
- Cudd_RecursiveDeref(dd,cube);
- cube = newCube;
- }
-
- subset = Cudd_bddAnd(dd,f,cube);
- cuddRef(subset);
- Cudd_RecursiveDeref(dd,cube);
-
- /* Test. */
- if (Cudd_bddLeq(dd,subset,f)) {
- cuddDeref(subset);
- } else {
- Cudd_RecursiveDeref(dd,subset);
- subset = NULL;
- }
-
- FREE(string);
- FREE(mask);
- FREE(indices);
- FREE(weight);
- return(subset);
-
-} /* end of Cudd_SubsetWithMaskVars */
-
-
-/**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.<p>
- 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.<p>
- 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]
-
-******************************************************************************/
-DdGen *
-Cudd_FirstCube(
- DdManager * dd,
- DdNode * f,
- int ** cube,
- CUDD_VALUE_TYPE * value)
-{
- DdGen *gen;
- DdNode *top, *treg, *next, *nreg, *prev, *preg;
- int i;
- int nvars;
-
- /* Sanity Check. */
- if (dd == NULL || f == NULL) return(NULL);
-
- /* Allocate generator an initialize it. */
- gen = ALLOC(DdGen,1);
- if (gen == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
-
- gen->manager = dd;
- gen->type = CUDD_GEN_CUBES;
- gen->status = CUDD_GEN_EMPTY;
- gen->gen.cubes.cube = NULL;
- gen->gen.cubes.value = DD_ZERO_VAL;
- gen->stack.sp = 0;
- gen->stack.stack = NULL;
- gen->node = NULL;
-
- nvars = dd->size;
- gen->gen.cubes.cube = ALLOC(int,nvars);
- if (gen->gen.cubes.cube == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(gen);
- return(NULL);
- }
- for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2;
-
- /* The maximum stack depth is one plus the number of variables.
- ** because a path may have nodes at all levels, including the
- ** constant level.
- */
- gen->stack.stack = ALLOC(DdNode *, nvars+1);
- if (gen->stack.stack == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- FREE(gen->gen.cubes.cube);
- FREE(gen);
- return(NULL);
- }
- for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL;
-
- /* Find the first cube of the onset. */
- gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++;
-
- while (1) {
- top = gen->stack.stack[gen->stack.sp-1];
- treg = Cudd_Regular(top);
- if (!cuddIsConstant(treg)) {
- /* Take the else branch first. */
- gen->gen.cubes.cube[treg->index] = 0;
- next = cuddE(treg);
- if (top != treg) next = Cudd_Not(next);
- gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++;
- } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) {
- /* Backtrack */
- while (1) {
- if (gen->stack.sp == 1) {
- /* The current node has no predecessor. */
- gen->status = CUDD_GEN_EMPTY;
- gen->stack.sp--;
- goto done;
- }
- prev = gen->stack.stack[gen->stack.sp-2];
- preg = Cudd_Regular(prev);
- nreg = cuddT(preg);
- if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;}
- if (next != top) { /* follow the then branch next */
- gen->gen.cubes.cube[preg->index] = 1;
- gen->stack.stack[gen->stack.sp-1] = next;
- break;
- }
- /* Pop the stack and try again. */
- gen->gen.cubes.cube[preg->index] = 2;
- gen->stack.sp--;
- top = gen->stack.stack[gen->stack.sp-1];
- treg = Cudd_Regular(top);
- }
- } else {
- gen->status = CUDD_GEN_NONEMPTY;
- gen->gen.cubes.value = cuddV(top);
- goto done;
- }
- }
-
-done:
- *cube = gen->gen.cubes.cube;
- *value = gen->gen.cubes.value;
- return(gen);
-
-} /* end of Cudd_FirstCube */
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_NextCube(
- DdGen * gen,
- int ** cube,
- CUDD_VALUE_TYPE * value)
-{
- DdNode *top, *treg, *next, *nreg, *prev, *preg;
- DdManager *dd = gen->manager;
-
- /* Backtrack from previously reached terminal node. */
- while (1) {
- if (gen->stack.sp == 1) {
- /* The current node has no predecessor. */
- gen->status = CUDD_GEN_EMPTY;
- gen->stack.sp--;
- goto done;
- }
- top = gen->stack.stack[gen->stack.sp-1];
- treg = Cudd_Regular(top);
- prev = gen->stack.stack[gen->stack.sp-2];
- preg = Cudd_Regular(prev);
- nreg = cuddT(preg);
- if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;}
- if (next != top) { /* follow the then branch next */
- gen->gen.cubes.cube[preg->index] = 1;
- gen->stack.stack[gen->stack.sp-1] = next;
- break;
- }
- /* Pop the stack and try again. */
- gen->gen.cubes.cube[preg->index] = 2;
- gen->stack.sp--;
- }
-
- while (1) {
- top = gen->stack.stack[gen->stack.sp-1];
- treg = Cudd_Regular(top);
- if (!cuddIsConstant(treg)) {
- /* Take the else branch first. */
- gen->gen.cubes.cube[treg->index] = 0;
- next = cuddE(treg);
- if (top != treg) next = Cudd_Not(next);
- gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++;
- } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) {
- /* Backtrack */
- while (1) {
- if (gen->stack.sp == 1) {
- /* The current node has no predecessor. */
- gen->status = CUDD_GEN_EMPTY;
- gen->stack.sp--;
- goto done;
- }
- prev = gen->stack.stack[gen->stack.sp-2];
- preg = Cudd_Regular(prev);
- nreg = cuddT(preg);
- if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;}
- if (next != top) { /* follow the then branch next */
- gen->gen.cubes.cube[preg->index] = 1;
- gen->stack.stack[gen->stack.sp-1] = next;
- break;
- }
- /* Pop the stack and try again. */
- gen->gen.cubes.cube[preg->index] = 2;
- gen->stack.sp--;
- top = gen->stack.stack[gen->stack.sp-1];
- treg = Cudd_Regular(top);
- }
- } else {
- gen->status = CUDD_GEN_NONEMPTY;
- gen->gen.cubes.value = cuddV(top);
- goto done;
- }
- }
-
-done:
- if (gen->status == CUDD_GEN_EMPTY) return(0);
- *cube = gen->gen.cubes.cube;
- *value = gen->gen.cubes.value;
- return(1);
-
-} /* end of Cudd_NextCube */
-
-
-/**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]
-
-******************************************************************************/
-DdNode *
-Cudd_bddComputeCube(
- DdManager * dd,
- DdNode ** vars,
- int * phase,
- int n)
-{
- DdNode *cube;
- DdNode *fn;
- int i;
-
- cube = DD_ONE(dd);
- cuddRef(cube);
-
- for (i = n - 1; i >= 0; i--) {
- if (phase == NULL || phase[i] != 0) {
- fn = Cudd_bddAnd(dd,vars[i],cube);
- } else {
- fn = Cudd_bddAnd(dd,Cudd_Not(vars[i]),cube);
- }
- if (fn == NULL) {
- Cudd_RecursiveDeref(dd,cube);
- return(NULL);
- }
- cuddRef(fn);
- Cudd_RecursiveDeref(dd,cube);
- cube = fn;
- }
- cuddDeref(cube);
-
- return(cube);
-
-} /* end of Cudd_bddComputeCube */
-
-
-/**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]
-
-******************************************************************************/
-DdNode *
-Cudd_addComputeCube(
- DdManager * dd,
- DdNode ** vars,
- int * phase,
- int n)
-{
- DdNode *cube, *zero;
- DdNode *fn;
- int i;
-
- cube = DD_ONE(dd);
- cuddRef(cube);
- zero = DD_ZERO(dd);
-
- for (i = n - 1; i >= 0; i--) {
- if (phase == NULL || phase[i] != 0) {
- fn = Cudd_addIte(dd,vars[i],cube,zero);
- } else {
- fn = Cudd_addIte(dd,vars[i],zero,cube);
- }
- if (fn == NULL) {
- Cudd_RecursiveDeref(dd,cube);
- return(NULL);
- }
- cuddRef(fn);
- Cudd_RecursiveDeref(dd,cube);
- cube = fn;
- }
- cuddDeref(cube);
-
- return(cube);
-
-} /* end of Cudd_addComputeCube */
-
-
-/**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]
-
-******************************************************************************/
-DdNode *
-Cudd_CubeArrayToBdd(
- DdManager *dd,
- int *array)
-{
- DdNode *cube, *var, *tmp;
- int i;
- int size = Cudd_ReadSize(dd);
-
- cube = DD_ONE(dd);
- cuddRef(cube);
- for (i = size - 1; i >= 0; i--) {
- if ((array[i] & ~1) == 0) {
- var = Cudd_bddIthVar(dd,i);
- tmp = Cudd_bddAnd(dd,cube,Cudd_NotCond(var,array[i]==0));
- if (tmp == NULL) {
- Cudd_RecursiveDeref(dd,cube);
- return(NULL);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,cube);
- cube = tmp;
- }
- }
- cuddDeref(cube);
- return(cube);
-
-} /* end of Cudd_CubeArrayToBdd */
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_BddToCubeArray(
- DdManager *dd,
- DdNode *cube,
- int *array)
-{
- DdNode *scan, *t, *e;
- int i;
- int size = Cudd_ReadSize(dd);
- DdNode *zero = Cudd_Not(DD_ONE(dd));
-
- for (i = size-1; i >= 0; i--) {
- array[i] = 2;
- }
- scan = cube;
- while (!Cudd_IsConstant(scan)) {
- int index = Cudd_Regular(scan)->index;
- cuddGetBranches(scan,&t,&e);
- if (t == zero) {
- array[index] = 0;
- scan = e;
- } else if (e == zero) {
- array[index] = 1;
- scan = t;
- } else {
- return(0); /* cube is not a cube */
- }
- }
- if (scan == zero) {
- return(0);
- } else {
- return(1);
- }
-
-} /* end of Cudd_BddToCubeArray */
-
-
-/**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.]
-
- SideEffects [The first node is returned as a side effect.]
-
- SeeAlso [Cudd_ForeachNode Cudd_NextNode Cudd_GenFree Cudd_IsGenEmpty
- Cudd_FirstCube]
-
-******************************************************************************/
-DdGen *
-Cudd_FirstNode(
- DdManager * dd,
- DdNode * f,
- DdNode ** node)
-{
- DdGen *gen;
- int retval;
-
- /* Sanity Check. */
- if (dd == NULL || f == NULL) return(NULL);
-
- /* Allocate generator an initialize it. */
- gen = ALLOC(DdGen,1);
- if (gen == NULL) {
- dd->errorCode = CUDD_MEMORY_OUT;
- return(NULL);
- }
-
- gen->manager = dd;
- gen->type = CUDD_GEN_NODES;
- gen->status = CUDD_GEN_EMPTY;
- gen->gen.nodes.visited = NULL;
- gen->gen.nodes.stGen = NULL;
- gen->stack.sp = 0;
- gen->stack.stack = NULL;
- gen->node = NULL;
-
- gen->gen.nodes.visited = st_init_table(st_ptrcmp,st_ptrhash);
- if (gen->gen.nodes.visited == NULL) {
- FREE(gen);
- return(NULL);
- }
-
- /* Collect all the nodes in a st table for later perusal. */
- retval = cuddCollectNodes(Cudd_Regular(f),gen->gen.nodes.visited);
- if (retval == 0) {
- st_free_table(gen->gen.nodes.visited);
- FREE(gen);
- return(NULL);
- }
-
- /* Initialize the st table generator. */
- gen->gen.nodes.stGen = st_init_gen(gen->gen.nodes.visited);
- if (gen->gen.nodes.stGen == NULL) {
- st_free_table(gen->gen.nodes.visited);
- FREE(gen);
- return(NULL);
- }
-
- /* Find the first node. */
- retval = st_gen(gen->gen.nodes.stGen, (char **) &(gen->node), NULL);
- if (retval != 0) {
- gen->status = CUDD_GEN_NONEMPTY;
- *node = gen->node;
- }
-
- return(gen);
-
-} /* end of Cudd_FirstNode */
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_NextNode(
- DdGen * gen,
- DdNode ** node)
-{
- int retval;
-
- /* Find the next node. */
- retval = st_gen(gen->gen.nodes.stGen, (char **) &(gen->node), NULL);
- if (retval == 0) {
- gen->status = CUDD_GEN_EMPTY;
- } else {
- *node = gen->node;
- }
-
- return(retval);
-
-} /* end of Cudd_NextNode */
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_GenFree(
- DdGen * gen)
-{
-
- if (gen == NULL) return(0);
- switch (gen->type) {
- case CUDD_GEN_CUBES:
- case CUDD_GEN_ZDD_PATHS:
- FREE(gen->gen.cubes.cube);
- FREE(gen->stack.stack);
- break;
- case CUDD_GEN_NODES:
- st_free_gen(gen->gen.nodes.stGen);
- st_free_table(gen->gen.nodes.visited);
- break;
- default:
- return(0);
- }
- FREE(gen);
- return(0);
-
-} /* end of Cudd_GenFree */
-
-
-/**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]
-
-******************************************************************************/
-int
-Cudd_IsGenEmpty(
- DdGen * gen)
-{
- if (gen == NULL) return(1);
- return(gen->status == CUDD_GEN_EMPTY);
-
-} /* end of Cudd_IsGenEmpty */
-
-
-/**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]
-
-******************************************************************************/
-DdNode *
-Cudd_IndicesToCube(
- DdManager * dd,
- int * array,
- int n)
-{
- DdNode *cube, *tmp;
- int i;
-
- cube = DD_ONE(dd);
- cuddRef(cube);
- for (i = n - 1; i >= 0; i--) {
- tmp = Cudd_bddAnd(dd,Cudd_bddIthVar(dd,array[i]),cube);
- if (tmp == NULL) {
- Cudd_RecursiveDeref(dd,cube);
- return(NULL);
- }
- cuddRef(tmp);
- Cudd_RecursiveDeref(dd,cube);
- cube = tmp;
- }
-
- cuddDeref(cube);
- return(cube);
-
-} /* end of Cudd_IndicesToCube */
-
-
-/**Function********************************************************************
-
- Synopsis [Prints the package version number.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso []
-
-******************************************************************************/
-void
-Cudd_PrintVersion(
- FILE * fp)
-{
- (void) fprintf(fp, "%s\n", CUDD_VERSION);
-
-} /* end of Cudd_PrintVersion */
-
-
-/**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 []
-
-******************************************************************************/
-double
-Cudd_AverageDistance(
- DdManager * dd)
-{
- double tetotal, nexttotal;
- double tesubtotal, nextsubtotal;
- double temeasured, nextmeasured;
- int i, j;
- int slots, nvars;
- long diff;
- DdNode *scan;
- DdNodePtr *nodelist;
- DdNode *sentinel = &(dd->sentinel);
-
- nvars = dd->size;
- if (nvars == 0) return(0.0);
-
- /* Initialize totals. */
- tetotal = 0.0;
- nexttotal = 0.0;
- temeasured = 0.0;
- nextmeasured = 0.0;
-
- /* Scan the variable subtables. */
- for (i = 0; i < nvars; i++) {
- nodelist = dd->subtables[i].nodelist;
- tesubtotal = 0.0;
- nextsubtotal = 0.0;
- slots = dd->subtables[i].slots;
- for (j = 0; j < slots; j++) {
- scan = nodelist[j];
- while (scan != sentinel) {
- diff = (long) scan - (long) cuddT(scan);
- tesubtotal += (double) ddAbs(diff);
- diff = (long) scan - (long) Cudd_Regular(cuddE(scan));
- tesubtotal += (double) ddAbs(diff);
- temeasured += 2.0;
- if (scan->next != NULL) {
- diff = (long) scan - (long) scan->next;
- nextsubtotal += (double) ddAbs(diff);
- nextmeasured += 1.0;
- }
- scan = scan->next;
- }
- }
- tetotal += tesubtotal;
- nexttotal += nextsubtotal;
- }
-
- /* Scan the constant table. */
- nodelist = dd->constants.nodelist;
- nextsubtotal = 0.0;
- slots = dd->constants.slots;
- for (j = 0; j < slots; j++) {
- scan = nodelist[j];
- while (scan != NULL) {
- if (scan->next != NULL) {
- diff = (long) scan - (long) scan->next;
- nextsubtotal += (double) ddAbs(diff);
- nextmeasured += 1.0;
- }
- scan = scan->next;
- }
- }
- nexttotal += nextsubtotal;
-
- return((tetotal + nexttotal) / (temeasured + nextmeasured));
-
-} /* end of Cudd_AverageDistance */
-
-
-/**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]
-
-******************************************************************************/
-long
-Cudd_Random(
- )
-{
- int i; /* index in the shuffle table */
- long int w; /* work variable */
-
- /* cuddRand == 0 if the geneartor has not been initialized yet. */
- if (cuddRand == 0) Cudd_Srandom(1);
-
- /* Compute cuddRand = (cuddRand * LEQA1) % MODULUS1 avoiding
- ** overflows by Schrage's method.
- */
- w = cuddRand / LEQQ1;
- cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1;
- cuddRand += (cuddRand < 0) * MODULUS1;
-
- /* Compute cuddRand2 = (cuddRand2 * LEQA2) % MODULUS2 avoiding
- ** overflows by Schrage's method.
- */
- w = cuddRand2 / LEQQ2;
- cuddRand2 = LEQA2 * (cuddRand2 - w * LEQQ2) - w * LEQR2;
- cuddRand2 += (cuddRand2 < 0) * MODULUS2;
-
- /* cuddRand is shuffled with the Bays-Durham algorithm.
- ** shuffleSelect and cuddRand2 are combined to generate the output.
- */
-
- /* Pick one element from the shuffle table; "i" will be in the range
- ** from 0 to STAB_SIZE-1.
- */
- i = (int) (shuffleSelect / STAB_DIV);
- /* Mix the element of the shuffle table with the current iterate of
- ** the second sub-generator, and replace the chosen element of the
- ** shuffle table with the current iterate of the first sub-generator.
- */
- shuffleSelect = shuffleTable[i] - cuddRand2;
- shuffleTable[i] = cuddRand;
- shuffleSelect += (shuffleSelect < 1) * (MODULUS1 - 1);
- /* Since shuffleSelect != 0, and we want to be able to return 0,
- ** here we subtract 1 before returning.
- */
- return(shuffleSelect - 1);
-
-} /* end of Cudd_Random */
-
-
-/**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]
-
-******************************************************************************/
-void
-Cudd_Srandom(
- long seed)
-{
- int i;
-
- if (seed < 0) cuddRand = -seed;
- else if (seed == 0) cuddRand = 1;
- else cuddRand = seed;
- cuddRand2 = cuddRand;
- /* Load the shuffle table (after 11 warm-ups). */
- for (i = 0; i < STAB_SIZE + 11; i++) {
- long int w;
- w = cuddRand / LEQQ1;
- cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1;
- cuddRand += (cuddRand < 0) * MODULUS1;
- shuffleTable[i % STAB_SIZE] = cuddRand;
- }
- shuffleSelect = shuffleTable[1 % STAB_SIZE];
-
-} /* end of Cudd_Srandom */
-
-
-/**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]
-
-******************************************************************************/
-double
-Cudd_Density(
- DdManager * dd /* manager */,
- DdNode * f /* function whose density is sought */,
- int nvars /* size of the support of f */)
-{
- double minterms;
- int nodes;
- double density;
-
- if (nvars == 0) nvars = dd->size;
- minterms = Cudd_CountMinterm(dd,f,nvars);
- if (minterms == (double) CUDD_OUT_OF_MEM) return(minterms);
- nodes = Cudd_DagSize(f);
- density = minterms / (double) nodes;
- return(density);
-
-} /* end of Cudd_Density */
-
-
-/**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 []
-
-******************************************************************************/
-void
-Cudd_OutOfMem(
- long size /* size of the allocation that failed */)
-{
- (void) fflush(stdout);
- (void) fprintf(stderr, "\nunable to allocate %ld bytes\n", size);
- return;
-
-} /* end of Cudd_OutOfMem */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of internal functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**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]
-
-******************************************************************************/
-int
-cuddP(
- DdManager * dd,
- DdNode * f)
-{
- int retval;
- st_table *table = st_init_table(st_ptrcmp,st_ptrhash);
-
- if (table == NULL) return(0);
-
- retval = dp2(dd,f,table);
- st_free_table(table);
- (void) fputc('\n',dd->out);
- return(retval);
-
-} /* end of cuddP */
-
-
-/**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]
-
-******************************************************************************/
-enum st_retval
-cuddStCountfree(
- char * key,
- char * value,
- char * arg)
-{
- double *d;
-
- d = (double *)value;
- FREE(d);
- return(ST_CONTINUE);
-
-} /* end of cuddStCountfree */
-
-
-/**Function********************************************************************
-
- Synopsis [Recursively collects all the nodes of a DD in a symbol
- table.]
-
- Description [Traverses the BDD 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 []
-
-******************************************************************************/
-int
-cuddCollectNodes(
- DdNode * f,
- st_table * visited)
-{
- DdNode *T, *E;
- int retval;
-
-#ifdef DD_DEBUG
- assert(!Cudd_IsComplement(f));
-#endif
-
- /* If already visited, nothing to do. */
- if (st_is_member(visited, (char *) f) == 1)
- return(1);
-
- /* Check for abnormal condition that should never happen. */
- if (f == NULL)
- return(0);
-
- /* Mark node as visited. */
- if (st_add_direct(visited, (char *) f, NULL) == ST_OUT_OF_MEM)
- return(0);
-
- /* Check terminal case. */
- if (cuddIsConstant(f))
- return(1);
-
- /* Recursive calls. */
- T = cuddT(f);
- retval = cuddCollectNodes(T,visited);
- if (retval != 1) return(retval);
- E = Cudd_Regular(cuddE(f));
- retval = cuddCollectNodes(E,visited);
- return(retval);
-
-} /* end of cuddCollectNodes */
-
-
-/*---------------------------------------------------------------------------*/
-/* Definition of static functions */
-/*---------------------------------------------------------------------------*/
-
-
-/**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]
-
-******************************************************************************/
-static int
-dp2(
- DdManager *dd,
- DdNode * f,
- st_table * t)
-{
- DdNode *g, *n, *N;
- int T,E;
-
- if (f == NULL) {
- return(0);
- }
- g = Cudd_Regular(f);
- if (cuddIsConstant(g)) {
-#if SIZEOF_VOID_P == 8
- (void) fprintf(dd->out,"ID = %c0x%lx\tvalue = %-9g\n", bang(f),
- (unsigned long) g / (unsigned long) sizeof(DdNode),cuddV(g));
-#else
- (void) fprintf(dd->out,"ID = %c0x%x\tvalue = %-9g\n", bang(f),
- (unsigned) g / (unsigned) sizeof(DdNode),cuddV(g));
-#endif
- return(1);
- }
- if (st_is_member(t,(char *) g) == 1) {
- return(1);
- }
- if (st_add_direct(t,(char *) g,NULL) == ST_OUT_OF_MEM)
- return(0);
-#ifdef DD_STATS
-#if SIZEOF_VOID_P == 8
- (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %d\tr = %d\t", bang(f),
- (unsigned long) g / (unsigned long) sizeof(DdNode), g->index, g->ref);
-#else
- (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\tr = %d\t", bang(f),
- (unsigned) g / (unsigned) sizeof(DdNode),g->index,g->ref);
-#endif
-#else
-#if SIZEOF_VOID_P == 8
- (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %d\t", bang(f),
- (unsigned long) g / (unsigned long) sizeof(DdNode),g->index);
-#else
- (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\t", bang(f),
- (unsigned) g / (unsigned) sizeof(DdNode),g->index);
-#endif
-#endif
- n = cuddT(g);
- if (cuddIsConstant(n)) {
- (void) fprintf(dd->out,"T = %-9g\t",cuddV(n));
- T = 1;
- } else {
-#if SIZEOF_VOID_P == 8
- (void) fprintf(dd->out,"T = 0x%lx\t",(unsigned long) n / (unsigned long) sizeof(DdNode));
-#else
- (void) fprintf(dd->out,"T = 0x%x\t",(unsigned) n / (unsigned) sizeof(DdNode));
-#endif
- T = 0;
- }
-
- n = cuddE(g);
- N = Cudd_Regular(n);
- if (cuddIsConstant(N)) {
- (void) fprintf(dd->out,"E = %c%-9g\n",bang(n),cuddV(N));
- E = 1;
- } else {
-#if SIZEOF_VOID_P == 8
- (void) fprintf(dd->out,"E = %c0x%lx\n", bang(n), (unsigned long) N/(unsigned long) sizeof(DdNode));
-#else
- (void) fprintf(dd->out,"E = %c0x%x\n", bang(n), (unsigned) N/(unsigned) sizeof(DdNode));
-#endif
- E = 0;
- }
- if (E == 0) {
- if (dp2(dd,N,t) == 0)
- return(0);
- }
- if (T == 0) {
- if (dp2(dd,cuddT(g),t) == 0)
- return(0);
- }
- return(1);
-
-} /* end of dp2 */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_PrintMinterm.]
-
- Description []
-
- SideEffects [None]
-
-******************************************************************************/
-static void
-ddPrintMintermAux(
- DdManager * dd /* manager */,
- DdNode * node /* current node */,
- int * list /* current recursion path */)
-{
- DdNode *N,*Nv,*Nnv;
- int i,v,index;
-
- N = Cudd_Regular(node);
-
- if (cuddIsConstant(N)) {
- /* Terminal case: Print one cube based on the current recursion
- ** path, unless we have reached the background value (ADDs) or
- ** the logical zero (BDDs).
- */
- if (node != background && node != zero) {
- for (i = 0; i < dd->size; i++) {
- v = list[i];
- if (v == 0) (void) fprintf(dd->out,"0");
- else if (v == 1) (void) fprintf(dd->out,"1");
- else (void) fprintf(dd->out,"-");
- }
- (void) fprintf(dd->out," % g\n", cuddV(node));
- }
- } else {
- Nv = cuddT(N);
- Nnv = cuddE(N);
- if (Cudd_IsComplement(node)) {
- Nv = Cudd_Not(Nv);
- Nnv = Cudd_Not(Nnv);
- }
- index = N->index;
- list[index] = 0;
- ddPrintMintermAux(dd,Nnv,list);
- list[index] = 1;
- ddPrintMintermAux(dd,Nv,list);
- list[index] = 2;
- }
- return;
-
-} /* end of ddPrintMintermAux */
-
-
-/**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]
-
-******************************************************************************/
-static int
-ddDagInt(
- DdNode * n)
-{
- int tval, eval;
-
- if (Cudd_IsComplement(n->next)) {
- return(0);
- }
- n->next = Cudd_Not(n->next);
- if (cuddIsConstant(n)) {
- return(1);
- }
- tval = ddDagInt(cuddT(n));
- eval = ddDagInt(Cudd_Regular(cuddE(n)));
- return(1 + tval + eval);
-
-} /* end of ddDagInt */
-
-
-/**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 []
-
-******************************************************************************/
-static int
-cuddEstimateCofactor(
- DdManager *dd,
- st_table *table,
- DdNode * node,
- int i,
- int phase,
- DdNode ** ptr)
-{
- int tval, eval, val;
- DdNode *ptrT, *ptrE;
-
- if (Cudd_IsComplement(node->next)) {
- if (!st_lookup(table,(char *)node,(char **)ptr)) {
- st_add_direct(table,(char *)node,(char *)node);
- *ptr = node;
- }
- return(0);
- }
- node->next = Cudd_Not(node->next);
- if (cuddIsConstant(node)) {
- *ptr = node;
- if (st_add_direct(table,(char *)node,(char *)node) == ST_OUT_OF_MEM)
- return(CUDD_OUT_OF_MEM);
- return(1);
- }
- if ((int) node->index == i) {
- if (phase == 1) {
- *ptr = cuddT(node);
- val = ddDagInt(cuddT(node));
- } else {
- *ptr = cuddE(node);
- val = ddDagInt(Cudd_Regular(cuddE(node)));
- }
- if (node->ref > 1) {
- if (st_add_direct(table,(char *)node,(char *)*ptr) ==
- ST_OUT_OF_MEM)
- return(CUDD_OUT_OF_MEM);
- }
- return(val);
- }
- if (dd->perm[node->index] > dd->perm[i]) {
- *ptr = node;
- tval = ddDagInt(cuddT(node));
- eval = ddDagInt(Cudd_Regular(cuddE(node)));
- if (node->ref > 1) {
- if (st_add_direct(table,(char *)node,(char *)node) ==
- ST_OUT_OF_MEM)
- return(CUDD_OUT_OF_MEM);
- }
- val = 1 + tval + eval;
- return(val);
- }
- tval = cuddEstimateCofactor(dd,table,cuddT(node),i,phase,&ptrT);
- eval = cuddEstimateCofactor(dd,table,Cudd_Regular(cuddE(node)),i,
- phase,&ptrE);
- ptrE = Cudd_NotCond(ptrE,Cudd_IsComplement(cuddE(node)));
- if (ptrT == ptrE) { /* recombination */
- *ptr = ptrT;
- val = tval;
- if (node->ref > 1) {
- if (st_add_direct(table,(char *)node,(char *)*ptr) ==
- ST_OUT_OF_MEM)
- return(CUDD_OUT_OF_MEM);
- }
- } else if ((ptrT != cuddT(node) || ptrE != cuddE(node)) &&
- (*ptr = cuddUniqueLookup(dd,node->index,ptrT,ptrE)) != NULL) {
- if (Cudd_IsComplement((*ptr)->next)) {
- val = 0;
- } else {
- val = 1 + tval + eval;
- }
- if (node->ref > 1) {
- if (st_add_direct(table,(char *)node,(char *)*ptr) ==
- ST_OUT_OF_MEM)
- return(CUDD_OUT_OF_MEM);
- }
- } else {
- *ptr = node;
- val = 1 + tval + eval;
- }
- return(val);
-
-} /* end of cuddEstimateCofactor */
-
-
-/**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]
-
-******************************************************************************/
-static DdNode *
-cuddUniqueLookup(
- DdManager * unique,
- int index,
- DdNode * T,
- DdNode * E)
-{
- int posn;
- unsigned int level;
- DdNodePtr *nodelist;
- DdNode *looking;
- DdSubtable *subtable;
-
- if (index >= unique->size) {
- return(NULL);
- }
-
- level = unique->perm[index];
- subtable = &(unique->subtables[level]);
-
-#ifdef DD_DEBUG
- assert(level < (unsigned) cuddI(unique,T->index));
- assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index));
-#endif
-
- posn = ddHash(T, E, subtable->shift);
- nodelist = subtable->nodelist;
- looking = nodelist[posn];
-
- while (T < cuddT(looking)) {
- looking = Cudd_Regular(looking->next);
- }
- while (T == cuddT(looking) && E < cuddE(looking)) {
- looking = Cudd_Regular(looking->next);
- }
- if (cuddT(looking) == T && cuddE(looking) == E) {
- return(looking);
- }
-
- return(NULL);
-
-} /* end of cuddUniqueLookup */
-
-
-/**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 []
-
-******************************************************************************/
-static int
-cuddEstimateCofactorSimple(
- DdNode * node,
- int i)
-{
- int tval, eval;
-
- if (Cudd_IsComplement(node->next)) {
- return(0);
- }
- node->next = Cudd_Not(node->next);
- if (cuddIsConstant(node)) {
- return(1);
- }
- tval = cuddEstimateCofactorSimple(cuddT(node),i);
- if ((int) node->index == i) return(tval);
- eval = cuddEstimateCofactorSimple(Cudd_Regular(cuddE(node)),i);
- return(1 + tval + eval);
-
-} /* end of cuddEstimateCofactorSimple */
-
-
-/**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]
-
-******************************************************************************/
-static double
-ddCountMintermAux(
- DdNode * node,
- double max,
- DdHashTable * table)
-{
- DdNode *N, *Nt, *Ne;
- double min, minT, minE;
- DdNode *res;
-
- N = Cudd_Regular(node);
-
- if (cuddIsConstant(N)) {
- if (node == background || node == zero) {
- return(0.0);
- } else {
- return(max);
- }
- }
- if (N->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) {
- min = cuddV(res);
- if (res->ref == 0) {
- table->manager->dead++;
- table->manager->constants.dead++;
- }
- return(min);
- }
-
- Nt = cuddT(N); Ne = cuddE(N);
- if (Cudd_IsComplement(node)) {
- Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne);
- }
-
- minT = ddCountMintermAux(Nt,max,table);
- if (minT == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
- minT *= 0.5;
- minE = ddCountMintermAux(Ne,max,table);
- if (minE == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
- minE *= 0.5;
- min = minT + minE;
-
- if (N->ref != 1) {
- ptrint fanout = (ptrint) N->ref;
- cuddSatDec(fanout);
- res = cuddUniqueConst(table->manager,min);
- if (!cuddHashTableInsert1(table,node,res,fanout)) {
- cuddRef(res); Cudd_RecursiveDeref(table->manager, res);
- return((double)CUDD_OUT_OF_MEM);
- }
- }
-
- return(min);
-
-} /* end of ddCountMintermAux */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs the recursive step of Cudd_CountPath.]
-
- Description [Performs the recursive step of Cudd_CountPath.
- It is based on the following identity. Let |f| be the
- number of paths of f. Then:
- <xmp>
- |f| = |f0|+|f1|
- </xmp>
- where f0 and f1 are the two cofactors of f. Uses the
- identity |f'| = |f|, to improve the utilization of the (local) cache.
- Returns the number of paths of the function rooted at node.]
-
- SideEffects [None]
-
-******************************************************************************/
-static double
-ddCountPathAux(
- DdNode * node,
- st_table * table)
-{
-
- DdNode *Nv, *Nnv;
- double paths, *ppaths, paths1, paths2;
- double *dummy;
-
-
- if (cuddIsConstant(node)) {
- return(1.0);
- }
- if (st_lookup(table, (char *)node, (char **)&dummy)) {
- paths = *dummy;
- return(paths);
- }
-
- Nv = cuddT(node); Nnv = cuddE(node);
-
- paths1 = ddCountPathAux(Nv,table);
- if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
- paths2 = ddCountPathAux(Cudd_Regular(Nnv),table);
- if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
- paths = paths1 + paths2;
-
- ppaths = ALLOC(double,1);
- if (ppaths == NULL) {
- return((double)CUDD_OUT_OF_MEM);
- }
-
- *ppaths = paths;
-
- if (st_add_direct(table,(char *)node, (char *)ppaths) == ST_OUT_OF_MEM) {
- FREE(ppaths);
- return((double)CUDD_OUT_OF_MEM);
- }
- return(paths);
-
-} /* end of ddCountPathAux */
-
-
-/**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]
-
-******************************************************************************/
-static int
-ddEpdCountMintermAux(
- DdNode * node,
- EpDouble * max,
- EpDouble * epd,
- st_table * table)
-{
- DdNode *Nt, *Ne;
- EpDouble *min, minT, minE;
- EpDouble *res;
- int status;
-
- if (cuddIsConstant(node)) {
- if (node == background || node == zero) {
- EpdMakeZero(epd, 0);
- } else {
- EpdCopy(max, epd);
- }
- return(0);
- }
- if (node->ref != 1 && st_lookup(table, (char *)node, (char **)&res)) {
- EpdCopy(res, epd);
- return(0);
- }
-
- Nt = cuddT(node); Ne = cuddE(node);
- if (Cudd_IsComplement(node)) {
- Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne);
- }
-
- status = ddEpdCountMintermAux(Nt,max,&minT,table);
- if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM);
- EpdMultiply(&minT, (double)0.5);
- status = ddEpdCountMintermAux(Ne,max,&minE,table);
- if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM);
- if (Cudd_IsComplement(Ne)) {
- EpdSubtract3(max, &minE, epd);
- EpdCopy(epd, &minE);
- }
- EpdMultiply(&minE, (double)0.5);
- EpdAdd3(&minT, &minE, epd);
-
- if (node->ref > 1) {
- min = EpdAlloc();
- if (!min)
- return(CUDD_OUT_OF_MEM);
- EpdCopy(epd, min);
- if (st_insert(table, (char *)node, (char *)min) == ST_OUT_OF_MEM) {
- EpdFree(min);
- return(CUDD_OUT_OF_MEM);
- }
- }
-
- return(0);
-
-} /* end of ddEpdCountMintermAux */
-
-
-/**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]
-
-******************************************************************************/
-static double
-ddCountPathsToNonZero(
- DdNode * N,
- st_table * table)
-{
-
- DdNode *node, *Nt, *Ne;
- double paths, *ppaths, paths1, paths2;
- double *dummy;
-
- node = Cudd_Regular(N);
- if (cuddIsConstant(node)) {
- return((double) !(Cudd_IsComplement(N) || cuddV(node)==DD_ZERO_VAL));
- }
- if (st_lookup(table, (char *)N, (char **)&dummy)) {
- paths = *dummy;
- return(paths);
- }
-
- Nt = cuddT(node); Ne = cuddE(node);
- if (node != N) {
- Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne);
- }
-
- paths1 = ddCountPathsToNonZero(Nt,table);
- if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
- paths2 = ddCountPathsToNonZero(Ne,table);
- if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
- paths = paths1 + paths2;
-
- ppaths = ALLOC(double,1);
- if (ppaths == NULL) {
- return((double)CUDD_OUT_OF_MEM);
- }
-
- *ppaths = paths;
-
- if (st_add_direct(table,(char *)N, (char *)ppaths) == ST_OUT_OF_MEM) {
- FREE(ppaths);
- return((double)CUDD_OUT_OF_MEM);
- }
- return(paths);
-
-} /* end of ddCountPathsToNonZero */
-
-
-/**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]
-
-******************************************************************************/
-static void
-ddSupportStep(
- DdNode * f,
- int * support)
-{
- if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) {
- return;
- }
-
- support[f->index] = 1;
- ddSupportStep(cuddT(f),support);
- ddSupportStep(Cudd_Regular(cuddE(f)),support);
- /* Mark as visited. */
- f->next = Cudd_Not(f->next);
- return;
-
-} /* end of ddSupportStep */
-
-
-/**Function********************************************************************
-
- Synopsis [Performs a DFS from f, clearing the LSB of the next
- pointers.]
-
- Description []
-
- SideEffects [None]
-
- SeeAlso [ddSupportStep ddDagInt]
-
-******************************************************************************/
-static void
-ddClearFlag(
- DdNode * f)
-{
- if (!Cudd_IsComplement(f->next)) {
- return;
- }
- /* Clear visited flag. */
- f->next = Cudd_Regular(f->next);
- if (cuddIsConstant(f)) {
- return;
- }
- ddClearFlag(cuddT(f));
- ddClearFlag(Cudd_Regular(cuddE(f)));
- return;
-
-} /* end of ddClearFlag */
-
-
-/**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]
-
-******************************************************************************/
-static int
-ddLeavesInt(
- DdNode * n)
-{
- int tval, eval;
-
- if (Cudd_IsComplement(n->next)) {
- return(0);
- }
- n->next = Cudd_Not(n->next);
- if (cuddIsConstant(n)) {
- return(1);
- }
- tval = ddLeavesInt(cuddT(n));
- eval = ddLeavesInt(Cudd_Regular(cuddE(n)));
- return(tval + eval);
-
-} /* end of ddLeavesInt */
-
-
-/**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]
-
-******************************************************************************/
-static int
-ddPickArbitraryMinterms(
- DdManager *dd,
- DdNode *node,
- int nvars,
- int nminterms,
- char **string)
-{
- DdNode *N, *T, *E;
- DdNode *one, *bzero;
- int i, t, result;
- double min1, min2;
-
- if (string == NULL || node == NULL) return(0);
-
- /* The constant 0 function has no on-set cubes. */
- one = DD_ONE(dd);
- bzero = Cudd_Not(one);
- if (nminterms == 0 || node == bzero) return(1);
- if (node == one) {
- return(1);
- }
-
- N = Cudd_Regular(node);
- T = cuddT(N); E = cuddE(N);
- if (Cudd_IsComplement(node)) {
- T = Cudd_Not(T); E = Cudd_Not(E);
- }
-
- min1 = Cudd_CountMinterm(dd, T, nvars) / 2.0;
- if (min1 == (double)CUDD_OUT_OF_MEM) return(0);
- min2 = Cudd_CountMinterm(dd, E, nvars) / 2.0;
- if (min2 == (double)CUDD_OUT_OF_MEM) return(0);
-
- t = (int)((double)nminterms * min1 / (min1 + min2) + 0.5);
- for (i = 0; i < t; i++)
- string[i][N->index] = '1';
- for (i = t; i < nminterms; i++)
- string[i][N->index] = '0';
-
- result = ddPickArbitraryMinterms(dd,T,nvars,t,&string[0]);
- if (result == 0)
- return(0);
- result = ddPickArbitraryMinterms(dd,E,nvars,nminterms-t,&string[t]);
- return(result);
-
-} /* end of ddPickArbitraryMinterms */
-
-
-/**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]
-
-******************************************************************************/
-static int
-ddPickRepresentativeCube(
- DdManager *dd,
- DdNode *node,
- int nvars,
- double *weight,
- char *string)
-{
- DdNode *N, *T, *E;
- DdNode *one, *bzero;
-
- if (string == NULL || node == NULL) return(0);
-
- /* The constant 0 function has no on-set cubes. */
- one = DD_ONE(dd);
- bzero = Cudd_Not(one);
- if (node == bzero) return(0);
-
- if (node == DD_ONE(dd)) return(1);
-
- for (;;) {
- N = Cudd_Regular(node);
- if (N == one)
- break;
- T = cuddT(N);
- E = cuddE(N);
- if (Cudd_IsComplement(node)) {
- T = Cudd_Not(T);
- E = Cudd_Not(E);
- }
- if (weight[N->index] >= 0.0) {
- if (T == bzero) {
- node = E;
- string[N->index] = '0';
- } else {
- node = T;
- string[N->index] = '1';
- }
- } else {
- if (E == bzero) {
- node = T;
- string[N->index] = '1';
- } else {
- node = E;
- string[N->index] = '0';
- }
- }
- }
- return(1);
-
-} /* end of ddPickRepresentativeCube */
-
-
-/**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]
-
-******************************************************************************/
-static enum st_retval
-ddEpdFree(
- char * key,
- char * value,
- char * arg)
-{
- EpDouble *epd;
-
- epd = (EpDouble *) value;
- EpdFree(epd);
- return(ST_CONTINUE);
-
-} /* end of ddEpdFree */