diff options
Diffstat (limited to 'src/bdd/cudd/cuddPriority.c')
-rw-r--r-- | src/bdd/cudd/cuddPriority.c | 1475 |
1 files changed, 0 insertions, 1475 deletions
diff --git a/src/bdd/cudd/cuddPriority.c b/src/bdd/cudd/cuddPriority.c deleted file mode 100644 index 788fc712..00000000 --- a/src/bdd/cudd/cuddPriority.c +++ /dev/null @@ -1,1475 +0,0 @@ -/**CFile*********************************************************************** - - FileName [cuddPriority.c] - - PackageName [cudd] - - Synopsis [Priority functions.] - - Description [External procedures included in this file: - <ul> - <li> Cudd_PrioritySelect() - <li> Cudd_Xgty() - <li> Cudd_Xeqy() - <li> Cudd_addXeqy() - <li> Cudd_Dxygtdxz() - <li> Cudd_Dxygtdyz() - <li> Cudd_CProjection() - <li> Cudd_addHamming() - <li> Cudd_MinHammingDist() - <li> Cudd_bddClosestCube() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddCProjectionRecur() - <li> cuddBddClosestCube() - </ul> - Static procedures included in this module: - <ul> - <li> cuddMinHammingDistRecur() - <li> separateCube() - <li> createResult() - </ul> - ] - - SeeAlso [] - - 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 */ -/*---------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------*/ -/* Stucture declarations */ -/*---------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------*/ -/* Type declarations */ -/*---------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------*/ -/* Variable declarations */ -/*---------------------------------------------------------------------------*/ - -#ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddPriority.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; -#endif - -/*---------------------------------------------------------------------------*/ -/* Macro declarations */ -/*---------------------------------------------------------------------------*/ - - -/**AutomaticStart*************************************************************/ - -/*---------------------------------------------------------------------------*/ -/* Static function prototypes */ -/*---------------------------------------------------------------------------*/ -static int cuddMinHammingDistRecur ARGS((DdNode * f, int *minterm, DdHashTable * table, int upperBound)); -static DdNode * separateCube ARGS((DdManager *dd, DdNode *f, CUDD_VALUE_TYPE *distance)); -static DdNode * createResult ARGS((DdManager *dd, unsigned int index, unsigned int phase, DdNode *cube, CUDD_VALUE_TYPE distance)); - -/**AutomaticEnd***************************************************************/ - - -/*---------------------------------------------------------------------------*/ -/* Definition of exported functions */ -/*---------------------------------------------------------------------------*/ - - -/**Function******************************************************************** - - Synopsis [Selects pairs from R using a priority function.] - - Description [Selects pairs from a relation R(x,y) (given as a BDD) - in such a way that a given x appears in one pair only. Uses a - priority function to determine which y should be paired to a given x. - Cudd_PrioritySelect returns a pointer to - the selected function if successful; NULL otherwise. - Three of the arguments--x, y, and z--are vectors of BDD variables. - The first two are the variables on which R depends. The third vectore - is a vector of auxiliary variables, used during the computation. This - vector is optional. If a NULL value is passed instead, - Cudd_PrioritySelect will create the working variables on the fly. - The sizes of x and y (and z if it is not NULL) should equal n. - The priority function Pi can be passed as a BDD, or can be built by - Cudd_PrioritySelect. If NULL is passed instead of a DdNode *, - parameter Pifunc is used by Cudd_PrioritySelect to build a BDD for the - priority function. (Pifunc is a pointer to a C function.) If Pi is not - NULL, then Pifunc is ignored. Pifunc should have the same interface as - the standard priority functions (e.g., Cudd_Dxygtdxz). - Cudd_PrioritySelect and Cudd_CProjection can sometimes be used - interchangeably. Specifically, calling Cudd_PrioritySelect with - Cudd_Xgty as Pifunc produces the same result as calling - Cudd_CProjection with the all-zero minterm as reference minterm. - However, depending on the application, one or the other may be - preferable: - <ul> - <li> When extracting representatives from an equivalence relation, - Cudd_CProjection has the advantage of nor requiring the auxiliary - variables. - <li> When computing matchings in general bipartite graphs, - Cudd_PrioritySelect normally obtains better results because it can use - more powerful matching schemes (e.g., Cudd_Dxygtdxz). - </ul> - ] - - SideEffects [If called with z == NULL, will create new variables in - the manager.] - - SeeAlso [Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_Xgty - Cudd_bddAdjPermuteX Cudd_CProjection] - -******************************************************************************/ -DdNode * -Cudd_PrioritySelect( - DdManager * dd /* manager */, - DdNode * R /* BDD of the relation */, - DdNode ** x /* array of x variables */, - DdNode ** y /* array of y variables */, - DdNode ** z /* array of z variables (optional: may be NULL) */, - DdNode * Pi /* BDD of the priority function (optional: may be NULL) */, - int n /* size of x, y, and z */, - DdNode * (*Pifunc)(DdManager *, int, DdNode **, DdNode **, DdNode **) /* function used to build Pi if it is NULL */) -{ - DdNode *res = NULL; - DdNode *zcube = NULL; - DdNode *Rxz, *Q; - int createdZ = 0; - int createdPi = 0; - int i; - - /* Create z variables if needed. */ - if (z == NULL) { - if (Pi != NULL) return(NULL); - z = ALLOC(DdNode *,n); - if (z == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - createdZ = 1; - for (i = 0; i < n; i++) { - if (dd->size >= (int) CUDD_MAXINDEX - 1) goto endgame; - z[i] = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); - if (z[i] == NULL) goto endgame; - } - } - - /* Create priority function BDD if needed. */ - if (Pi == NULL) { - Pi = Pifunc(dd,n,x,y,z); - if (Pi == NULL) goto endgame; - createdPi = 1; - cuddRef(Pi); - } - - /* Initialize abstraction cube. */ - zcube = DD_ONE(dd); - cuddRef(zcube); - for (i = n - 1; i >= 0; i--) { - DdNode *tmpp; - tmpp = Cudd_bddAnd(dd,z[i],zcube); - if (tmpp == NULL) goto endgame; - cuddRef(tmpp); - Cudd_RecursiveDeref(dd,zcube); - zcube = tmpp; - } - - /* Compute subset of (x,y) pairs. */ - Rxz = Cudd_bddSwapVariables(dd,R,y,z,n); - if (Rxz == NULL) goto endgame; - cuddRef(Rxz); - Q = Cudd_bddAndAbstract(dd,Rxz,Pi,zcube); - if (Q == NULL) { - Cudd_RecursiveDeref(dd,Rxz); - goto endgame; - } - cuddRef(Q); - Cudd_RecursiveDeref(dd,Rxz); - res = Cudd_bddAnd(dd,R,Cudd_Not(Q)); - if (res == NULL) { - Cudd_RecursiveDeref(dd,Q); - goto endgame; - } - cuddRef(res); - Cudd_RecursiveDeref(dd,Q); - -endgame: - if (zcube != NULL) Cudd_RecursiveDeref(dd,zcube); - if (createdZ) { - FREE(z); - } - if (createdPi) { - Cudd_RecursiveDeref(dd,Pi); - } - if (res != NULL) cuddDeref(res); - return(res); - -} /* Cudd_PrioritySelect */ - - -/**Function******************************************************************** - - Synopsis [Generates a BDD for the function x > y.] - - Description [This function generates a BDD for the function x > y. - Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and - y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. - The BDD is built bottom-up. - It has 3*N-1 internal nodes, if the variables are ordered as follows: - x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. - Argument z is not used by Cudd_Xgty: it is included to make it - call-compatible to Cudd_Dxygtdxz and Cudd_Dxygtdyz.] - - SideEffects [None] - - SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Dxygtdyz] - -******************************************************************************/ -DdNode * -Cudd_Xgty( - DdManager * dd /* DD manager */, - int N /* number of x and y variables */, - DdNode ** z /* array of z variables: unused */, - DdNode ** x /* array of x variables */, - DdNode ** y /* array of y variables */) -{ - DdNode *u, *v, *w; - int i; - - /* Build bottom part of BDD outside loop. */ - u = Cudd_bddAnd(dd, x[N-1], Cudd_Not(y[N-1])); - if (u == NULL) return(NULL); - cuddRef(u); - - /* Loop to build the rest of the BDD. */ - for (i = N-2; i >= 0; i--) { - v = Cudd_bddAnd(dd, y[i], Cudd_Not(u)); - if (v == NULL) { - Cudd_RecursiveDeref(dd, u); - return(NULL); - } - cuddRef(v); - w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); - if (w == NULL) { - Cudd_RecursiveDeref(dd, u); - Cudd_RecursiveDeref(dd, v); - return(NULL); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, u); - u = Cudd_bddIte(dd, x[i], Cudd_Not(v), w); - if (u == NULL) { - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(u); - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); - - } - cuddDeref(u); - return(u); - -} /* end of Cudd_Xgty */ - - -/**Function******************************************************************** - - Synopsis [Generates a BDD for the function x==y.] - - Description [This function generates a BDD for the function x==y. - Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and - y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. - The BDD is built bottom-up. - It has 3*N-1 internal nodes, if the variables are ordered as follows: - x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ] - - SideEffects [None] - - SeeAlso [Cudd_addXeqy] - -******************************************************************************/ -DdNode * -Cudd_Xeqy( - DdManager * dd /* DD manager */, - int N /* number of x and y variables */, - DdNode ** x /* array of x variables */, - DdNode ** y /* array of y variables */) -{ - DdNode *u, *v, *w; - int i; - - /* Build bottom part of BDD outside loop. */ - u = Cudd_bddIte(dd, x[N-1], y[N-1], Cudd_Not(y[N-1])); - if (u == NULL) return(NULL); - cuddRef(u); - - /* Loop to build the rest of the BDD. */ - for (i = N-2; i >= 0; i--) { - v = Cudd_bddAnd(dd, y[i], u); - if (v == NULL) { - Cudd_RecursiveDeref(dd, u); - return(NULL); - } - cuddRef(v); - w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); - if (w == NULL) { - Cudd_RecursiveDeref(dd, u); - Cudd_RecursiveDeref(dd, v); - return(NULL); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, u); - u = Cudd_bddIte(dd, x[i], v, w); - if (u == NULL) { - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(u); - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); - } - cuddDeref(u); - return(u); - -} /* end of Cudd_Xeqy */ - - -/**Function******************************************************************** - - Synopsis [Generates an ADD for the function x==y.] - - Description [This function generates an ADD for the function x==y. - Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and - y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. - The ADD is built bottom-up. - It has 3*N-1 internal nodes, if the variables are ordered as follows: - x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ] - - SideEffects [None] - - SeeAlso [Cudd_Xeqy] - -******************************************************************************/ -DdNode * -Cudd_addXeqy( - DdManager * dd /* DD manager */, - int N /* number of x and y variables */, - DdNode ** x /* array of x variables */, - DdNode ** y /* array of y variables */) -{ - DdNode *one, *zero; - DdNode *u, *v, *w; - int i; - - one = DD_ONE(dd); - zero = DD_ZERO(dd); - - /* Build bottom part of ADD outside loop. */ - v = Cudd_addIte(dd, y[N-1], one, zero); - if (v == NULL) return(NULL); - cuddRef(v); - w = Cudd_addIte(dd, y[N-1], zero, one); - if (w == NULL) { - Cudd_RecursiveDeref(dd, v); - return(NULL); - } - cuddRef(w); - u = Cudd_addIte(dd, x[N-1], v, w); - if (w == NULL) { - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(u); - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); - - /* Loop to build the rest of the ADD. */ - for (i = N-2; i >= 0; i--) { - v = Cudd_addIte(dd, y[i], u, zero); - if (v == NULL) { - Cudd_RecursiveDeref(dd, u); - return(NULL); - } - cuddRef(v); - w = Cudd_addIte(dd, y[i], zero, u); - if (w == NULL) { - Cudd_RecursiveDeref(dd, u); - Cudd_RecursiveDeref(dd, v); - return(NULL); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, u); - u = Cudd_addIte(dd, x[i], v, w); - if (w == NULL) { - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(u); - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); - } - cuddDeref(u); - return(u); - -} /* end of Cudd_addXeqy */ - - -/**Function******************************************************************** - - Synopsis [Generates a BDD for the function d(x,y) > d(x,z).] - - Description [This function generates a BDD for the function d(x,y) - > d(x,z); - x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\], - y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\], - with 0 the most significant bit. - The distance d(x,y) is defined as: - \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). - The BDD is built bottom-up. - It has 7*N-3 internal nodes, if the variables are ordered as follows: - x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ] - - SideEffects [None] - - SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdyz Cudd_Xgty Cudd_bddAdjPermuteX] - -******************************************************************************/ -DdNode * -Cudd_Dxygtdxz( - DdManager * dd /* DD manager */, - int N /* number of x, y, and z variables */, - DdNode ** x /* array of x variables */, - DdNode ** y /* array of y variables */, - DdNode ** z /* array of z variables */) -{ - DdNode *one, *zero; - DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1; - int i; - - one = DD_ONE(dd); - zero = Cudd_Not(one); - - /* Build bottom part of BDD outside loop. */ - y1_ = Cudd_bddIte(dd, y[N-1], one, Cudd_Not(z[N-1])); - if (y1_ == NULL) return(NULL); - cuddRef(y1_); - y2 = Cudd_bddIte(dd, y[N-1], z[N-1], one); - if (y2 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - return(NULL); - } - cuddRef(y2); - x1 = Cudd_bddIte(dd, x[N-1], y1_, y2); - if (x1 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); - return(NULL); - } - cuddRef(x1); - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); - - /* Loop to build the rest of the BDD. */ - for (i = N-2; i >= 0; i--) { - z1 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); - if (z1 == NULL) { - Cudd_RecursiveDeref(dd, x1); - return(NULL); - } - cuddRef(z1); - z2 = Cudd_bddIte(dd, z[i], x1, one); - if (z2 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - return(NULL); - } - cuddRef(z2); - z3 = Cudd_bddIte(dd, z[i], one, x1); - if (z3 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - return(NULL); - } - cuddRef(z3); - z4 = Cudd_bddIte(dd, z[i], x1, zero); - if (z4 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - return(NULL); - } - cuddRef(z4); - Cudd_RecursiveDeref(dd, x1); - y1_ = Cudd_bddIte(dd, y[i], z2, Cudd_Not(z1)); - if (y1_ == NULL) { - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - return(NULL); - } - cuddRef(y1_); - y2 = Cudd_bddIte(dd, y[i], z4, z3); - if (y2 == NULL) { - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - Cudd_RecursiveDeref(dd, y1_); - return(NULL); - } - cuddRef(y2); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - x1 = Cudd_bddIte(dd, x[i], y1_, y2); - if (x1 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); - return(NULL); - } - cuddRef(x1); - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); - } - cuddDeref(x1); - return(Cudd_Not(x1)); - -} /* end of Cudd_Dxygtdxz */ - - -/**Function******************************************************************** - - Synopsis [Generates a BDD for the function d(x,y) > d(y,z).] - - Description [This function generates a BDD for the function d(x,y) - > d(y,z); - x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\], - y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\], - with 0 the most significant bit. - The distance d(x,y) is defined as: - \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). - The BDD is built bottom-up. - It has 7*N-3 internal nodes, if the variables are ordered as follows: - x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ] - - SideEffects [None] - - SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Xgty Cudd_bddAdjPermuteX] - -******************************************************************************/ -DdNode * -Cudd_Dxygtdyz( - DdManager * dd /* DD manager */, - int N /* number of x, y, and z variables */, - DdNode ** x /* array of x variables */, - DdNode ** y /* array of y variables */, - DdNode ** z /* array of z variables */) -{ - DdNode *one, *zero; - DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1; - int i; - - one = DD_ONE(dd); - zero = Cudd_Not(one); - - /* Build bottom part of BDD outside loop. */ - y1_ = Cudd_bddIte(dd, y[N-1], one, z[N-1]); - if (y1_ == NULL) return(NULL); - cuddRef(y1_); - y2 = Cudd_bddIte(dd, y[N-1], z[N-1], zero); - if (y2 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - return(NULL); - } - cuddRef(y2); - x1 = Cudd_bddIte(dd, x[N-1], y1_, Cudd_Not(y2)); - if (x1 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); - return(NULL); - } - cuddRef(x1); - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); - - /* Loop to build the rest of the BDD. */ - for (i = N-2; i >= 0; i--) { - z1 = Cudd_bddIte(dd, z[i], x1, zero); - if (z1 == NULL) { - Cudd_RecursiveDeref(dd, x1); - return(NULL); - } - cuddRef(z1); - z2 = Cudd_bddIte(dd, z[i], x1, one); - if (z2 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - return(NULL); - } - cuddRef(z2); - z3 = Cudd_bddIte(dd, z[i], one, x1); - if (z3 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - return(NULL); - } - cuddRef(z3); - z4 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); - if (z4 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - return(NULL); - } - cuddRef(z4); - Cudd_RecursiveDeref(dd, x1); - y1_ = Cudd_bddIte(dd, y[i], z2, z1); - if (y1_ == NULL) { - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - return(NULL); - } - cuddRef(y1_); - y2 = Cudd_bddIte(dd, y[i], z4, Cudd_Not(z3)); - if (y2 == NULL) { - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - Cudd_RecursiveDeref(dd, y1_); - return(NULL); - } - cuddRef(y2); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - x1 = Cudd_bddIte(dd, x[i], y1_, Cudd_Not(y2)); - if (x1 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); - return(NULL); - } - cuddRef(x1); - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); - } - cuddDeref(x1); - return(Cudd_Not(x1)); - -} /* end of Cudd_Dxygtdyz */ - - -/**Function******************************************************************** - - Synopsis [Computes the compatible projection of R w.r.t. cube Y.] - - Description [Computes the compatible projection of relation R with - respect to cube Y. Returns a pointer to the c-projection if - successful; NULL otherwise. For a comparison between Cudd_CProjection - and Cudd_PrioritySelect, see the documentation of the latter.] - - SideEffects [None] - - SeeAlso [Cudd_PrioritySelect] - -******************************************************************************/ -DdNode * -Cudd_CProjection( - DdManager * dd, - DdNode * R, - DdNode * Y) -{ - DdNode *res; - DdNode *support; - - if (cuddCheckCube(dd,Y) == 0) { - (void) fprintf(dd->err, - "Error: The third argument of Cudd_CProjection should be a cube\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); - } - - /* Compute the support of Y, which is used by the abstraction step - ** in cuddCProjectionRecur. - */ - support = Cudd_Support(dd,Y); - if (support == NULL) return(NULL); - cuddRef(support); - - do { - dd->reordered = 0; - res = cuddCProjectionRecur(dd,R,Y,support); - } while (dd->reordered == 1); - - if (res == NULL) { - Cudd_RecursiveDeref(dd,support); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(dd,support); - cuddDeref(res); - - return(res); - -} /* end of Cudd_CProjection */ - - -/**Function******************************************************************** - - Synopsis [Computes the Hamming distance ADD.] - - Description [Computes the Hamming distance ADD. Returns an ADD that - gives the Hamming distance between its two arguments if successful; - NULL otherwise. The two vectors xVars and yVars identify the variables - that form the two arguments.] - - SideEffects [None] - - SeeAlso [] - -******************************************************************************/ -DdNode * -Cudd_addHamming( - DdManager * dd, - DdNode ** xVars, - DdNode ** yVars, - int nVars) -{ - DdNode *result,*tempBdd; - DdNode *tempAdd,*temp; - int i; - - result = DD_ZERO(dd); - cuddRef(result); - - for (i = 0; i < nVars; i++) { - tempBdd = Cudd_bddIte(dd,xVars[i],Cudd_Not(yVars[i]),yVars[i]); - if (tempBdd == NULL) { - Cudd_RecursiveDeref(dd,result); - return(NULL); - } - cuddRef(tempBdd); - tempAdd = Cudd_BddToAdd(dd,tempBdd); - if (tempAdd == NULL) { - Cudd_RecursiveDeref(dd,tempBdd); - Cudd_RecursiveDeref(dd,result); - return(NULL); - } - cuddRef(tempAdd); - Cudd_RecursiveDeref(dd,tempBdd); - temp = Cudd_addApply(dd,Cudd_addPlus,tempAdd,result); - if (temp == NULL) { - Cudd_RecursiveDeref(dd,tempAdd); - Cudd_RecursiveDeref(dd,result); - return(NULL); - } - cuddRef(temp); - Cudd_RecursiveDeref(dd,tempAdd); - Cudd_RecursiveDeref(dd,result); - result = temp; - } - - cuddDeref(result); - return(result); - -} /* end of Cudd_addHamming */ - - -/**Function******************************************************************** - - Synopsis [Returns the minimum Hamming distance between f and minterm.] - - Description [Returns the minimum Hamming distance between the - minterms of a function f and a reference minterm. The function is - given as a BDD; the minterm is given as an array of integers, one - for each variable in the manager. Returns the minimum distance if - it is less than the upper bound; the upper bound if the minimum - distance is at least as large; CUDD_OUT_OF_MEM in case of failure.] - - SideEffects [None] - - SeeAlso [Cudd_addHamming Cudd_bddClosestCube] - -******************************************************************************/ -int -Cudd_MinHammingDist( - DdManager *dd /* DD manager */, - DdNode *f /* function to examine */, - int *minterm /* reference minterm */, - int upperBound /* distance above which an approximate answer is OK */) -{ - DdHashTable *table; - CUDD_VALUE_TYPE epsilon; - int res; - - table = cuddHashTableInit(dd,1,2); - if (table == NULL) { - return(CUDD_OUT_OF_MEM); - } - epsilon = Cudd_ReadEpsilon(dd); - Cudd_SetEpsilon(dd,(CUDD_VALUE_TYPE)0.0); - res = cuddMinHammingDistRecur(f,minterm,table,upperBound); - cuddHashTableQuit(table); - Cudd_SetEpsilon(dd,epsilon); - - return(res); - -} /* end of Cudd_MinHammingDist */ - - -/**Function******************************************************************** - - Synopsis [Finds a cube of f at minimum Hamming distance from g.] - - Description [Finds a cube of f at minimum Hamming distance from the - minterms of g. All the minterms of the cube are at the minimum - distance. If the distance is 0, the cube belongs to the - intersection of f and g. Returns the cube if successful; NULL - otherwise.] - - SideEffects [The distance is returned as a side effect.] - - SeeAlso [Cudd_MinHammingDist] - -******************************************************************************/ -DdNode * -Cudd_bddClosestCube( - DdManager *dd, - DdNode * f, - DdNode *g, - int *distance) -{ - DdNode *res, *acube; - CUDD_VALUE_TYPE rdist; - - /* Compute the cube and distance as a single ADD. */ - do { - dd->reordered = 0; - res = cuddBddClosestCube(dd,f,g,CUDD_CONST_INDEX + 1.0); - } while (dd->reordered == 1); - if (res == NULL) return(NULL); - cuddRef(res); - - /* Unpack distance and cube. */ - do { - dd->reordered = 0; - acube = separateCube(dd, res, &rdist); - } while (dd->reordered == 1); - if (acube == NULL) { - Cudd_RecursiveDeref(dd, res); - return(NULL); - } - cuddRef(acube); - Cudd_RecursiveDeref(dd, res); - - /* Convert cube from ADD to BDD. */ - do { - dd->reordered = 0; - res = cuddAddBddDoPattern(dd, acube); - } while (dd->reordered == 1); - if (res == NULL) { - Cudd_RecursiveDeref(dd, acube); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(dd, acube); - - *distance = (int) rdist; - cuddDeref(res); - return(res); - -} /* end of Cudd_bddClosestCube */ - - -/*---------------------------------------------------------------------------*/ -/* Definition of internal functions */ -/*---------------------------------------------------------------------------*/ - - -/**Function******************************************************************** - - Synopsis [Performs the recursive step of Cudd_CProjection.] - - Description [Performs the recursive step of Cudd_CProjection. Returns - the projection if successful; NULL otherwise.] - - SideEffects [None] - - SeeAlso [Cudd_CProjection] - -******************************************************************************/ -DdNode * -cuddCProjectionRecur( - DdManager * dd, - DdNode * R, - DdNode * Y, - DdNode * Ysupp) -{ - DdNode *res, *res1, *res2, *resA; - DdNode *r, *y, *RT, *RE, *YT, *YE, *Yrest, *Ra, *Ran, *Gamma, *Alpha; - unsigned int topR, topY, top, index; - DdNode *one = DD_ONE(dd); - - statLine(dd); - if (Y == one) return(R); - -#ifdef DD_DEBUG - assert(!Cudd_IsConstant(Y)); -#endif - - if (R == Cudd_Not(one)) return(R); - - res = cuddCacheLookup2(dd, Cudd_CProjection, R, Y); - if (res != NULL) return(res); - - r = Cudd_Regular(R); - topR = cuddI(dd,r->index); - y = Cudd_Regular(Y); - topY = cuddI(dd,y->index); - - top = ddMin(topR, topY); - - /* Compute the cofactors of R */ - if (topR == top) { - index = r->index; - RT = cuddT(r); - RE = cuddE(r); - if (r != R) { - RT = Cudd_Not(RT); RE = Cudd_Not(RE); - } - } else { - RT = RE = R; - } - - if (topY > top) { - /* Y does not depend on the current top variable. - ** We just need to compute the results on the two cofactors of R - ** and make them the children of a node labeled r->index. - */ - res1 = cuddCProjectionRecur(dd,RT,Y,Ysupp); - if (res1 == NULL) return(NULL); - cuddRef(res1); - res2 = cuddCProjectionRecur(dd,RE,Y,Ysupp); - if (res2 == NULL) { - Cudd_RecursiveDeref(dd,res1); - return(NULL); - } - cuddRef(res2); - res = cuddBddIteRecur(dd, dd->vars[index], res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(dd,res1); - Cudd_RecursiveDeref(dd,res2); - return(NULL); - } - /* If we have reached this point, res1 and res2 are now - ** incorporated in res. cuddDeref is therefore sufficient. - */ - cuddDeref(res1); - cuddDeref(res2); - } else { - /* Compute the cofactors of Y */ - index = y->index; - YT = cuddT(y); - YE = cuddE(y); - if (y != Y) { - YT = Cudd_Not(YT); YE = Cudd_Not(YE); - } - if (YT == Cudd_Not(one)) { - Alpha = Cudd_Not(dd->vars[index]); - Yrest = YE; - Ra = RE; - Ran = RT; - } else { - Alpha = dd->vars[index]; - Yrest = YT; - Ra = RT; - Ran = RE; - } - Gamma = cuddBddExistAbstractRecur(dd,Ra,cuddT(Ysupp)); - if (Gamma == NULL) return(NULL); - if (Gamma == one) { - res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); - if (res1 == NULL) return(NULL); - cuddRef(res1); - res = cuddBddAndRecur(dd, Alpha, res1); - if (res == NULL) { - Cudd_RecursiveDeref(dd,res1); - return(NULL); - } - cuddDeref(res1); - } else if (Gamma == Cudd_Not(one)) { - res1 = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); - if (res1 == NULL) return(NULL); - cuddRef(res1); - res = cuddBddAndRecur(dd, Cudd_Not(Alpha), res1); - if (res == NULL) { - Cudd_RecursiveDeref(dd,res1); - return(NULL); - } - cuddDeref(res1); - } else { - cuddRef(Gamma); - resA = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); - if (resA == NULL) { - Cudd_RecursiveDeref(dd,Gamma); - return(NULL); - } - cuddRef(resA); - res2 = cuddBddAndRecur(dd, Cudd_Not(Gamma), resA); - if (res2 == NULL) { - Cudd_RecursiveDeref(dd,Gamma); - Cudd_RecursiveDeref(dd,resA); - return(NULL); - } - cuddRef(res2); - Cudd_RecursiveDeref(dd,Gamma); - Cudd_RecursiveDeref(dd,resA); - res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); - if (res1 == NULL) { - Cudd_RecursiveDeref(dd,res2); - return(NULL); - } - cuddRef(res1); - res = cuddBddIteRecur(dd, Alpha, res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(dd,res1); - Cudd_RecursiveDeref(dd,res2); - return(NULL); - } - cuddDeref(res1); - cuddDeref(res2); - } - } - - cuddCacheInsert2(dd,Cudd_CProjection,R,Y,res); - - return(res); - -} /* end of cuddCProjectionRecur */ - - -/**Function******************************************************************** - - Synopsis [Performs the recursive step of Cudd_bddClosestCube.] - - Description [Performs the recursive step of Cudd_bddClosestCube. - Returns the cube if succesful; NULL otherwise. The procedure uses a - four-way recursion to examine all four combinations of cofactors of - f and g. The most interesting feature of this function is the - scheme used for caching the results in the global computed table. - Since we have a cube and a distance, we combine them to form an ADD. - The combination replaces the zero child of the top node of the cube - with the negative of the distance. (The use of the negative is to - avoid ambiguity with 1.) The degenerate cases (zero and one) are - treated specially because the distance is known (0 for one, and - infinity for zero).] - - SideEffects [None] - - SeeAlso [Cudd_bddClosestCube] - -******************************************************************************/ -DdNode * -cuddBddClosestCube( - DdManager *dd, - DdNode *f, - DdNode *g, - CUDD_VALUE_TYPE bound) -{ - DdNode *res, *F, *G, *ft, *fe, *gt, *ge, *tt, *ee; - DdNode *ctt, *cee, *cte, *cet; - CUDD_VALUE_TYPE minD, dtt, dee, dte, det; - DdNode *one = DD_ONE(dd); - DdNode *lzero = Cudd_Not(one); - DdNode *azero = DD_ZERO(dd); - unsigned int topf, topg, index; - - statLine(dd); - if (bound < (f == Cudd_Not(g))) return(azero); - /* Terminal cases. */ - if (g == lzero || f == lzero) return(azero); - if (f == one && g == one) return(one); - - /* Check cache. */ - F = Cudd_Regular(f); - G = Cudd_Regular(g); - if (F->ref != 1 || G->ref != 1) { - res = cuddCacheLookup2(dd,(DdNode * (*)(DdManager *, DdNode *, - DdNode *)) Cudd_bddClosestCube, f, g); - if (res != NULL) return(res); - } - - topf = cuddI(dd,F->index); - topg = cuddI(dd,G->index); - - /* Compute cofactors. */ - if (topf <= topg) { - index = F->index; - ft = cuddT(F); - fe = cuddE(F); - if (Cudd_IsComplement(f)) { - ft = Cudd_Not(ft); - fe = Cudd_Not(fe); - } - } else { - index = G->index; - ft = fe = f; - } - - if (topg <= topf) { - gt = cuddT(G); - ge = cuddE(G); - if (Cudd_IsComplement(g)) { - gt = Cudd_Not(gt); - ge = Cudd_Not(ge); - } - } else { - gt = ge = g; - } - - tt = cuddBddClosestCube(dd,ft,gt,bound); - if (tt == NULL) return(NULL); - cuddRef(tt); - ctt = separateCube(dd,tt,&dtt); - if (ctt == NULL) { - Cudd_RecursiveDeref(dd, tt); - return(NULL); - } - cuddRef(ctt); - Cudd_RecursiveDeref(dd, tt); - minD = dtt; - bound = ddMin(bound,minD); - - ee = cuddBddClosestCube(dd,fe,ge,bound); - if (ee == NULL) { - Cudd_RecursiveDeref(dd, ctt); - return(NULL); - } - cuddRef(ee); - cee = separateCube(dd,ee,&dee); - if (cee == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, ee); - return(NULL); - } - cuddRef(cee); - Cudd_RecursiveDeref(dd, ee); - minD = ddMin(dtt, dee); - bound = ddMin(bound,minD-1); - - if (minD > 0 && topf == topg) { - DdNode *te = cuddBddClosestCube(dd,ft,ge,bound-1); - if (te == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); - return(NULL); - } - cuddRef(te); - cte = separateCube(dd,te,&dte); - if (cte == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); - Cudd_RecursiveDeref(dd, te); - return(NULL); - } - cuddRef(cte); - Cudd_RecursiveDeref(dd, te); - dte += 1.0; - minD = ddMin(minD, dte); - } else { - cte = azero; - cuddRef(cte); - dte = CUDD_CONST_INDEX + 1.0; - } - bound = ddMin(bound,minD-1); - - if (minD > 0 && topf == topg) { - DdNode *et = cuddBddClosestCube(dd,fe,gt,bound-1); - if (et == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); - Cudd_RecursiveDeref(dd, cte); - return(NULL); - } - cuddRef(et); - cet = separateCube(dd,et,&det); - if (cet == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); - Cudd_RecursiveDeref(dd, cte); - Cudd_RecursiveDeref(dd, et); - return(NULL); - } - cuddRef(cet); - Cudd_RecursiveDeref(dd, et); - det += 1.0; - minD = ddMin(minD, det); - } else { - cet = azero; - cuddRef(cet); - det = CUDD_CONST_INDEX + 1.0; - } - - if (minD == dtt) { - if (dtt == dee && ctt == cee) { - res = createResult(dd,CUDD_CONST_INDEX,1,ctt,dtt); - } else { - res = createResult(dd,index,1,ctt,dtt); - } - } else if (minD == dee) { - res = createResult(dd,index,0,cee,dee); - } else if (minD == dte) { - res = createResult(dd,index,(topf <= topg),cte,dte); - } else { - res = createResult(dd,index,(topf > topg),cet,det); - } - cuddRef(res); - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); - Cudd_RecursiveDeref(dd, cte); - Cudd_RecursiveDeref(dd, cet); - - if (F->ref != 1 || G->ref != 1) - cuddCacheInsert2(dd,(DdNode * (*)(DdManager *, DdNode *, - DdNode *)) Cudd_bddClosestCube, f, g, res); - - cuddDeref(res); - return(res); - -} /* end of cuddBddClosestCube */ - - -/*---------------------------------------------------------------------------*/ -/* Definition of static functions */ -/*---------------------------------------------------------------------------*/ - - -/**Function******************************************************************** - - Synopsis [Performs the recursive step of Cudd_MinHammingDist.] - - Description [Performs the recursive step of Cudd_MinHammingDist. - It is based on the following identity. Let H(f) be the - minimum Hamming distance of the minterms of f from the reference - minterm. Then: - <xmp> - H(f) = min(H(f0)+h0,H(f1)+h1) - </xmp> - where f0 and f1 are the two cofactors of f with respect to its top - variable; h0 is 1 if the minterm assigns 1 to the top variable of f; - h1 is 1 if the minterm assigns 0 to the top variable of f. - The upper bound on the distance is used to bound the depth of the - recursion. - Returns the minimum distance unless it exceeds the upper bound or - computation fails.] - - SideEffects [None] - - SeeAlso [Cudd_MinHammingDist] - -******************************************************************************/ -static int -cuddMinHammingDistRecur( - DdNode * f, - int *minterm, - DdHashTable * table, - int upperBound) -{ - DdNode *F, *Ft, *Fe; - double h, hT, hE; - DdNode *zero, *res; - DdManager *dd = table->manager; - - statLine(dd); - if (upperBound == 0) return(0); - - F = Cudd_Regular(f); - - if (cuddIsConstant(F)) { - zero = Cudd_Not(DD_ONE(dd)); - if (f == dd->background || f == zero) { - return(upperBound); - } else { - return(0); - } - } - if ((res = cuddHashTableLookup1(table,f)) != NULL) { - h = cuddV(res); - if (res->ref == 0) { - dd->dead++; - dd->constants.dead++; - } - return((int) h); - } - - Ft = cuddT(F); Fe = cuddE(F); - if (Cudd_IsComplement(f)) { - Ft = Cudd_Not(Ft); Fe = Cudd_Not(Fe); - } - if (minterm[F->index] == 0) { - DdNode *temp = Ft; - Ft = Fe; Fe = temp; - } - - hT = cuddMinHammingDistRecur(Ft,minterm,table,upperBound); - if (hT == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); - if (hT == 0) { - hE = upperBound; - } else { - hE = cuddMinHammingDistRecur(Fe,minterm,table,upperBound - 1); - if (hE == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); - } - h = ddMin(hT, hE + 1); - - if (F->ref != 1) { - ptrint fanout = (ptrint) F->ref; - cuddSatDec(fanout); - res = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) h); - if (!cuddHashTableInsert1(table,f,res,fanout)) { - cuddRef(res); Cudd_RecursiveDeref(dd, res); - return(CUDD_OUT_OF_MEM); - } - } - - return((int) h); - -} /* end of cuddMinHammingDistRecur */ - - -/**Function******************************************************************** - - Synopsis [Separates cube from distance.] - - Description [Separates cube from distance. Returns the cube if - successful; NULL otherwise.] - - SideEffects [The distance is returned as a side effect.] - - SeeAlso [cuddBddClosestCube createResult] - -******************************************************************************/ -static DdNode * -separateCube( - DdManager *dd, - DdNode *f, - CUDD_VALUE_TYPE *distance) -{ - DdNode *cube, *t; - - /* One and zero are special cases because the distance is implied. */ - if (Cudd_IsConstant(f)) { - *distance = (f == DD_ONE(dd)) ? 0.0 : - (1.0 + (CUDD_VALUE_TYPE) CUDD_CONST_INDEX); - return(f); - } - - /* Find out which branch points to the distance and replace the top - ** node with one pointing to zero instead. */ - t = cuddT(f); - if (Cudd_IsConstant(t) && cuddV(t) <= 0) { -#ifdef DD_DEBUG - assert(!Cudd_IsConstant(cuddE(f)) || cuddE(f) == DD_ONE(dd)); -#endif - *distance = -cuddV(t); - cube = cuddUniqueInter(dd, f->index, DD_ZERO(dd), cuddE(f)); - } else { -#ifdef DD_DEBUG - assert(!Cudd_IsConstant(t) || t == DD_ONE(dd)); -#endif - *distance = -cuddV(cuddE(f)); - cube = cuddUniqueInter(dd, f->index, t, DD_ZERO(dd)); - } - - return(cube); - -} /* end of separateCube */ - - -/**Function******************************************************************** - - Synopsis [Builds a result for cache storage.] - - Description [Builds a result for cache storage. Returns a pointer - to the resulting ADD if successful; NULL otherwise.] - - SideEffects [None] - - SeeAlso [cuddBddClosestCube separateCube] - -******************************************************************************/ -static DdNode * -createResult( - DdManager *dd, - unsigned int index, - unsigned int phase, - DdNode *cube, - CUDD_VALUE_TYPE distance) -{ - DdNode *res, *constant; - - /* Special case. The cube is either one or zero, and we do not - ** add any variables. Hence, the result is also one or zero, - ** and the distance remains implied by teh value of the constant. */ - if (index == CUDD_CONST_INDEX && Cudd_IsConstant(cube)) return(cube); - - constant = cuddUniqueConst(dd,-distance); - if (constant == NULL) return(NULL); - cuddRef(constant); - - if (index == CUDD_CONST_INDEX) { - /* Replace the top node. */ - if (cuddT(cube) == DD_ZERO(dd)) { - res = cuddUniqueInter(dd,cube->index,constant,cuddE(cube)); - } else { - res = cuddUniqueInter(dd,cube->index,cuddT(cube),constant); - } - } else { - /* Add a new top node. */ -#ifdef DD_DEBUG - assert(cuddI(dd,index) < cuddI(dd,cube->index)); -#endif - if (phase) { - res = cuddUniqueInter(dd,index,cube,constant); - } else { - res = cuddUniqueInter(dd,index,constant,cube); - } - } - if (res == NULL) { - Cudd_RecursiveDeref(dd, constant); - return(NULL); - } - cuddDeref(constant); /* safe because constant is part of res */ - - return(res); - -} /* end of createResult */ |