#include "util.h"
#include "cuddInt.h"
Go to the source code of this file.
Defines | |
#define | DD_DEBUG 1 |
Functions | |
static int | cuddMinHammingDistRecur (DdNode *f, int *minterm, DdHashTable *table, int upperBound) |
static DdNode * | separateCube (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE *distance) |
static DdNode * | createResult (DdManager *dd, unsigned int index, unsigned int phase, DdNode *cube, CUDD_VALUE_TYPE distance) |
DdNode * | Cudd_PrioritySelect (DdManager *dd, DdNode *R, DdNode **x, DdNode **y, DdNode **z, DdNode *Pi, int n, DD_PRFP Pifunc) |
DdNode * | Cudd_Xgty (DdManager *dd, int N, DdNode **z, DdNode **x, DdNode **y) |
DdNode * | Cudd_Xeqy (DdManager *dd, int N, DdNode **x, DdNode **y) |
DdNode * | Cudd_addXeqy (DdManager *dd, int N, DdNode **x, DdNode **y) |
DdNode * | Cudd_Dxygtdxz (DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z) |
DdNode * | Cudd_Dxygtdyz (DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z) |
DdNode * | Cudd_Inequality (DdManager *dd, int N, int c, DdNode **x, DdNode **y) |
DdNode * | Cudd_Disequality (DdManager *dd, int N, int c, DdNode **x, DdNode **y) |
DdNode * | Cudd_bddInterval (DdManager *dd, int N, DdNode **x, unsigned int lowerB, unsigned int upperB) |
DdNode * | Cudd_CProjection (DdManager *dd, DdNode *R, DdNode *Y) |
DdNode * | Cudd_addHamming (DdManager *dd, DdNode **xVars, DdNode **yVars, int nVars) |
int | Cudd_MinHammingDist (DdManager *dd, DdNode *f, int *minterm, int upperBound) |
DdNode * | Cudd_bddClosestCube (DdManager *dd, DdNode *f, DdNode *g, int *distance) |
DdNode * | cuddCProjectionRecur (DdManager *dd, DdNode *R, DdNode *Y, DdNode *Ysupp) |
DdNode * | cuddBddClosestCube (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE bound) |
Variables | |
static char rcsid[] | DD_UNUSED = "$Id: cuddPriority.c,v 1.33 2009/02/20 02:14:58 fabio Exp $" |
#define DD_DEBUG 1 |
CFile***********************************************************************
FileName [cuddPriority.c]
PackageName [cudd]
Synopsis [Priority functions.]
Description [External procedures included in this file:
Internal procedures included in this module:
Static procedures included in this module:
]
SeeAlso []
Author [Fabio Somenzi]
Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]
Definition at line 84 of file cuddPriority.c.
static DdNode * createResult | ( | DdManager * | dd, | |
unsigned int | index, | |||
unsigned int | phase, | |||
DdNode * | cube, | |||
CUDD_VALUE_TYPE | distance | |||
) | [static] |
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]
Definition at line 1983 of file cuddPriority.c.
01989 { 01990 DdNode *res, *constant; 01991 01992 /* Special case. The cube is either one or zero, and we do not 01993 ** add any variables. Hence, the result is also one or zero, 01994 ** and the distance remains implied by the value of the constant. */ 01995 if (index == CUDD_CONST_INDEX && Cudd_IsConstant(cube)) return(cube); 01996 01997 constant = cuddUniqueConst(dd,-distance); 01998 if (constant == NULL) return(NULL); 01999 cuddRef(constant); 02000 02001 if (index == CUDD_CONST_INDEX) { 02002 /* Replace the top node. */ 02003 if (cuddT(cube) == DD_ZERO(dd)) { 02004 res = cuddUniqueInter(dd,cube->index,constant,cuddE(cube)); 02005 } else { 02006 res = cuddUniqueInter(dd,cube->index,cuddT(cube),constant); 02007 } 02008 } else { 02009 /* Add a new top node. */ 02010 #ifdef DD_DEBUG 02011 assert(cuddI(dd,index) < cuddI(dd,cube->index)); 02012 #endif 02013 if (phase) { 02014 res = cuddUniqueInter(dd,index,cube,constant); 02015 } else { 02016 res = cuddUniqueInter(dd,index,constant,cube); 02017 } 02018 } 02019 if (res == NULL) { 02020 Cudd_RecursiveDeref(dd, constant); 02021 return(NULL); 02022 } 02023 cuddDeref(constant); /* safe because constant is part of res */ 02024 02025 return(res); 02026 02027 } /* end of createResult */
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 []
Definition at line 1251 of file cuddPriority.c.
01256 { 01257 DdNode *result,*tempBdd; 01258 DdNode *tempAdd,*temp; 01259 int i; 01260 01261 result = DD_ZERO(dd); 01262 cuddRef(result); 01263 01264 for (i = 0; i < nVars; i++) { 01265 tempBdd = Cudd_bddIte(dd,xVars[i],Cudd_Not(yVars[i]),yVars[i]); 01266 if (tempBdd == NULL) { 01267 Cudd_RecursiveDeref(dd,result); 01268 return(NULL); 01269 } 01270 cuddRef(tempBdd); 01271 tempAdd = Cudd_BddToAdd(dd,tempBdd); 01272 if (tempAdd == NULL) { 01273 Cudd_RecursiveDeref(dd,tempBdd); 01274 Cudd_RecursiveDeref(dd,result); 01275 return(NULL); 01276 } 01277 cuddRef(tempAdd); 01278 Cudd_RecursiveDeref(dd,tempBdd); 01279 temp = Cudd_addApply(dd,Cudd_addPlus,tempAdd,result); 01280 if (temp == NULL) { 01281 Cudd_RecursiveDeref(dd,tempAdd); 01282 Cudd_RecursiveDeref(dd,result); 01283 return(NULL); 01284 } 01285 cuddRef(temp); 01286 Cudd_RecursiveDeref(dd,tempAdd); 01287 Cudd_RecursiveDeref(dd,result); 01288 result = temp; 01289 } 01290 01291 cuddDeref(result); 01292 return(result); 01293 01294 } /* end of Cudd_addHamming */
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]
Definition at line 404 of file cuddPriority.c.
00409 { 00410 DdNode *one, *zero; 00411 DdNode *u, *v, *w; 00412 int i; 00413 00414 one = DD_ONE(dd); 00415 zero = DD_ZERO(dd); 00416 00417 /* Build bottom part of ADD outside loop. */ 00418 v = Cudd_addIte(dd, y[N-1], one, zero); 00419 if (v == NULL) return(NULL); 00420 cuddRef(v); 00421 w = Cudd_addIte(dd, y[N-1], zero, one); 00422 if (w == NULL) { 00423 Cudd_RecursiveDeref(dd, v); 00424 return(NULL); 00425 } 00426 cuddRef(w); 00427 u = Cudd_addIte(dd, x[N-1], v, w); 00428 if (u == NULL) { 00429 Cudd_RecursiveDeref(dd, v); 00430 Cudd_RecursiveDeref(dd, w); 00431 return(NULL); 00432 } 00433 cuddRef(u); 00434 Cudd_RecursiveDeref(dd, v); 00435 Cudd_RecursiveDeref(dd, w); 00436 00437 /* Loop to build the rest of the ADD. */ 00438 for (i = N-2; i >= 0; i--) { 00439 v = Cudd_addIte(dd, y[i], u, zero); 00440 if (v == NULL) { 00441 Cudd_RecursiveDeref(dd, u); 00442 return(NULL); 00443 } 00444 cuddRef(v); 00445 w = Cudd_addIte(dd, y[i], zero, u); 00446 if (w == NULL) { 00447 Cudd_RecursiveDeref(dd, u); 00448 Cudd_RecursiveDeref(dd, v); 00449 return(NULL); 00450 } 00451 cuddRef(w); 00452 Cudd_RecursiveDeref(dd, u); 00453 u = Cudd_addIte(dd, x[i], v, w); 00454 if (w == NULL) { 00455 Cudd_RecursiveDeref(dd, v); 00456 Cudd_RecursiveDeref(dd, w); 00457 return(NULL); 00458 } 00459 cuddRef(u); 00460 Cudd_RecursiveDeref(dd, v); 00461 Cudd_RecursiveDeref(dd, w); 00462 } 00463 cuddDeref(u); 00464 return(u); 00465 00466 } /* end of Cudd_addXeqy */
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]
Definition at line 1355 of file cuddPriority.c.
01360 { 01361 DdNode *res, *acube; 01362 CUDD_VALUE_TYPE rdist; 01363 01364 /* Compute the cube and distance as a single ADD. */ 01365 do { 01366 dd->reordered = 0; 01367 res = cuddBddClosestCube(dd,f,g,CUDD_CONST_INDEX + 1.0); 01368 } while (dd->reordered == 1); 01369 if (res == NULL) return(NULL); 01370 cuddRef(res); 01371 01372 /* Unpack distance and cube. */ 01373 do { 01374 dd->reordered = 0; 01375 acube = separateCube(dd, res, &rdist); 01376 } while (dd->reordered == 1); 01377 if (acube == NULL) { 01378 Cudd_RecursiveDeref(dd, res); 01379 return(NULL); 01380 } 01381 cuddRef(acube); 01382 Cudd_RecursiveDeref(dd, res); 01383 01384 /* Convert cube from ADD to BDD. */ 01385 do { 01386 dd->reordered = 0; 01387 res = cuddAddBddDoPattern(dd, acube); 01388 } while (dd->reordered == 1); 01389 if (res == NULL) { 01390 Cudd_RecursiveDeref(dd, acube); 01391 return(NULL); 01392 } 01393 cuddRef(res); 01394 Cudd_RecursiveDeref(dd, acube); 01395 01396 *distance = (int) rdist; 01397 cuddDeref(res); 01398 return(res); 01399 01400 } /* end of Cudd_bddClosestCube */
DdNode* Cudd_bddInterval | ( | DdManager * | dd, | |
int | N, | |||
DdNode ** | x, | |||
unsigned int | lowerB, | |||
unsigned int | upperB | |||
) |
Function********************************************************************
Synopsis [Generates a BDD for the function lowerB x upperB.]
Description [This function generates a BDD for the function lowerB x upperB, where x is an N-bit number, x\[0\] x\[1\] ... x\[N-1\], with 0 the most significant bit (important!). The number of variables N should be sufficient to represent the bounds; otherwise, the bounds are truncated to their N least significant bits. Two BDDs are built bottom-up for lowerB x and x upperB, and they are finally conjoined.]
SideEffects [None]
SeeAlso [Cudd_Xgty]
Definition at line 1117 of file cuddPriority.c.
01123 { 01124 DdNode *one, *zero; 01125 DdNode *r, *rl, *ru; 01126 int i; 01127 01128 one = DD_ONE(dd); 01129 zero = Cudd_Not(one); 01130 01131 rl = one; 01132 cuddRef(rl); 01133 ru = one; 01134 cuddRef(ru); 01135 01136 /* Loop to build the rest of the BDDs. */ 01137 for (i = N-1; i >= 0; i--) { 01138 DdNode *vl, *vu; 01139 vl = Cudd_bddIte(dd, x[i], 01140 lowerB&1 ? rl : one, 01141 lowerB&1 ? zero : rl); 01142 if (vl == NULL) { 01143 Cudd_IterDerefBdd(dd, rl); 01144 Cudd_IterDerefBdd(dd, ru); 01145 return(NULL); 01146 } 01147 cuddRef(vl); 01148 Cudd_IterDerefBdd(dd, rl); 01149 rl = vl; 01150 lowerB >>= 1; 01151 vu = Cudd_bddIte(dd, x[i], 01152 upperB&1 ? ru : zero, 01153 upperB&1 ? one : ru); 01154 if (vu == NULL) { 01155 Cudd_IterDerefBdd(dd, rl); 01156 Cudd_IterDerefBdd(dd, ru); 01157 return(NULL); 01158 } 01159 cuddRef(vu); 01160 Cudd_IterDerefBdd(dd, ru); 01161 ru = vu; 01162 upperB >>= 1; 01163 } 01164 01165 /* Conjoin the two bounds. */ 01166 r = Cudd_bddAnd(dd, rl, ru); 01167 if (r == NULL) { 01168 Cudd_IterDerefBdd(dd, rl); 01169 Cudd_IterDerefBdd(dd, ru); 01170 return(NULL); 01171 } 01172 cuddRef(r); 01173 Cudd_IterDerefBdd(dd, rl); 01174 Cudd_IterDerefBdd(dd, ru); 01175 cuddDeref(r); 01176 return(r); 01177 01178 } /* end of Cudd_bddInterval */
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]
Definition at line 1196 of file cuddPriority.c.
01200 { 01201 DdNode *res; 01202 DdNode *support; 01203 01204 if (cuddCheckCube(dd,Y) == 0) { 01205 (void) fprintf(dd->err, 01206 "Error: The third argument of Cudd_CProjection should be a cube\n"); 01207 dd->errorCode = CUDD_INVALID_ARG; 01208 return(NULL); 01209 } 01210 01211 /* Compute the support of Y, which is used by the abstraction step 01212 ** in cuddCProjectionRecur. 01213 */ 01214 support = Cudd_Support(dd,Y); 01215 if (support == NULL) return(NULL); 01216 cuddRef(support); 01217 01218 do { 01219 dd->reordered = 0; 01220 res = cuddCProjectionRecur(dd,R,Y,support); 01221 } while (dd->reordered == 1); 01222 01223 if (res == NULL) { 01224 Cudd_RecursiveDeref(dd,support); 01225 return(NULL); 01226 } 01227 cuddRef(res); 01228 Cudd_RecursiveDeref(dd,support); 01229 cuddDeref(res); 01230 01231 return(res); 01232 01233 } /* end of Cudd_CProjection */
Function********************************************************************
Synopsis [Generates a BDD for the function x - y != c.]
Description [This function generates a BDD for the function x -y != c. 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 a linear number of 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_Xgty]
Definition at line 928 of file cuddPriority.c.
00934 { 00935 /* The nodes at level i represent values of the difference that are 00936 ** multiples of 2^i. We use variables with names starting with k 00937 ** to denote the multipliers of 2^i in such multiples. */ 00938 int kTrueLb = c + 1; 00939 int kTrueUb = c - 1; 00940 int kFalse = c; 00941 /* Mask used to compute the ceiling function. Since we divide by 2^i, 00942 ** we want to know whether the dividend is a multiple of 2^i. If it is, 00943 ** then ceiling and floor coincide; otherwise, they differ by one. */ 00944 int mask = 1; 00945 int i; 00946 00947 DdNode *f = NULL; /* the eventual result */ 00948 DdNode *one = DD_ONE(dd); 00949 DdNode *zero = Cudd_Not(one); 00950 00951 /* Two x-labeled nodes are created at most at each iteration. They are 00952 ** stored, along with their k values, in these variables. At each level, 00953 ** the old nodes are freed and the new nodes are copied into the old map. 00954 */ 00955 DdNode *map[2]; 00956 int invalidIndex = 1 << (N-1); 00957 int index[2] = {invalidIndex, invalidIndex}; 00958 00959 /* This should never happen. */ 00960 if (N < 0) return(NULL); 00961 00962 /* If there are no bits, both operands are 0. The result depends on c. */ 00963 if (N == 0) { 00964 if (c != 0) return(one); 00965 else return(zero); 00966 } 00967 00968 /* The maximum or the minimum difference comparing to c can generate the terminal case */ 00969 if ((1 << N) - 1 < c || (-(1 << N) + 1) > c) return(one); 00970 00971 /* Build the result bottom up. */ 00972 for (i = 1; i <= N; i++) { 00973 int kTrueLbLower, kTrueUbLower; 00974 int leftChild, middleChild, rightChild; 00975 DdNode *g0, *g1, *fplus, *fequal, *fminus; 00976 int j; 00977 DdNode *newMap[2]; 00978 int newIndex[2]; 00979 00980 kTrueLbLower = kTrueLb; 00981 kTrueUbLower = kTrueUb; 00982 /* kTrueLb = floor((c-1)/2^i) + 2 */ 00983 kTrueLb = ((c-1) >> i) + 2; 00984 /* kTrueUb = ceiling((c+1)/2^i) - 2 */ 00985 kTrueUb = ((c+1) >> i) + (((c+2) & mask) != 1) - 2; 00986 mask = (mask << 1) | 1; 00987 newIndex[0] = invalidIndex; 00988 newIndex[1] = invalidIndex; 00989 00990 for (j = kTrueUb + 1; j < kTrueLb; j++) { 00991 /* Skip if node is not reachable from top of BDD. */ 00992 if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue; 00993 00994 /* Find f- */ 00995 leftChild = (j << 1) - 1; 00996 if (leftChild >= kTrueLbLower || leftChild <= kTrueUbLower) { 00997 fminus = one; 00998 } else if (i == 1 && leftChild == kFalse) { 00999 fminus = zero; 01000 } else { 01001 assert(leftChild == index[0] || leftChild == index[1]); 01002 if (leftChild == index[0]) { 01003 fminus = map[0]; 01004 } else { 01005 fminus = map[1]; 01006 } 01007 } 01008 01009 /* Find f= */ 01010 middleChild = j << 1; 01011 if (middleChild >= kTrueLbLower || middleChild <= kTrueUbLower) { 01012 fequal = one; 01013 } else if (i == 1 && middleChild == kFalse) { 01014 fequal = zero; 01015 } else { 01016 assert(middleChild == index[0] || middleChild == index[1]); 01017 if (middleChild == index[0]) { 01018 fequal = map[0]; 01019 } else { 01020 fequal = map[1]; 01021 } 01022 } 01023 01024 /* Find f+ */ 01025 rightChild = (j << 1) + 1; 01026 if (rightChild >= kTrueLbLower || rightChild <= kTrueUbLower) { 01027 fplus = one; 01028 } else if (i == 1 && rightChild == kFalse) { 01029 fplus = zero; 01030 } else { 01031 assert(rightChild == index[0] || rightChild == index[1]); 01032 if (rightChild == index[0]) { 01033 fplus = map[0]; 01034 } else { 01035 fplus = map[1]; 01036 } 01037 } 01038 01039 /* Build new nodes. */ 01040 g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus); 01041 if (g1 == NULL) { 01042 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); 01043 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); 01044 if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); 01045 if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); 01046 return(NULL); 01047 } 01048 cuddRef(g1); 01049 g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal); 01050 if (g0 == NULL) { 01051 Cudd_IterDerefBdd(dd, g1); 01052 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); 01053 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); 01054 if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); 01055 if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); 01056 return(NULL); 01057 } 01058 cuddRef(g0); 01059 f = Cudd_bddIte(dd, x[N - i], g1, g0); 01060 if (f == NULL) { 01061 Cudd_IterDerefBdd(dd, g1); 01062 Cudd_IterDerefBdd(dd, g0); 01063 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); 01064 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); 01065 if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); 01066 if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); 01067 return(NULL); 01068 } 01069 cuddRef(f); 01070 Cudd_IterDerefBdd(dd, g1); 01071 Cudd_IterDerefBdd(dd, g0); 01072 01073 /* Save newly computed node in map. */ 01074 assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex); 01075 if (newIndex[0] == invalidIndex) { 01076 newIndex[0] = j; 01077 newMap[0] = f; 01078 } else { 01079 newIndex[1] = j; 01080 newMap[1] = f; 01081 } 01082 } 01083 01084 /* Copy new map to map. */ 01085 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); 01086 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); 01087 map[0] = newMap[0]; 01088 map[1] = newMap[1]; 01089 index[0] = newIndex[0]; 01090 index[1] = newIndex[1]; 01091 } 01092 01093 cuddDeref(f); 01094 return(f); 01095 01096 } /* end of Cudd_Disequality */
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: {i=0}^{N-1}(|x_i - y_i| 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]
Definition at line 490 of file cuddPriority.c.
00496 { 00497 DdNode *one, *zero; 00498 DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1; 00499 int i; 00500 00501 one = DD_ONE(dd); 00502 zero = Cudd_Not(one); 00503 00504 /* Build bottom part of BDD outside loop. */ 00505 y1_ = Cudd_bddIte(dd, y[N-1], one, Cudd_Not(z[N-1])); 00506 if (y1_ == NULL) return(NULL); 00507 cuddRef(y1_); 00508 y2 = Cudd_bddIte(dd, y[N-1], z[N-1], one); 00509 if (y2 == NULL) { 00510 Cudd_RecursiveDeref(dd, y1_); 00511 return(NULL); 00512 } 00513 cuddRef(y2); 00514 x1 = Cudd_bddIte(dd, x[N-1], y1_, y2); 00515 if (x1 == NULL) { 00516 Cudd_RecursiveDeref(dd, y1_); 00517 Cudd_RecursiveDeref(dd, y2); 00518 return(NULL); 00519 } 00520 cuddRef(x1); 00521 Cudd_RecursiveDeref(dd, y1_); 00522 Cudd_RecursiveDeref(dd, y2); 00523 00524 /* Loop to build the rest of the BDD. */ 00525 for (i = N-2; i >= 0; i--) { 00526 z1 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); 00527 if (z1 == NULL) { 00528 Cudd_RecursiveDeref(dd, x1); 00529 return(NULL); 00530 } 00531 cuddRef(z1); 00532 z2 = Cudd_bddIte(dd, z[i], x1, one); 00533 if (z2 == NULL) { 00534 Cudd_RecursiveDeref(dd, x1); 00535 Cudd_RecursiveDeref(dd, z1); 00536 return(NULL); 00537 } 00538 cuddRef(z2); 00539 z3 = Cudd_bddIte(dd, z[i], one, x1); 00540 if (z3 == NULL) { 00541 Cudd_RecursiveDeref(dd, x1); 00542 Cudd_RecursiveDeref(dd, z1); 00543 Cudd_RecursiveDeref(dd, z2); 00544 return(NULL); 00545 } 00546 cuddRef(z3); 00547 z4 = Cudd_bddIte(dd, z[i], x1, zero); 00548 if (z4 == NULL) { 00549 Cudd_RecursiveDeref(dd, x1); 00550 Cudd_RecursiveDeref(dd, z1); 00551 Cudd_RecursiveDeref(dd, z2); 00552 Cudd_RecursiveDeref(dd, z3); 00553 return(NULL); 00554 } 00555 cuddRef(z4); 00556 Cudd_RecursiveDeref(dd, x1); 00557 y1_ = Cudd_bddIte(dd, y[i], z2, Cudd_Not(z1)); 00558 if (y1_ == NULL) { 00559 Cudd_RecursiveDeref(dd, z1); 00560 Cudd_RecursiveDeref(dd, z2); 00561 Cudd_RecursiveDeref(dd, z3); 00562 Cudd_RecursiveDeref(dd, z4); 00563 return(NULL); 00564 } 00565 cuddRef(y1_); 00566 y2 = Cudd_bddIte(dd, y[i], z4, z3); 00567 if (y2 == NULL) { 00568 Cudd_RecursiveDeref(dd, z1); 00569 Cudd_RecursiveDeref(dd, z2); 00570 Cudd_RecursiveDeref(dd, z3); 00571 Cudd_RecursiveDeref(dd, z4); 00572 Cudd_RecursiveDeref(dd, y1_); 00573 return(NULL); 00574 } 00575 cuddRef(y2); 00576 Cudd_RecursiveDeref(dd, z1); 00577 Cudd_RecursiveDeref(dd, z2); 00578 Cudd_RecursiveDeref(dd, z3); 00579 Cudd_RecursiveDeref(dd, z4); 00580 x1 = Cudd_bddIte(dd, x[i], y1_, y2); 00581 if (x1 == NULL) { 00582 Cudd_RecursiveDeref(dd, y1_); 00583 Cudd_RecursiveDeref(dd, y2); 00584 return(NULL); 00585 } 00586 cuddRef(x1); 00587 Cudd_RecursiveDeref(dd, y1_); 00588 Cudd_RecursiveDeref(dd, y2); 00589 } 00590 cuddDeref(x1); 00591 return(Cudd_Not(x1)); 00592 00593 } /* 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: {i=0}^{N-1}(|x_i - y_i| 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]
Definition at line 617 of file cuddPriority.c.
00623 { 00624 DdNode *one, *zero; 00625 DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1; 00626 int i; 00627 00628 one = DD_ONE(dd); 00629 zero = Cudd_Not(one); 00630 00631 /* Build bottom part of BDD outside loop. */ 00632 y1_ = Cudd_bddIte(dd, y[N-1], one, z[N-1]); 00633 if (y1_ == NULL) return(NULL); 00634 cuddRef(y1_); 00635 y2 = Cudd_bddIte(dd, y[N-1], z[N-1], zero); 00636 if (y2 == NULL) { 00637 Cudd_RecursiveDeref(dd, y1_); 00638 return(NULL); 00639 } 00640 cuddRef(y2); 00641 x1 = Cudd_bddIte(dd, x[N-1], y1_, Cudd_Not(y2)); 00642 if (x1 == NULL) { 00643 Cudd_RecursiveDeref(dd, y1_); 00644 Cudd_RecursiveDeref(dd, y2); 00645 return(NULL); 00646 } 00647 cuddRef(x1); 00648 Cudd_RecursiveDeref(dd, y1_); 00649 Cudd_RecursiveDeref(dd, y2); 00650 00651 /* Loop to build the rest of the BDD. */ 00652 for (i = N-2; i >= 0; i--) { 00653 z1 = Cudd_bddIte(dd, z[i], x1, zero); 00654 if (z1 == NULL) { 00655 Cudd_RecursiveDeref(dd, x1); 00656 return(NULL); 00657 } 00658 cuddRef(z1); 00659 z2 = Cudd_bddIte(dd, z[i], x1, one); 00660 if (z2 == NULL) { 00661 Cudd_RecursiveDeref(dd, x1); 00662 Cudd_RecursiveDeref(dd, z1); 00663 return(NULL); 00664 } 00665 cuddRef(z2); 00666 z3 = Cudd_bddIte(dd, z[i], one, x1); 00667 if (z3 == NULL) { 00668 Cudd_RecursiveDeref(dd, x1); 00669 Cudd_RecursiveDeref(dd, z1); 00670 Cudd_RecursiveDeref(dd, z2); 00671 return(NULL); 00672 } 00673 cuddRef(z3); 00674 z4 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); 00675 if (z4 == NULL) { 00676 Cudd_RecursiveDeref(dd, x1); 00677 Cudd_RecursiveDeref(dd, z1); 00678 Cudd_RecursiveDeref(dd, z2); 00679 Cudd_RecursiveDeref(dd, z3); 00680 return(NULL); 00681 } 00682 cuddRef(z4); 00683 Cudd_RecursiveDeref(dd, x1); 00684 y1_ = Cudd_bddIte(dd, y[i], z2, z1); 00685 if (y1_ == NULL) { 00686 Cudd_RecursiveDeref(dd, z1); 00687 Cudd_RecursiveDeref(dd, z2); 00688 Cudd_RecursiveDeref(dd, z3); 00689 Cudd_RecursiveDeref(dd, z4); 00690 return(NULL); 00691 } 00692 cuddRef(y1_); 00693 y2 = Cudd_bddIte(dd, y[i], z4, Cudd_Not(z3)); 00694 if (y2 == NULL) { 00695 Cudd_RecursiveDeref(dd, z1); 00696 Cudd_RecursiveDeref(dd, z2); 00697 Cudd_RecursiveDeref(dd, z3); 00698 Cudd_RecursiveDeref(dd, z4); 00699 Cudd_RecursiveDeref(dd, y1_); 00700 return(NULL); 00701 } 00702 cuddRef(y2); 00703 Cudd_RecursiveDeref(dd, z1); 00704 Cudd_RecursiveDeref(dd, z2); 00705 Cudd_RecursiveDeref(dd, z3); 00706 Cudd_RecursiveDeref(dd, z4); 00707 x1 = Cudd_bddIte(dd, x[i], y1_, Cudd_Not(y2)); 00708 if (x1 == NULL) { 00709 Cudd_RecursiveDeref(dd, y1_); 00710 Cudd_RecursiveDeref(dd, y2); 00711 return(NULL); 00712 } 00713 cuddRef(x1); 00714 Cudd_RecursiveDeref(dd, y1_); 00715 Cudd_RecursiveDeref(dd, y2); 00716 } 00717 cuddDeref(x1); 00718 return(Cudd_Not(x1)); 00719 00720 } /* end of Cudd_Dxygtdyz */
Function********************************************************************
Synopsis [Generates a BDD for the function x - y c.]
Description [This function generates a BDD for the function x -y c. 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 a linear number of 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_Xgty]
Definition at line 740 of file cuddPriority.c.
00746 { 00747 /* The nodes at level i represent values of the difference that are 00748 ** multiples of 2^i. We use variables with names starting with k 00749 ** to denote the multipliers of 2^i in such multiples. */ 00750 int kTrue = c; 00751 int kFalse = c - 1; 00752 /* Mask used to compute the ceiling function. Since we divide by 2^i, 00753 ** we want to know whether the dividend is a multiple of 2^i. If it is, 00754 ** then ceiling and floor coincide; otherwise, they differ by one. */ 00755 int mask = 1; 00756 int i; 00757 00758 DdNode *f = NULL; /* the eventual result */ 00759 DdNode *one = DD_ONE(dd); 00760 DdNode *zero = Cudd_Not(one); 00761 00762 /* Two x-labeled nodes are created at most at each iteration. They are 00763 ** stored, along with their k values, in these variables. At each level, 00764 ** the old nodes are freed and the new nodes are copied into the old map. 00765 */ 00766 DdNode *map[2]; 00767 int invalidIndex = 1 << (N-1); 00768 int index[2] = {invalidIndex, invalidIndex}; 00769 00770 /* This should never happen. */ 00771 if (N < 0) return(NULL); 00772 00773 /* If there are no bits, both operands are 0. The result depends on c. */ 00774 if (N == 0) { 00775 if (c >= 0) return(one); 00776 else return(zero); 00777 } 00778 00779 /* The maximum or the minimum difference comparing to c can generate the terminal case */ 00780 if ((1 << N) - 1 < c) return(zero); 00781 else if ((-(1 << N) + 1) >= c) return(one); 00782 00783 /* Build the result bottom up. */ 00784 for (i = 1; i <= N; i++) { 00785 int kTrueLower, kFalseLower; 00786 int leftChild, middleChild, rightChild; 00787 DdNode *g0, *g1, *fplus, *fequal, *fminus; 00788 int j; 00789 DdNode *newMap[2]; 00790 int newIndex[2]; 00791 00792 kTrueLower = kTrue; 00793 kFalseLower = kFalse; 00794 /* kTrue = ceiling((c-1)/2^i) + 1 */ 00795 kTrue = ((c-1) >> i) + ((c & mask) != 1) + 1; 00796 mask = (mask << 1) | 1; 00797 /* kFalse = floor(c/2^i) - 1 */ 00798 kFalse = (c >> i) - 1; 00799 newIndex[0] = invalidIndex; 00800 newIndex[1] = invalidIndex; 00801 00802 for (j = kFalse + 1; j < kTrue; j++) { 00803 /* Skip if node is not reachable from top of BDD. */ 00804 if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue; 00805 00806 /* Find f- */ 00807 leftChild = (j << 1) - 1; 00808 if (leftChild >= kTrueLower) { 00809 fminus = one; 00810 } else if (leftChild <= kFalseLower) { 00811 fminus = zero; 00812 } else { 00813 assert(leftChild == index[0] || leftChild == index[1]); 00814 if (leftChild == index[0]) { 00815 fminus = map[0]; 00816 } else { 00817 fminus = map[1]; 00818 } 00819 } 00820 00821 /* Find f= */ 00822 middleChild = j << 1; 00823 if (middleChild >= kTrueLower) { 00824 fequal = one; 00825 } else if (middleChild <= kFalseLower) { 00826 fequal = zero; 00827 } else { 00828 assert(middleChild == index[0] || middleChild == index[1]); 00829 if (middleChild == index[0]) { 00830 fequal = map[0]; 00831 } else { 00832 fequal = map[1]; 00833 } 00834 } 00835 00836 /* Find f+ */ 00837 rightChild = (j << 1) + 1; 00838 if (rightChild >= kTrueLower) { 00839 fplus = one; 00840 } else if (rightChild <= kFalseLower) { 00841 fplus = zero; 00842 } else { 00843 assert(rightChild == index[0] || rightChild == index[1]); 00844 if (rightChild == index[0]) { 00845 fplus = map[0]; 00846 } else { 00847 fplus = map[1]; 00848 } 00849 } 00850 00851 /* Build new nodes. */ 00852 g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus); 00853 if (g1 == NULL) { 00854 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); 00855 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); 00856 if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); 00857 if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); 00858 return(NULL); 00859 } 00860 cuddRef(g1); 00861 g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal); 00862 if (g0 == NULL) { 00863 Cudd_IterDerefBdd(dd, g1); 00864 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); 00865 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); 00866 if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); 00867 if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); 00868 return(NULL); 00869 } 00870 cuddRef(g0); 00871 f = Cudd_bddIte(dd, x[N - i], g1, g0); 00872 if (f == NULL) { 00873 Cudd_IterDerefBdd(dd, g1); 00874 Cudd_IterDerefBdd(dd, g0); 00875 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); 00876 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); 00877 if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); 00878 if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); 00879 return(NULL); 00880 } 00881 cuddRef(f); 00882 Cudd_IterDerefBdd(dd, g1); 00883 Cudd_IterDerefBdd(dd, g0); 00884 00885 /* Save newly computed node in map. */ 00886 assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex); 00887 if (newIndex[0] == invalidIndex) { 00888 newIndex[0] = j; 00889 newMap[0] = f; 00890 } else { 00891 newIndex[1] = j; 00892 newMap[1] = f; 00893 } 00894 } 00895 00896 /* Copy new map to map. */ 00897 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); 00898 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); 00899 map[0] = newMap[0]; 00900 map[1] = newMap[1]; 00901 index[0] = newIndex[0]; 00902 index[1] = newIndex[1]; 00903 } 00904 00905 cuddDeref(f); 00906 return(f); 00907 00908 } /* end of Cudd_Inequality */
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]
Definition at line 1314 of file cuddPriority.c.
01319 { 01320 DdHashTable *table; 01321 CUDD_VALUE_TYPE epsilon; 01322 int res; 01323 01324 table = cuddHashTableInit(dd,1,2); 01325 if (table == NULL) { 01326 return(CUDD_OUT_OF_MEM); 01327 } 01328 epsilon = Cudd_ReadEpsilon(dd); 01329 Cudd_SetEpsilon(dd,(CUDD_VALUE_TYPE)0.0); 01330 res = cuddMinHammingDistRecur(f,minterm,table,upperBound); 01331 cuddHashTableQuit(table); 01332 Cudd_SetEpsilon(dd,epsilon); 01333 01334 return(res); 01335 01336 } /* end of Cudd_MinHammingDist */
DdNode* Cudd_PrioritySelect | ( | DdManager * | dd, | |
DdNode * | R, | |||
DdNode ** | x, | |||
DdNode ** | y, | |||
DdNode ** | z, | |||
DdNode * | Pi, | |||
int | n, | |||
DD_PRFP | Pifunc | |||
) |
AutomaticEnd 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:
]
SideEffects [If called with z == NULL, will create new variables in the manager.]
SeeAlso [Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_Xgty Cudd_bddAdjPermuteX Cudd_CProjection]
Definition at line 171 of file cuddPriority.c.
00176 : may be NULL) */, 00177 DdNode * Pi /* BDD of the priority function (optional: may be NULL) */, 00178 int n /* size of x, y, and z */, 00179 DD_PRFP Pifunc /* function used to build Pi if it is NULL */) 00180 { 00181 DdNode *res = NULL; 00182 DdNode *zcube = NULL; 00183 DdNode *Rxz, *Q; 00184 int createdZ = 0; 00185 int createdPi = 0; 00186 int i; 00187 00188 /* Create z variables if needed. */ 00189 if (z == NULL) { 00190 if (Pi != NULL) return(NULL); 00191 z = ALLOC(DdNode *,n); 00192 if (z == NULL) { 00193 dd->errorCode = CUDD_MEMORY_OUT; 00194 return(NULL); 00195 } 00196 createdZ = 1; 00197 for (i = 0; i < n; i++) { 00198 if (dd->size >= (int) CUDD_MAXINDEX - 1) goto endgame; 00199 z[i] = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); 00200 if (z[i] == NULL) goto endgame; 00201 } 00202 } 00203 00204 /* Create priority function BDD if needed. */ 00205 if (Pi == NULL) { 00206 Pi = Pifunc(dd,n,x,y,z); 00207 if (Pi == NULL) goto endgame; 00208 createdPi = 1; 00209 cuddRef(Pi); 00210 } 00211 00212 /* Initialize abstraction cube. */ 00213 zcube = DD_ONE(dd); 00214 cuddRef(zcube); 00215 for (i = n - 1; i >= 0; i--) { 00216 DdNode *tmpp; 00217 tmpp = Cudd_bddAnd(dd,z[i],zcube); 00218 if (tmpp == NULL) goto endgame; 00219 cuddRef(tmpp); 00220 Cudd_RecursiveDeref(dd,zcube); 00221 zcube = tmpp; 00222 } 00223 00224 /* Compute subset of (x,y) pairs. */ 00225 Rxz = Cudd_bddSwapVariables(dd,R,y,z,n); 00226 if (Rxz == NULL) goto endgame; 00227 cuddRef(Rxz); 00228 Q = Cudd_bddAndAbstract(dd,Rxz,Pi,zcube); 00229 if (Q == NULL) { 00230 Cudd_RecursiveDeref(dd,Rxz); 00231 goto endgame; 00232 } 00233 cuddRef(Q); 00234 Cudd_RecursiveDeref(dd,Rxz); 00235 res = Cudd_bddAnd(dd,R,Cudd_Not(Q)); 00236 if (res == NULL) { 00237 Cudd_RecursiveDeref(dd,Q); 00238 goto endgame; 00239 } 00240 cuddRef(res); 00241 Cudd_RecursiveDeref(dd,Q); 00242 00243 endgame: 00244 if (zcube != NULL) Cudd_RecursiveDeref(dd,zcube); 00245 if (createdZ) { 00246 FREE(z); 00247 } 00248 if (createdPi) { 00249 Cudd_RecursiveDeref(dd,Pi); 00250 } 00251 if (res != NULL) cuddDeref(res); 00252 return(res); 00253 00254 } /* 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\]. ]
SideEffects [None]
SeeAlso [Cudd_addXeqy]
Definition at line 341 of file cuddPriority.c.
00346 { 00347 DdNode *u, *v, *w; 00348 int i; 00349 00350 /* Build bottom part of BDD outside loop. */ 00351 u = Cudd_bddIte(dd, x[N-1], y[N-1], Cudd_Not(y[N-1])); 00352 if (u == NULL) return(NULL); 00353 cuddRef(u); 00354 00355 /* Loop to build the rest of the BDD. */ 00356 for (i = N-2; i >= 0; i--) { 00357 v = Cudd_bddAnd(dd, y[i], u); 00358 if (v == NULL) { 00359 Cudd_RecursiveDeref(dd, u); 00360 return(NULL); 00361 } 00362 cuddRef(v); 00363 w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); 00364 if (w == NULL) { 00365 Cudd_RecursiveDeref(dd, u); 00366 Cudd_RecursiveDeref(dd, v); 00367 return(NULL); 00368 } 00369 cuddRef(w); 00370 Cudd_RecursiveDeref(dd, u); 00371 u = Cudd_bddIte(dd, x[i], v, w); 00372 if (u == NULL) { 00373 Cudd_RecursiveDeref(dd, v); 00374 Cudd_RecursiveDeref(dd, w); 00375 return(NULL); 00376 } 00377 cuddRef(u); 00378 Cudd_RecursiveDeref(dd, v); 00379 Cudd_RecursiveDeref(dd, w); 00380 } 00381 cuddDeref(u); 00382 return(u); 00383 00384 } /* end of Cudd_Xeqy */
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]
Definition at line 276 of file cuddPriority.c.
00279 : unused */, 00280 DdNode ** x /* array of x variables */, 00281 DdNode ** y /* array of y variables */) 00282 { 00283 DdNode *u, *v, *w; 00284 int i; 00285 00286 /* Build bottom part of BDD outside loop. */ 00287 u = Cudd_bddAnd(dd, x[N-1], Cudd_Not(y[N-1])); 00288 if (u == NULL) return(NULL); 00289 cuddRef(u); 00290 00291 /* Loop to build the rest of the BDD. */ 00292 for (i = N-2; i >= 0; i--) { 00293 v = Cudd_bddAnd(dd, y[i], Cudd_Not(u)); 00294 if (v == NULL) { 00295 Cudd_RecursiveDeref(dd, u); 00296 return(NULL); 00297 } 00298 cuddRef(v); 00299 w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); 00300 if (w == NULL) { 00301 Cudd_RecursiveDeref(dd, u); 00302 Cudd_RecursiveDeref(dd, v); 00303 return(NULL); 00304 } 00305 cuddRef(w); 00306 Cudd_RecursiveDeref(dd, u); 00307 u = Cudd_bddIte(dd, x[i], Cudd_Not(v), w); 00308 if (u == NULL) { 00309 Cudd_RecursiveDeref(dd, v); 00310 Cudd_RecursiveDeref(dd, w); 00311 return(NULL); 00312 } 00313 cuddRef(u); 00314 Cudd_RecursiveDeref(dd, v); 00315 Cudd_RecursiveDeref(dd, w); 00316 00317 } 00318 cuddDeref(u); 00319 return(u); 00320 00321 } /* end of Cudd_Xgty */
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
according to the following formula.
H(f,g) = min(H(ft,gt), H(fe,ge), H(ft,ge)+1, H(fe,gt)+1)
Bounding is based on the following observations.
The variable bound
is set at the largest value of the distance that we are still interested in. Therefore, we desist when
(bound == -1) and (F != not(G)) or (bound == 0) and (F == not(G)).
If we were maximally aggressive in using the bound, we would always set the bound to the minimum distance seen thus far minus one. That is, we would maintain the invariant
bound < minD,
except at the very beginning, when we have no value for minD
.
However, we do not use bound < minD
when examining the two negative cofactors, because we try to find a large cube at minimum distance. To do so, we try to find a cube in the negative cofactors at the same or smaller distance from the cube found in the positive cofactors.
When we compute H(ft,ge)
and H(fe,gt)
we know that we are going to add 1 to the result of the recursive call to account for the difference in the splitting variable. Therefore, we decrease the bound correspondingly.
Another important observation concerns the need of examining all four pairs of cofators only when both f
and g
depend on the top variable.
Suppose gt == ge == g
. (That is, g
does not depend on the top variable.) Then
H(f,g) = min(H(ft,g), H(fe,g), H(ft,g)+1, H(fe,g)+1) = min(H(ft,g), H(fe,g)) .
Therefore, under these circumstances, we skip the two "cross" cases.
An 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]
Definition at line 1642 of file cuddPriority.c.
01647 { 01648 DdNode *res, *F, *G, *ft, *fe, *gt, *ge, *tt, *ee; 01649 DdNode *ctt, *cee, *cte, *cet; 01650 CUDD_VALUE_TYPE minD, dtt, dee, dte, det; 01651 DdNode *one = DD_ONE(dd); 01652 DdNode *lzero = Cudd_Not(one); 01653 DdNode *azero = DD_ZERO(dd); 01654 unsigned int topf, topg, index; 01655 01656 statLine(dd); 01657 if (bound < (f == Cudd_Not(g))) return(azero); 01658 /* Terminal cases. */ 01659 if (g == lzero || f == lzero) return(azero); 01660 if (f == one && g == one) return(one); 01661 01662 /* Check cache. */ 01663 F = Cudd_Regular(f); 01664 G = Cudd_Regular(g); 01665 if (F->ref != 1 || G->ref != 1) { 01666 res = cuddCacheLookup2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g); 01667 if (res != NULL) return(res); 01668 } 01669 01670 topf = cuddI(dd,F->index); 01671 topg = cuddI(dd,G->index); 01672 01673 /* Compute cofactors. */ 01674 if (topf <= topg) { 01675 index = F->index; 01676 ft = cuddT(F); 01677 fe = cuddE(F); 01678 if (Cudd_IsComplement(f)) { 01679 ft = Cudd_Not(ft); 01680 fe = Cudd_Not(fe); 01681 } 01682 } else { 01683 index = G->index; 01684 ft = fe = f; 01685 } 01686 01687 if (topg <= topf) { 01688 gt = cuddT(G); 01689 ge = cuddE(G); 01690 if (Cudd_IsComplement(g)) { 01691 gt = Cudd_Not(gt); 01692 ge = Cudd_Not(ge); 01693 } 01694 } else { 01695 gt = ge = g; 01696 } 01697 01698 tt = cuddBddClosestCube(dd,ft,gt,bound); 01699 if (tt == NULL) return(NULL); 01700 cuddRef(tt); 01701 ctt = separateCube(dd,tt,&dtt); 01702 if (ctt == NULL) { 01703 Cudd_RecursiveDeref(dd, tt); 01704 return(NULL); 01705 } 01706 cuddRef(ctt); 01707 Cudd_RecursiveDeref(dd, tt); 01708 minD = dtt; 01709 bound = ddMin(bound,minD); 01710 01711 ee = cuddBddClosestCube(dd,fe,ge,bound); 01712 if (ee == NULL) { 01713 Cudd_RecursiveDeref(dd, ctt); 01714 return(NULL); 01715 } 01716 cuddRef(ee); 01717 cee = separateCube(dd,ee,&dee); 01718 if (cee == NULL) { 01719 Cudd_RecursiveDeref(dd, ctt); 01720 Cudd_RecursiveDeref(dd, ee); 01721 return(NULL); 01722 } 01723 cuddRef(cee); 01724 Cudd_RecursiveDeref(dd, ee); 01725 minD = ddMin(dtt, dee); 01726 if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1); 01727 01728 if (minD > 0 && topf == topg) { 01729 DdNode *te = cuddBddClosestCube(dd,ft,ge,bound-1); 01730 if (te == NULL) { 01731 Cudd_RecursiveDeref(dd, ctt); 01732 Cudd_RecursiveDeref(dd, cee); 01733 return(NULL); 01734 } 01735 cuddRef(te); 01736 cte = separateCube(dd,te,&dte); 01737 if (cte == NULL) { 01738 Cudd_RecursiveDeref(dd, ctt); 01739 Cudd_RecursiveDeref(dd, cee); 01740 Cudd_RecursiveDeref(dd, te); 01741 return(NULL); 01742 } 01743 cuddRef(cte); 01744 Cudd_RecursiveDeref(dd, te); 01745 dte += 1.0; 01746 minD = ddMin(minD, dte); 01747 } else { 01748 cte = azero; 01749 cuddRef(cte); 01750 dte = CUDD_CONST_INDEX + 1.0; 01751 } 01752 if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1); 01753 01754 if (minD > 0 && topf == topg) { 01755 DdNode *et = cuddBddClosestCube(dd,fe,gt,bound-1); 01756 if (et == NULL) { 01757 Cudd_RecursiveDeref(dd, ctt); 01758 Cudd_RecursiveDeref(dd, cee); 01759 Cudd_RecursiveDeref(dd, cte); 01760 return(NULL); 01761 } 01762 cuddRef(et); 01763 cet = separateCube(dd,et,&det); 01764 if (cet == NULL) { 01765 Cudd_RecursiveDeref(dd, ctt); 01766 Cudd_RecursiveDeref(dd, cee); 01767 Cudd_RecursiveDeref(dd, cte); 01768 Cudd_RecursiveDeref(dd, et); 01769 return(NULL); 01770 } 01771 cuddRef(cet); 01772 Cudd_RecursiveDeref(dd, et); 01773 det += 1.0; 01774 minD = ddMin(minD, det); 01775 } else { 01776 cet = azero; 01777 cuddRef(cet); 01778 det = CUDD_CONST_INDEX + 1.0; 01779 } 01780 01781 if (minD == dtt) { 01782 if (dtt == dee && ctt == cee) { 01783 res = createResult(dd,CUDD_CONST_INDEX,1,ctt,dtt); 01784 } else { 01785 res = createResult(dd,index,1,ctt,dtt); 01786 } 01787 } else if (minD == dee) { 01788 res = createResult(dd,index,0,cee,dee); 01789 } else if (minD == dte) { 01790 #ifdef DD_DEBUG 01791 assert(topf == topg); 01792 #endif 01793 res = createResult(dd,index,1,cte,dte); 01794 } else { 01795 #ifdef DD_DEBUG 01796 assert(topf == topg); 01797 #endif 01798 res = createResult(dd,index,0,cet,det); 01799 } 01800 if (res == NULL) { 01801 Cudd_RecursiveDeref(dd, ctt); 01802 Cudd_RecursiveDeref(dd, cee); 01803 Cudd_RecursiveDeref(dd, cte); 01804 Cudd_RecursiveDeref(dd, cet); 01805 return(NULL); 01806 } 01807 cuddRef(res); 01808 Cudd_RecursiveDeref(dd, ctt); 01809 Cudd_RecursiveDeref(dd, cee); 01810 Cudd_RecursiveDeref(dd, cte); 01811 Cudd_RecursiveDeref(dd, cet); 01812 01813 /* Only cache results that are different from azero to avoid 01814 ** storing results that depend on the value of the bound. */ 01815 if ((F->ref != 1 || G->ref != 1) && res != azero) 01816 cuddCacheInsert2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g, res); 01817 01818 cuddDeref(res); 01819 return(res); 01820 01821 } /* end of cuddBddClosestCube */
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]
Definition at line 1421 of file cuddPriority.c.
01426 { 01427 DdNode *res, *res1, *res2, *resA; 01428 DdNode *r, *y, *RT, *RE, *YT, *YE, *Yrest, *Ra, *Ran, *Gamma, *Alpha; 01429 unsigned int topR, topY, top, index; 01430 DdNode *one = DD_ONE(dd); 01431 01432 statLine(dd); 01433 if (Y == one) return(R); 01434 01435 #ifdef DD_DEBUG 01436 assert(!Cudd_IsConstant(Y)); 01437 #endif 01438 01439 if (R == Cudd_Not(one)) return(R); 01440 01441 res = cuddCacheLookup2(dd, Cudd_CProjection, R, Y); 01442 if (res != NULL) return(res); 01443 01444 r = Cudd_Regular(R); 01445 topR = cuddI(dd,r->index); 01446 y = Cudd_Regular(Y); 01447 topY = cuddI(dd,y->index); 01448 01449 top = ddMin(topR, topY); 01450 01451 /* Compute the cofactors of R */ 01452 if (topR == top) { 01453 index = r->index; 01454 RT = cuddT(r); 01455 RE = cuddE(r); 01456 if (r != R) { 01457 RT = Cudd_Not(RT); RE = Cudd_Not(RE); 01458 } 01459 } else { 01460 RT = RE = R; 01461 } 01462 01463 if (topY > top) { 01464 /* Y does not depend on the current top variable. 01465 ** We just need to compute the results on the two cofactors of R 01466 ** and make them the children of a node labeled r->index. 01467 */ 01468 res1 = cuddCProjectionRecur(dd,RT,Y,Ysupp); 01469 if (res1 == NULL) return(NULL); 01470 cuddRef(res1); 01471 res2 = cuddCProjectionRecur(dd,RE,Y,Ysupp); 01472 if (res2 == NULL) { 01473 Cudd_RecursiveDeref(dd,res1); 01474 return(NULL); 01475 } 01476 cuddRef(res2); 01477 res = cuddBddIteRecur(dd, dd->vars[index], res1, res2); 01478 if (res == NULL) { 01479 Cudd_RecursiveDeref(dd,res1); 01480 Cudd_RecursiveDeref(dd,res2); 01481 return(NULL); 01482 } 01483 /* If we have reached this point, res1 and res2 are now 01484 ** incorporated in res. cuddDeref is therefore sufficient. 01485 */ 01486 cuddDeref(res1); 01487 cuddDeref(res2); 01488 } else { 01489 /* Compute the cofactors of Y */ 01490 index = y->index; 01491 YT = cuddT(y); 01492 YE = cuddE(y); 01493 if (y != Y) { 01494 YT = Cudd_Not(YT); YE = Cudd_Not(YE); 01495 } 01496 if (YT == Cudd_Not(one)) { 01497 Alpha = Cudd_Not(dd->vars[index]); 01498 Yrest = YE; 01499 Ra = RE; 01500 Ran = RT; 01501 } else { 01502 Alpha = dd->vars[index]; 01503 Yrest = YT; 01504 Ra = RT; 01505 Ran = RE; 01506 } 01507 Gamma = cuddBddExistAbstractRecur(dd,Ra,cuddT(Ysupp)); 01508 if (Gamma == NULL) return(NULL); 01509 if (Gamma == one) { 01510 res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); 01511 if (res1 == NULL) return(NULL); 01512 cuddRef(res1); 01513 res = cuddBddAndRecur(dd, Alpha, res1); 01514 if (res == NULL) { 01515 Cudd_RecursiveDeref(dd,res1); 01516 return(NULL); 01517 } 01518 cuddDeref(res1); 01519 } else if (Gamma == Cudd_Not(one)) { 01520 res1 = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); 01521 if (res1 == NULL) return(NULL); 01522 cuddRef(res1); 01523 res = cuddBddAndRecur(dd, Cudd_Not(Alpha), res1); 01524 if (res == NULL) { 01525 Cudd_RecursiveDeref(dd,res1); 01526 return(NULL); 01527 } 01528 cuddDeref(res1); 01529 } else { 01530 cuddRef(Gamma); 01531 resA = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); 01532 if (resA == NULL) { 01533 Cudd_RecursiveDeref(dd,Gamma); 01534 return(NULL); 01535 } 01536 cuddRef(resA); 01537 res2 = cuddBddAndRecur(dd, Cudd_Not(Gamma), resA); 01538 if (res2 == NULL) { 01539 Cudd_RecursiveDeref(dd,Gamma); 01540 Cudd_RecursiveDeref(dd,resA); 01541 return(NULL); 01542 } 01543 cuddRef(res2); 01544 Cudd_RecursiveDeref(dd,Gamma); 01545 Cudd_RecursiveDeref(dd,resA); 01546 res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); 01547 if (res1 == NULL) { 01548 Cudd_RecursiveDeref(dd,res2); 01549 return(NULL); 01550 } 01551 cuddRef(res1); 01552 res = cuddBddIteRecur(dd, Alpha, res1, res2); 01553 if (res == NULL) { 01554 Cudd_RecursiveDeref(dd,res1); 01555 Cudd_RecursiveDeref(dd,res2); 01556 return(NULL); 01557 } 01558 cuddDeref(res1); 01559 cuddDeref(res2); 01560 } 01561 } 01562 01563 cuddCacheInsert2(dd,Cudd_CProjection,R,Y,res); 01564 01565 return(res); 01566 01567 } /* end of cuddCProjectionRecur */
static int cuddMinHammingDistRecur | ( | DdNode * | f, | |
int * | minterm, | |||
DdHashTable * | table, | |||
int | upperBound | |||
) | [static] |
AutomaticStart
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]
Definition at line 1854 of file cuddPriority.c.
01859 { 01860 DdNode *F, *Ft, *Fe; 01861 double h, hT, hE; 01862 DdNode *zero, *res; 01863 DdManager *dd = table->manager; 01864 01865 statLine(dd); 01866 if (upperBound == 0) return(0); 01867 01868 F = Cudd_Regular(f); 01869 01870 if (cuddIsConstant(F)) { 01871 zero = Cudd_Not(DD_ONE(dd)); 01872 if (f == dd->background || f == zero) { 01873 return(upperBound); 01874 } else { 01875 return(0); 01876 } 01877 } 01878 if ((res = cuddHashTableLookup1(table,f)) != NULL) { 01879 h = cuddV(res); 01880 if (res->ref == 0) { 01881 dd->dead++; 01882 dd->constants.dead++; 01883 } 01884 return((int) h); 01885 } 01886 01887 Ft = cuddT(F); Fe = cuddE(F); 01888 if (Cudd_IsComplement(f)) { 01889 Ft = Cudd_Not(Ft); Fe = Cudd_Not(Fe); 01890 } 01891 if (minterm[F->index] == 0) { 01892 DdNode *temp = Ft; 01893 Ft = Fe; Fe = temp; 01894 } 01895 01896 hT = cuddMinHammingDistRecur(Ft,minterm,table,upperBound); 01897 if (hT == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); 01898 if (hT == 0) { 01899 hE = upperBound; 01900 } else { 01901 hE = cuddMinHammingDistRecur(Fe,minterm,table,upperBound - 1); 01902 if (hE == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); 01903 } 01904 h = ddMin(hT, hE + 1); 01905 01906 if (F->ref != 1) { 01907 ptrint fanout = (ptrint) F->ref; 01908 cuddSatDec(fanout); 01909 res = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) h); 01910 if (!cuddHashTableInsert1(table,f,res,fanout)) { 01911 cuddRef(res); Cudd_RecursiveDeref(dd, res); 01912 return(CUDD_OUT_OF_MEM); 01913 } 01914 } 01915 01916 return((int) h); 01917 01918 } /* 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]
Definition at line 1934 of file cuddPriority.c.
01938 { 01939 DdNode *cube, *t; 01940 01941 /* One and zero are special cases because the distance is implied. */ 01942 if (Cudd_IsConstant(f)) { 01943 *distance = (f == DD_ONE(dd)) ? 0.0 : 01944 (1.0 + (CUDD_VALUE_TYPE) CUDD_CONST_INDEX); 01945 return(f); 01946 } 01947 01948 /* Find out which branch points to the distance and replace the top 01949 ** node with one pointing to zero instead. */ 01950 t = cuddT(f); 01951 if (Cudd_IsConstant(t) && cuddV(t) <= 0) { 01952 #ifdef DD_DEBUG 01953 assert(!Cudd_IsConstant(cuddE(f)) || cuddE(f) == DD_ONE(dd)); 01954 #endif 01955 *distance = -cuddV(t); 01956 cube = cuddUniqueInter(dd, f->index, DD_ZERO(dd), cuddE(f)); 01957 } else { 01958 #ifdef DD_DEBUG 01959 assert(!Cudd_IsConstant(t) || t == DD_ONE(dd)); 01960 #endif 01961 *distance = -cuddV(cuddE(f)); 01962 cube = cuddUniqueInter(dd, f->index, t, DD_ZERO(dd)); 01963 } 01964 01965 return(cube); 01966 01967 } /* end of separateCube */
char rcsid [] DD_UNUSED = "$Id: cuddPriority.c,v 1.33 2009/02/20 02:14:58 fabio Exp $" [static] |
Definition at line 101 of file cuddPriority.c.