diff options
Diffstat (limited to 'src/bdd/cudd/cuddSplit.c')
-rw-r--r-- | src/bdd/cudd/cuddSplit.c | 657 |
1 files changed, 0 insertions, 657 deletions
diff --git a/src/bdd/cudd/cuddSplit.c b/src/bdd/cudd/cuddSplit.c deleted file mode 100644 index e21ea7cb..00000000 --- a/src/bdd/cudd/cuddSplit.c +++ /dev/null @@ -1,657 +0,0 @@ -/**CFile*********************************************************************** - - FileName [cuddSplit.c] - - PackageName [cudd] - - Synopsis [Returns a subset of minterms from a boolean function.] - - Description [External functions included in this modoule: - <ul> - <li> Cudd_SplitSet() - </ul> - Internal functions included in this module: - <ul> - <li> cuddSplitSetRecur() - </u> - Static functions included in this module: - <ul> - <li> selectMintermsFromUniverse() - <li> mintermsFromUniverse() - <li> bddAnnotateMintermCount() - </ul> ] - - SeeAlso [] - - Author [Balakrishna Kumthekar] - - 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 */ -/*---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------*/ -/* Type declarations */ -/*---------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------*/ -/* Structure declarations */ -/*---------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------*/ -/* Variable declarations */ -/*---------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------*/ -/* Macro declarations */ -/*---------------------------------------------------------------------------*/ - - -/**AutomaticStart*************************************************************/ - -/*---------------------------------------------------------------------------*/ -/* Static function prototypes */ -/*---------------------------------------------------------------------------*/ - -static DdNode * selectMintermsFromUniverse ARGS((DdManager *manager, int *varSeen, double n)); -static DdNode * mintermsFromUniverse ARGS((DdManager *manager, DdNode **vars, int numVars, double n, int index)); -static double bddAnnotateMintermCount ARGS((DdManager *manager, DdNode *node, double max, st_table *table)); - -/**AutomaticEnd***************************************************************/ - - -/*---------------------------------------------------------------------------*/ -/* Definition of exported functions */ -/*---------------------------------------------------------------------------*/ - - -/**Function******************************************************************** - - Synopsis [Returns m minterms from a BDD.] - - Description [Returns <code>m</code> minterms from a BDD whose - support has <code>n</code> variables at most. The procedure tries - to create as few extra nodes as possible. The function represented - by <code>S</code> depends on at most <code>n</code> of the variables - in <code>xVars</code>. Returns a BDD with <code>m</code> minterms - of the on-set of S if successful; NULL otherwise.] - - SideEffects [None] - - SeeAlso [] - -******************************************************************************/ -DdNode * -Cudd_SplitSet( - DdManager * manager, - DdNode * S, - DdNode ** xVars, - int n, - double m) -{ - DdNode *result; - DdNode *zero, *one; - double max, num; - st_table *mtable; - int *varSeen; - int i,index, size; - - size = manager->size; - one = DD_ONE(manager); - zero = Cudd_Not(one); - - /* Trivial cases. */ - if (m == 0.0) { - return(zero); - } - if (S == zero) { - return(NULL); - } - - max = pow(2.0,(double)n); - if (m > max) - return(NULL); - - do { - manager->reordered = 0; - /* varSeen is used to mark the variables that are encountered - ** while traversing the BDD S. - */ - varSeen = ALLOC(int, size); - if (varSeen == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - for (i = 0; i < size; i++) { - varSeen[i] = -1; - } - for (i = 0; i < n; i++) { - index = (xVars[i])->index; - varSeen[manager->invperm[index]] = 0; - } - - if (S == one) { - if (m == max) - return(S); - result = selectMintermsFromUniverse(manager,varSeen,m); - if (result) - cuddRef(result); - FREE(varSeen); - } else { - mtable = st_init_table(st_ptrcmp,st_ptrhash); - if (mtable == NULL) { - (void) fprintf(manager->out, - "Cudd_SplitSet: out-of-memory.\n"); - FREE(varSeen); - manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - /* The nodes of BDD S are annotated by the number of minterms - ** in their onset. The node and the number of minterms in its - ** onset are stored in mtable. - */ - num = bddAnnotateMintermCount(manager,S,max,mtable); - if (m == num) { - st_foreach(mtable,cuddStCountfree,NIL(char)); - st_free_table(mtable); - FREE(varSeen); - return(S); - } - - result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0); - if (result) - cuddRef(result); - st_foreach(mtable,cuddStCountfree,NULL); - st_free_table(mtable); - FREE(varSeen); - } - } while (manager->reordered == 1); - - cuddDeref(result); - return(result); - -} /* end of Cudd_SplitSet */ - - -/*---------------------------------------------------------------------------*/ -/* Definition of internal functions */ -/*---------------------------------------------------------------------------*/ - -/**Function******************************************************************** - - Synopsis [Implements the recursive step of Cudd_SplitSet.] - - Description [Implements the recursive step of Cudd_SplitSet. The - procedure recursively traverses the BDD and checks to see if any - node satisfies the minterm requirements as specified by 'n'. At any - node X, n is compared to the number of minterms in the onset of X's - children. If either of the child nodes have exactly n minterms, then - that node is returned; else, if n is greater than the onset of one - of the child nodes, that node is retained and the difference in the - number of minterms is extracted from the other child. In case n - minterms can be extracted from constant 1, the algorithm returns the - result with at most log(n) nodes.] - - SideEffects [The array 'varSeen' is updated at every recursive call - to set the variables traversed by the procedure.] - - SeeAlso [] - -******************************************************************************/ -DdNode* -cuddSplitSetRecur( - DdManager * manager, - st_table * mtable, - int * varSeen, - DdNode * p, - double n, - double max, - int index) -{ - DdNode *one, *zero, *N, *Nv; - DdNode *Nnv, *q, *r, *v; - DdNode *result; - double *dummy, numT, numE; - int variable, positive; - - statLine(manager); - one = DD_ONE(manager); - zero = Cudd_Not(one); - - /* If p is constant, extract n minterms from constant 1. The procedure by - ** construction guarantees that minterms will not be extracted from - ** constant 0. - */ - if (Cudd_IsConstant(p)) { - q = selectMintermsFromUniverse(manager,varSeen,n); - return(q); - } - - N = Cudd_Regular(p); - - /* Set variable as seen. */ - variable = N->index; - varSeen[manager->invperm[variable]] = -1; - - Nv = cuddT(N); - Nnv = cuddE(N); - if (Cudd_IsComplement(p)) { - Nv = Cudd_Not(Nv); - Nnv = Cudd_Not(Nnv); - } - - /* If both the children of 'p' are constants, extract n minterms from a - ** constant node. - */ - if (Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) { - q = selectMintermsFromUniverse(manager,varSeen,n); - if (q == NULL) { - return(NULL); - } - cuddRef(q); - r = cuddBddAndRecur(manager,p,q); - if (r == NULL) { - Cudd_RecursiveDeref(manager,q); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDeref(manager,q); - cuddDeref(r); - return(r); - } - - /* Lookup the # of minterms in the onset of the node from the table. */ - if (!Cudd_IsConstant(Nv)) { - st_lookup(mtable,(char *)Nv, (char **)&dummy); - numT = *dummy/(2*(1<<index)); - } else if (Nv == one) { - numT = max/(2*(1<<index)); - } else { - numT = 0; - } - - if (!Cudd_IsConstant(Nnv)) { - st_lookup(mtable,(char *)Nnv, (char **)&dummy); - numE = *dummy/(2*(1<<index)); - } else if (Nnv == one) { - numE = max/(2*(1<<index)); - } else { - numE = 0; - } - - v = cuddUniqueInter(manager,variable,one,zero); - cuddRef(v); - - /* If perfect match. */ - if (numT == n) { - q = cuddBddAndRecur(manager,v,Nv); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(q); - return(q); - } - if (numE == n) { - q = cuddBddAndRecur(manager,Cudd_Not(v),Nnv); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(q); - return(q); - } - /* If n is greater than numT, extract the difference from the ELSE child - ** and retain the function represented by the THEN branch. - */ - if (numT < n) { - q = cuddSplitSetRecur(manager,mtable,varSeen, - Nnv,(n-numT),max,index+1); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - r = cuddBddIteRecur(manager,v,Nv,q); - if (r == NULL) { - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(r); - return(r); - } - /* If n is greater than numE, extract the difference from the THEN child - ** and retain the function represented by the ELSE branch. - */ - if (numE < n) { - q = cuddSplitSetRecur(manager,mtable,varSeen, - Nv, (n-numE),max,index+1); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - r = cuddBddIteRecur(manager,v,q,Nnv); - if (r == NULL) { - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(r); - return(r); - } - - /* None of the above cases; (n < numT and n < numE) and either of - ** the Nv, Nnv or both are not constants. If possible extract the - ** required minterms the constant branch. - */ - if (Cudd_IsConstant(Nv) && !Cudd_IsConstant(Nnv)) { - q = selectMintermsFromUniverse(manager,varSeen,n); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - result = cuddBddAndRecur(manager,v,q); - if (result == NULL) { - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(result); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(result); - return(result); - } else if (!Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) { - q = selectMintermsFromUniverse(manager,varSeen,n); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - result = cuddBddAndRecur(manager,Cudd_Not(v),q); - if (result == NULL) { - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(result); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(result); - return(result); - } - - /* Both Nv and Nnv are not constants. So choose the one which - ** has fewer minterms in its onset. - */ - positive = 0; - if (numT < numE) { - q = cuddSplitSetRecur(manager,mtable,varSeen, - Nv,n,max,index+1); - positive = 1; - } else { - q = cuddSplitSetRecur(manager,mtable,varSeen, - Nnv,n,max,index+1); - } - - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - - if (positive) { - result = cuddBddAndRecur(manager,v,q); - } else { - result = cuddBddAndRecur(manager,Cudd_Not(v),q); - } - if (result == NULL) { - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(result); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(result); - - return(result); - -} /* end of cuddSplitSetRecur */ - - -/*---------------------------------------------------------------------------*/ -/* Definition of static functions */ -/*---------------------------------------------------------------------------*/ - -/**Function******************************************************************** - - Synopsis [This function prepares an array of variables which have not been - encountered so far when traversing the procedure cuddSplitSetRecur.] - - Description [This function prepares an array of variables which have not been - encountered so far when traversing the procedure cuddSplitSetRecur. This - array is then used to extract the required number of minterms from a constant - 1. The algorithm guarantees that the size of BDD will be utmost \log(n).] - - SideEffects [None] - -******************************************************************************/ -static DdNode * -selectMintermsFromUniverse( - DdManager * manager, - int * varSeen, - double n) -{ - int numVars; - int i, size, j; - DdNode *one, *zero, *result; - DdNode **vars; - - numVars = 0; - size = manager->size; - one = DD_ONE(manager); - zero = Cudd_Not(one); - - /* Count the number of variables not encountered so far in procedure - ** cuddSplitSetRecur. - */ - for (i = size-1; i >= 0; i--) { - if(varSeen[i] == 0) - numVars++; - } - vars = ALLOC(DdNode *, numVars); - if (!vars) { - manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - - j = 0; - for (i = size-1; i >= 0; i--) { - if(varSeen[i] == 0) { - vars[j] = cuddUniqueInter(manager,manager->perm[i],one,zero); - cuddRef(vars[j]); - j++; - } - } - - /* Compute a function which has n minterms and depends on at most - ** numVars variables. - */ - result = mintermsFromUniverse(manager,vars,numVars,n, 0); - if (result) - cuddRef(result); - - for (i = 0; i < numVars; i++) - Cudd_RecursiveDeref(manager,vars[i]); - FREE(vars); - - return(result); - -} /* end of selectMintermsFromUniverse */ - - -/**Function******************************************************************** - - Synopsis [Recursive procedure to extract n mintems from constant 1.] - - Description [Recursive procedure to extract n mintems from constant 1.] - - SideEffects [None] - -******************************************************************************/ -static DdNode * -mintermsFromUniverse( - DdManager * manager, - DdNode ** vars, - int numVars, - double n, - int index) -{ - DdNode *one, *zero; - DdNode *q, *result; - double max, max2; - - statLine(manager); - one = DD_ONE(manager); - zero = Cudd_Not(one); - - max = pow(2.0, (double)numVars); - max2 = max / 2.0; - - if (n == max) - return(one); - if (n == 0.0) - return(zero); - /* if n == 2^(numVars-1), return a single variable */ - if (n == max2) - return vars[index]; - else if (n > max2) { - /* When n > 2^(numVars-1), a single variable vars[index] - ** contains 2^(numVars-1) minterms. The rest are extracted - ** from a constant with 1 less variable. - */ - q = mintermsFromUniverse(manager,vars,numVars-1,(n-max2),index+1); - if (q == NULL) - return(NULL); - cuddRef(q); - result = cuddBddIteRecur(manager,vars[index],one,q); - } else { - /* When n < 2^(numVars-1), a literal of variable vars[index] - ** is selected. The required n minterms are extracted from a - ** constant with 1 less variable. - */ - q = mintermsFromUniverse(manager,vars,numVars-1,n,index+1); - if (q == NULL) - return(NULL); - cuddRef(q); - result = cuddBddAndRecur(manager,vars[index],q); - } - - if (result == NULL) { - Cudd_RecursiveDeref(manager,q); - return(NULL); - } - cuddRef(result); - Cudd_RecursiveDeref(manager,q); - cuddDeref(result); - return(result); - -} /* end of mintermsFromUniverse */ - - -/**Function******************************************************************** - - Synopsis [Annotates every node in the BDD node with its minterm count.] - - Description [Annotates every node in the BDD node with its minterm count. - In this function, every node and the minterm count represented by it are - stored in a hash table.] - - SideEffects [Fills up 'table' with the pair <node,minterm_count>.] - -******************************************************************************/ -static double -bddAnnotateMintermCount( - DdManager * manager, - DdNode * node, - double max, - st_table * table) -{ - - DdNode *N,*Nv,*Nnv; - register double min_v,min_nv; - register double min_N; - double *pmin; - double *dummy; - - statLine(manager); - N = Cudd_Regular(node); - if (cuddIsConstant(N)) { - if (node == DD_ONE(manager)) { - return(max); - } else { - return(0.0); - } - } - - if (st_lookup(table,(char *)node,(char **)&dummy)) { - return(*dummy); - } - - Nv = cuddT(N); - Nnv = cuddE(N); - if (N != node) { - Nv = Cudd_Not(Nv); - Nnv = Cudd_Not(Nnv); - } - - /* Recur on the two branches. */ - min_v = bddAnnotateMintermCount(manager,Nv,max,table) / 2.0; - if (min_v == (double)CUDD_OUT_OF_MEM) - return ((double)CUDD_OUT_OF_MEM); - min_nv = bddAnnotateMintermCount(manager,Nnv,max,table) / 2.0; - if (min_nv == (double)CUDD_OUT_OF_MEM) - return ((double)CUDD_OUT_OF_MEM); - min_N = min_v + min_nv; - - pmin = ALLOC(double,1); - if (pmin == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return((double)CUDD_OUT_OF_MEM); - } - *pmin = min_N; - - if (st_insert(table,(char *)node, (char *)pmin) == ST_OUT_OF_MEM) { - FREE(pmin); - return((double)CUDD_OUT_OF_MEM); - } - - return(min_N); - -} /* end of bddAnnotateMintermCount */ |