#include "mtr.h"
#include "epd.h"
Go to the source code of this file.
#define Cudd_Complement | ( | node | ) | ((DdNode *)((unsigned long)(node) | 01)) |
#define Cudd_E | ( | node | ) | ((Cudd_Regular(node))->type.kids.E) |
Macro***********************************************************************
Synopsis [Returns the else child of an internal node.]
Description [Returns the else child of an internal node. If node
is a constant node, the result is unpredictable.]
SideEffects [none]
SeeAlso [Cudd_T Cudd_V]
#define Cudd_ForeachCube | ( | manager, | |||
f, | |||||
gen, | |||||
cube, | |||||
value | ) |
for((gen) = Cudd_FirstCube(manager, f, &cube, &value);\ Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ (void) Cudd_NextCube(gen, &cube, &value))
Macro***********************************************************************
Synopsis [Iterates over the cubes of a decision diagram.]
Description [Iterates over the cubes of a decision diagram f.
Cudd_ForeachCube allocates and frees the generator. Therefore the application should not try to do that. Also, the cube is freed at the end of Cudd_ForeachCube and hence is not available outside of the loop.
CAUTION: It is assumed that dynamic reordering will not occur while there are open generators. It is the user's responsibility to make sure that dynamic reordering does not occur. As long as new nodes are not created during generation, and dynamic reordering is not called explicitly, dynamic reordering will not occur. Alternatively, it is sufficient to disable dynamic reordering. It is a mistake to dispose of a diagram on which generation is ongoing.]
SideEffects [none]
SeeAlso [Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_GenFree Cudd_IsGenEmpty Cudd_AutodynDisable]
#define Cudd_ForeachNode | ( | manager, | |||
f, | |||||
gen, | |||||
node | ) |
for((gen) = Cudd_FirstNode(manager, f, &node);\ Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ (void) Cudd_NextNode(gen, &node))
Macro***********************************************************************
Synopsis [Iterates over the nodes of a decision diagram.]
Description [Iterates over the nodes of a decision diagram f.
The nodes are returned in a seemingly random order. Cudd_ForeachNode allocates and frees the generator. Therefore the application should not try to do that.
CAUTION: It is assumed that dynamic reordering will not occur while there are open generators. It is the user's responsibility to make sure that dynamic reordering does not occur. As long as new nodes are not created during generation, and dynamic reordering is not called explicitly, dynamic reordering will not occur. Alternatively, it is sufficient to disable dynamic reordering. It is a mistake to dispose of a diagram on which generation is ongoing.]
SideEffects [none]
SeeAlso [Cudd_ForeachCube Cudd_FirstNode Cudd_NextNode Cudd_GenFree Cudd_IsGenEmpty Cudd_AutodynDisable]
#define Cudd_ForeachPrime | ( | manager, | |||
l, | |||||
u, | |||||
gen, | |||||
cube | ) |
for((gen) = Cudd_FirstPrime(manager, l, u, &cube);\ Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ (void) Cudd_NextPrime(gen, &cube))
Macro***********************************************************************
Synopsis [Iterates over the primes of a Boolean function.]
Description [Iterates over the primes of a Boolean function producing a prime and irredundant cover.
The Boolean function is described by an upper bound and a lower bound. If the function is completely specified, the two bounds coincide. Cudd_ForeachPrime allocates and frees the generator. Therefore the application should not try to do that. Also, the cube is freed at the end of Cudd_ForeachPrime and hence is not available outside of the loop.
CAUTION: It is a mistake to change a diagram on which generation is ongoing.]
SideEffects [none]
SeeAlso [Cudd_ForeachCube Cudd_FirstPrime Cudd_NextPrime Cudd_GenFree Cudd_IsGenEmpty]
#define Cudd_IsComplement | ( | node | ) | ((int) ((long) (node) & 01)) |
#define Cudd_IsConstant | ( | node | ) | ((Cudd_Regular(node))->index == CUDD_CONST_INDEX) |
Macro***********************************************************************
Synopsis [Returns 1 if the node is a constant node.]
Description [Returns 1 if the node is a constant node (rather than an internal node). All constant nodes have the same index (CUDD_CONST_INDEX). The pointer passed to Cudd_IsConstant may be either regular or complemented.]
SideEffects [none]
SeeAlso []
#define CUDD_MAXINDEX ((DdHalfWord) ~0) |
#define Cudd_Not | ( | node | ) | ((DdNode *)((long)(node) ^ 01)) |
#define Cudd_NotCond | ( | node, | |||
c | ) | ((DdNode *)((long)(node) ^ (c))) |
Macro***********************************************************************
Synopsis [Complements a DD if a condition is true.]
Description [Complements a DD if condition c is true; c should be either 0 or 1, because it is used directly (for efficiency). If in doubt on the values c may take, use "(c) ? Cudd_Not(node) : node".]
SideEffects [none]
SeeAlso [Cudd_Not]
#define Cudd_ReadIndex | ( | dd, | |||
index | ) | (Cudd_ReadPerm(dd,index)) |
Macro***********************************************************************
Synopsis [Returns the current position in the order of variable index.]
Description [Returns the current position in the order of variable index. This macro is obsolete and is kept for compatibility. New applications should use Cudd_ReadPerm instead.]
SideEffects [none]
SeeAlso [Cudd_ReadPerm]
#define Cudd_Regular | ( | node | ) | ((DdNode *)((unsigned long)(node) & ~01)) |
#define Cudd_T | ( | node | ) | ((Cudd_Regular(node))->type.kids.T) |
Macro***********************************************************************
Synopsis [Returns the then child of an internal node.]
Description [Returns the then child of an internal node. If node
is a constant node, the result is unpredictable.]
SideEffects [none]
SeeAlso [Cudd_E Cudd_V]
#define Cudd_V | ( | node | ) | ((Cudd_Regular(node))->type.value) |
Macro***********************************************************************
Synopsis [Returns the value of a constant node.]
Description [Returns the value of a constant node. If node
is an internal node, the result is unpredictable.]
SideEffects [none]
SeeAlso [Cudd_T Cudd_E]
#define CUDD_VERSION "2.4.2" |
CHeaderFile*****************************************************************
FileName [cudd.h]
PackageName [cudd]
Synopsis [The University of Colorado decision diagram package.]
Description [External functions and data strucures of the CUDD package.
Modified by Abelardo Pardo to interface it to VIS. ]
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.]
Revision [
]
#define Cudd_zddForeachPath | ( | manager, | |||
f, | |||||
gen, | |||||
path | ) |
for((gen) = Cudd_zddFirstPath(manager, f, &path);\ Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ (void) Cudd_zddNextPath(gen, &path))
Macro***********************************************************************
Synopsis [Iterates over the paths of a ZDD.]
Description [Iterates over the paths of a ZDD f.
Cudd_zddForeachPath allocates and frees the generator. Therefore the application should not try to do that. Also, the path is freed at the end of Cudd_zddForeachPath and hence is not available outside of the loop.
CAUTION: It is assumed that dynamic reordering will not occur while there are open generators. It is the user's responsibility to make sure that dynamic reordering does not occur. As long as new nodes are not created during generation, and dynamic reordering is not called explicitly, dynamic reordering will not occur. Alternatively, it is sufficient to disable dynamic reordering. It is a mistake to dispose of a diagram on which generation is ongoing.]
SideEffects [none]
SeeAlso [Cudd_zddFirstPath Cudd_zddNextPath Cudd_GenFree Cudd_IsGenEmpty Cudd_AutodynDisable]
typedef unsigned short int DdApaDigit |
typedef unsigned int DdApaDoubleDigit |
typedef DdApaDigit* DdApaNumber |
typedef unsigned short DdHalfWord |
enum Cudd_AggregationType |
Enum************************************************************************
Synopsis [Type of aggregation methods.]
Description [Type of aggregation methods.]
CUDD_NO_CHECK | |
CUDD_GROUP_CHECK | |
CUDD_GROUP_CHECK2 | |
CUDD_GROUP_CHECK3 | |
CUDD_GROUP_CHECK4 | |
CUDD_GROUP_CHECK5 | |
CUDD_GROUP_CHECK6 | |
CUDD_GROUP_CHECK7 | |
CUDD_GROUP_CHECK8 | |
CUDD_GROUP_CHECK9 |
Definition at line 184 of file cudd.h.
00184 { 00185 CUDD_NO_CHECK, 00186 CUDD_GROUP_CHECK, 00187 CUDD_GROUP_CHECK2, 00188 CUDD_GROUP_CHECK3, 00189 CUDD_GROUP_CHECK4, 00190 CUDD_GROUP_CHECK5, 00191 CUDD_GROUP_CHECK6, 00192 CUDD_GROUP_CHECK7, 00193 CUDD_GROUP_CHECK8, 00194 CUDD_GROUP_CHECK9 00195 } Cudd_AggregationType;
enum Cudd_ErrorType |
Enum************************************************************************
Synopsis [Type of error codes.]
Description [Type of error codes.]
CUDD_NO_ERROR | |
CUDD_MEMORY_OUT | |
CUDD_TOO_MANY_NODES | |
CUDD_MAX_MEM_EXCEEDED | |
CUDD_INVALID_ARG | |
CUDD_INTERNAL_ERROR |
Definition at line 220 of file cudd.h.
00220 { 00221 CUDD_NO_ERROR, 00222 CUDD_MEMORY_OUT, 00223 CUDD_TOO_MANY_NODES, 00224 CUDD_MAX_MEM_EXCEEDED, 00225 CUDD_INVALID_ARG, 00226 CUDD_INTERNAL_ERROR 00227 } Cudd_ErrorType;
enum Cudd_HookType |
Enum************************************************************************
Synopsis [Type of hooks.]
Description [Type of hooks.]
Definition at line 205 of file cudd.h.
00205 { 00206 CUDD_PRE_GC_HOOK, 00207 CUDD_POST_GC_HOOK, 00208 CUDD_PRE_REORDERING_HOOK, 00209 CUDD_POST_REORDERING_HOOK 00210 } Cudd_HookType;
enum Cudd_LazyGroupType |
Enum************************************************************************
Synopsis [Group type for lazy sifting.]
Description [Group type for lazy sifting.]
Definition at line 237 of file cudd.h.
00237 { 00238 CUDD_LAZY_NONE, 00239 CUDD_LAZY_SOFT_GROUP, 00240 CUDD_LAZY_HARD_GROUP, 00241 CUDD_LAZY_UNGROUP 00242 } Cudd_LazyGroupType;
enum Cudd_ReorderingType |
Enum************************************************************************
Synopsis [Type of reordering algorithm.]
Description [Type of reordering algorithm.]
Definition at line 151 of file cudd.h.
00151 { 00152 CUDD_REORDER_SAME, 00153 CUDD_REORDER_NONE, 00154 CUDD_REORDER_RANDOM, 00155 CUDD_REORDER_RANDOM_PIVOT, 00156 CUDD_REORDER_SIFT, 00157 CUDD_REORDER_SIFT_CONVERGE, 00158 CUDD_REORDER_SYMM_SIFT, 00159 CUDD_REORDER_SYMM_SIFT_CONV, 00160 CUDD_REORDER_WINDOW2, 00161 CUDD_REORDER_WINDOW3, 00162 CUDD_REORDER_WINDOW4, 00163 CUDD_REORDER_WINDOW2_CONV, 00164 CUDD_REORDER_WINDOW3_CONV, 00165 CUDD_REORDER_WINDOW4_CONV, 00166 CUDD_REORDER_GROUP_SIFT, 00167 CUDD_REORDER_GROUP_SIFT_CONV, 00168 CUDD_REORDER_ANNEALING, 00169 CUDD_REORDER_GENETIC, 00170 CUDD_REORDER_LINEAR, 00171 CUDD_REORDER_LINEAR_CONVERGE, 00172 CUDD_REORDER_LAZY_SIFT, 00173 CUDD_REORDER_EXACT 00174 } Cudd_ReorderingType;
enum Cudd_VariableType |
Enum************************************************************************
Synopsis [Variable type.]
Description [Variable type. Currently used only in lazy sifting.]
Definition at line 252 of file cudd.h.
00252 { 00253 CUDD_VAR_PRIMARY_INPUT, 00254 CUDD_VAR_PRESENT_STATE, 00255 CUDD_VAR_NEXT_STATE 00256 } Cudd_VariableType;
Function********************************************************************
Synopsis [f if f==g; background if f!=g.]
Description [Returns NULL if not a terminal case; f op g otherwise, where f op g is f if f==g; background if f!=g.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 547 of file cuddAddApply.c.
00551 { 00552 DdNode *F, *G; 00553 00554 F = *f; G = *g; 00555 if (F == G) return(F); 00556 if (F == dd->background) return(F); 00557 if (G == dd->background) return(G); 00558 if (cuddIsConstant(F) && cuddIsConstant(G)) return(dd->background); 00559 return(NULL); 00560 00561 } /* end of Cudd_addAgreement */
DdNode* Cudd_addApply | ( | DdManager * | dd, | |
DdNode * | *)(DdManager *, DdNode **, DdNode **, | |||
DdNode * | f, | |||
DdNode * | g | |||
) |
DdNode* Cudd_addBddInterval | ( | DdManager * | dd, | |
DdNode * | f, | |||
CUDD_VALUE_TYPE | lower, | |||
CUDD_VALUE_TYPE | upper | |||
) |
Function********************************************************************
Synopsis [Converts an ADD to a BDD.]
Description [Converts an ADD to a BDD by replacing all discriminants greater than or equal to lower and less than or equal to upper with 1, and all other discriminants with 0. Returns a pointer to the resulting BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addBddThreshold Cudd_addBddStrictThreshold Cudd_addBddPattern Cudd_BddToAdd]
Definition at line 240 of file cuddBridge.c.
00245 { 00246 DdNode *res; 00247 DdNode *l; 00248 DdNode *u; 00249 00250 /* Create constant nodes for the interval bounds, so that we can use 00251 ** the global cache. 00252 */ 00253 l = cuddUniqueConst(dd,lower); 00254 if (l == NULL) return(NULL); 00255 cuddRef(l); 00256 u = cuddUniqueConst(dd,upper); 00257 if (u == NULL) { 00258 Cudd_RecursiveDeref(dd,l); 00259 return(NULL); 00260 } 00261 cuddRef(u); 00262 00263 do { 00264 dd->reordered = 0; 00265 res = addBddDoInterval(dd, f, l, u); 00266 } while (dd->reordered == 1); 00267 00268 if (res == NULL) { 00269 Cudd_RecursiveDeref(dd, l); 00270 Cudd_RecursiveDeref(dd, u); 00271 return(NULL); 00272 } 00273 cuddRef(res); 00274 Cudd_RecursiveDeref(dd, l); 00275 Cudd_RecursiveDeref(dd, u); 00276 cuddDeref(res); 00277 return(res); 00278 00279 } /* end of Cudd_addBddInterval */
Function********************************************************************
Synopsis [Converts an ADD to a BDD by extracting the i-th bit from the leaves.]
Description [Converts an ADD to a BDD by replacing all discriminants whose i-th bit is equal to 1 with 1, and all other discriminants with 0. The i-th bit refers to the integer representation of the leaf value. If the value is has a fractional part, it is ignored. Repeated calls to this procedure allow one to transform an integer-valued ADD into an array of BDDs, one for each bit of the leaf values. Returns a pointer to the resulting BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd]
Definition at line 302 of file cuddBridge.c.
00306 { 00307 DdNode *res; 00308 DdNode *index; 00309 00310 index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit); 00311 if (index == NULL) return(NULL); 00312 cuddRef(index); 00313 00314 do { 00315 dd->reordered = 0; 00316 res = addBddDoIthBit(dd, f, index); 00317 } while (dd->reordered == 1); 00318 00319 if (res == NULL) { 00320 Cudd_RecursiveDeref(dd, index); 00321 return(NULL); 00322 } 00323 cuddRef(res); 00324 Cudd_RecursiveDeref(dd, index); 00325 cuddDeref(res); 00326 return(res); 00327 00328 } /* end of Cudd_addBddIthBit */
Function********************************************************************
Synopsis [Converts an ADD to a BDD.]
Description [Converts an ADD to a BDD by replacing all discriminants different from 0 with 1. Returns a pointer to the resulting BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_BddToAdd Cudd_addBddThreshold Cudd_addBddInterval Cudd_addBddStrictThreshold]
Definition at line 375 of file cuddBridge.c.
00378 { 00379 DdNode *res; 00380 00381 do { 00382 dd->reordered = 0; 00383 res = cuddAddBddDoPattern(dd, f); 00384 } while (dd->reordered == 1); 00385 return(res); 00386 00387 } /* end of Cudd_addBddPattern */
Function********************************************************************
Synopsis [Converts an ADD to a BDD.]
Description [Converts an ADD to a BDD by replacing all discriminants STRICTLY greater than value with 1, and all other discriminants with 0. Returns a pointer to the resulting BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd Cudd_addBddThreshold]
Definition at line 195 of file cuddBridge.c.
00199 { 00200 DdNode *res; 00201 DdNode *val; 00202 00203 val = cuddUniqueConst(dd,value); 00204 if (val == NULL) return(NULL); 00205 cuddRef(val); 00206 00207 do { 00208 dd->reordered = 0; 00209 res = addBddDoStrictThreshold(dd, f, val); 00210 } while (dd->reordered == 1); 00211 00212 if (res == NULL) { 00213 Cudd_RecursiveDeref(dd, val); 00214 return(NULL); 00215 } 00216 cuddRef(res); 00217 Cudd_RecursiveDeref(dd, val); 00218 cuddDeref(res); 00219 return(res); 00220 00221 } /* end of Cudd_addBddStrictThreshold */
AutomaticEnd Function********************************************************************
Synopsis [Converts an ADD to a BDD.]
Description [Converts an ADD to a BDD by replacing all discriminants greater than or equal to value with 1, and all other discriminants with 0. Returns a pointer to the resulting BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd Cudd_addBddStrictThreshold]
Definition at line 150 of file cuddBridge.c.
00154 { 00155 DdNode *res; 00156 DdNode *val; 00157 00158 val = cuddUniqueConst(dd,value); 00159 if (val == NULL) return(NULL); 00160 cuddRef(val); 00161 00162 do { 00163 dd->reordered = 0; 00164 res = addBddDoThreshold(dd, f, val); 00165 } while (dd->reordered == 1); 00166 00167 if (res == NULL) { 00168 Cudd_RecursiveDeref(dd, val); 00169 return(NULL); 00170 } 00171 cuddRef(res); 00172 Cudd_RecursiveDeref(dd, val); 00173 cuddDeref(res); 00174 return(res); 00175 00176 } /* end of Cudd_addBddThreshold */
Function********************************************************************
Synopsis [Computes the complement of an ADD a la C language.]
Description [Computes the complement of an ADD a la C language: The complement of 0 is 1 and the complement of everything else is 0. Returns a pointer to the resulting ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addNegate]
Definition at line 343 of file cuddAddIte.c.
00346 { 00347 DdNode *res; 00348 00349 do { 00350 dd->reordered = 0; 00351 res = cuddAddCmplRecur(dd,f); 00352 } while (dd->reordered == 1); 00353 return(res); 00354 00355 } /* end of Cudd_addCmpl */
Function********************************************************************
Synopsis [Substitutes g for x_v in the ADD for f.]
Description [Substitutes g for x_v in the ADD for f. v is the index of the variable to be substituted. g must be a 0-1 ADD. Cudd_bddCompose passes the corresponding projection function to the recursive procedure, so that the cache may be used. Returns the composed ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddCompose]
Definition at line 200 of file cuddCompose.c.
00205 { 00206 DdNode *proj, *res; 00207 00208 /* Sanity check. */ 00209 if (v < 0 || v >= dd->size) return(NULL); 00210 00211 proj = dd->vars[v]; 00212 do { 00213 dd->reordered = 0; 00214 res = cuddAddComposeRecur(dd,f,g,proj); 00215 } while (dd->reordered == 1); 00216 return(res); 00217 00218 } /* end of Cudd_addCompose */
Function********************************************************************
Synopsis [Computes the cube of an array of ADD variables.]
Description [Computes the cube of an array of ADD variables. If non-null, the phase argument indicates which literal of each variable should appear in the cube. If phase\[i\] is nonzero, then the positive literal is used. If phase is NULL, the cube is positive unate. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [none]
SeeAlso [Cudd_bddComputeCube]
Definition at line 2242 of file cuddUtil.c.
02247 { 02248 DdNode *cube, *zero; 02249 DdNode *fn; 02250 int i; 02251 02252 cube = DD_ONE(dd); 02253 cuddRef(cube); 02254 zero = DD_ZERO(dd); 02255 02256 for (i = n - 1; i >= 0; i--) { 02257 if (phase == NULL || phase[i] != 0) { 02258 fn = Cudd_addIte(dd,vars[i],cube,zero); 02259 } else { 02260 fn = Cudd_addIte(dd,vars[i],zero,cube); 02261 } 02262 if (fn == NULL) { 02263 Cudd_RecursiveDeref(dd,cube); 02264 return(NULL); 02265 } 02266 cuddRef(fn); 02267 Cudd_RecursiveDeref(dd,cube); 02268 cube = fn; 02269 } 02270 cuddDeref(cube); 02271 02272 return(cube); 02273 02274 } /* end of Cudd_addComputeCube */
Function********************************************************************
Synopsis [Returns the ADD for constant c.]
Description [Retrieves the ADD for constant c if it already exists, or creates a new ADD. Returns a pointer to the ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addNewVar Cudd_addIthVar]
Definition at line 616 of file cuddAPI.c.
00619 { 00620 return(cuddUniqueConst(dd,c)); 00621 00622 } /* end of Cudd_addConst */
Function********************************************************************
Synopsis [Computes f constrain c for ADDs.]
Description [Computes f constrain c (f @ c), for f an ADD and c a 0-1 ADD. List of special cases:
Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddConstrain]
Definition at line 332 of file cuddGenCof.c.
00336 { 00337 DdNode *res; 00338 00339 do { 00340 dd->reordered = 0; 00341 res = cuddAddConstrainRecur(dd,f,c); 00342 } while (dd->reordered == 1); 00343 return(res); 00344 00345 } /* end of Cudd_addConstrain */
Function********************************************************************
Synopsis [Returns plusinfinity if f=g; returns min(f,g) if f!=g.]
Description [Returns NULL if not a terminal case; f op g otherwise, where f op g is plusinfinity if f=g; min(f,g) if f!=g.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 507 of file cuddAddApply.c.
00511 { 00512 DdNode *F, *G; 00513 00514 F = *f; G = *g; 00515 if (F == G) return(DD_PLUS_INFINITY(dd)); 00516 if (F == DD_PLUS_INFINITY(dd)) return(G); 00517 if (G == DD_PLUS_INFINITY(dd)) return(F); 00518 if (cuddIsConstant(F) && cuddIsConstant(G)) { 00519 if (cuddV(F) != cuddV(G)) { 00520 if (cuddV(F) < cuddV(G)) { 00521 return(F); 00522 } else { 00523 return(G); 00524 } 00525 } else { 00526 return(DD_PLUS_INFINITY(dd)); 00527 } 00528 } 00529 return(NULL); 00530 00531 } /* end of Cudd_addDiff */
Function********************************************************************
Synopsis [Integer and floating point division.]
Description [Integer and floating point division. Returns NULL if not a terminal case; f / g otherwise.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 308 of file cuddAddApply.c.
00312 { 00313 DdNode *res; 00314 DdNode *F, *G; 00315 CUDD_VALUE_TYPE value; 00316 00317 F = *f; G = *g; 00318 /* We would like to use F == G -> F/G == 1, but F and G may 00319 ** contain zeroes. */ 00320 if (F == DD_ZERO(dd)) return(DD_ZERO(dd)); 00321 if (G == DD_ONE(dd)) return(F); 00322 if (cuddIsConstant(F) && cuddIsConstant(G)) { 00323 value = cuddV(F)/cuddV(G); 00324 res = cuddUniqueConst(dd,value); 00325 return(res); 00326 } 00327 return(NULL); 00328 00329 } /* end of Cudd_addDivide */
Function********************************************************************
Synopsis [Checks whether ADD g is constant whenever ADD f is 1.]
Description [Checks whether ADD g is constant whenever ADD f is 1. f must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may or may not be constant) or DD_NON_CONSTANT. If f is identically 0, the check is assumed to be successful, and the background value is returned. No new nodes are created.]
SideEffects [None]
SeeAlso [Cudd_addIteConstant Cudd_addLeq]
Definition at line 256 of file cuddAddIte.c.
00260 { 00261 DdNode *zero; 00262 DdNode *Fv,*Fnv,*Gv,*Gnv,*r,*t,*e; 00263 unsigned int topf,topg; 00264 00265 #ifdef DD_DEBUG 00266 assert(!Cudd_IsComplement(f)); 00267 #endif 00268 00269 statLine(dd); 00270 /* Terminal cases. */ 00271 if (f == DD_ONE(dd) || cuddIsConstant(g)) { 00272 return(g); 00273 } 00274 if (f == (zero = DD_ZERO(dd))) { 00275 return(dd->background); 00276 } 00277 00278 #ifdef DD_DEBUG 00279 assert(!cuddIsConstant(f)); 00280 #endif 00281 /* From now on, f and g are known not to be constants. */ 00282 00283 topf = cuddI(dd,f->index); 00284 topg = cuddI(dd,g->index); 00285 00286 /* Check cache. */ 00287 r = cuddConstantLookup(dd,DD_ADD_EVAL_CONST_TAG,f,g,g); 00288 if (r != NULL) { 00289 return(r); 00290 } 00291 00292 /* Compute cofactors. */ 00293 if (topf <= topg) { 00294 Fv = cuddT(f); Fnv = cuddE(f); 00295 } else { 00296 Fv = Fnv = f; 00297 } 00298 if (topg <= topf) { 00299 Gv = cuddT(g); Gnv = cuddE(g); 00300 } else { 00301 Gv = Gnv = g; 00302 } 00303 00304 /* Recursive step. */ 00305 if (Fv != zero) { 00306 t = Cudd_addEvalConst(dd,Fv,Gv); 00307 if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { 00308 cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); 00309 return(DD_NON_CONSTANT); 00310 } 00311 if (Fnv != zero) { 00312 e = Cudd_addEvalConst(dd,Fnv,Gnv); 00313 if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { 00314 cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); 00315 return(DD_NON_CONSTANT); 00316 } 00317 } 00318 cuddCacheInsert2(dd,Cudd_addEvalConst,f,g,t); 00319 return(t); 00320 } else { /* Fnv must be != zero */ 00321 e = Cudd_addEvalConst(dd,Fnv,Gnv); 00322 cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e); 00323 return(e); 00324 } 00325 00326 } /* end of Cudd_addEvalConst */
AutomaticEnd Function********************************************************************
Synopsis [Existentially Abstracts all the variables in cube from f.]
Description [Abstracts all the variables in cube from f by summing over all possible values taken by the variables. Returns the abstracted ADD.]
SideEffects [None]
SeeAlso [Cudd_addUnivAbstract Cudd_bddExistAbstract Cudd_addOrAbstract]
Definition at line 125 of file cuddAddAbs.c.
00129 { 00130 DdNode *res; 00131 00132 two = cuddUniqueConst(manager,(CUDD_VALUE_TYPE) 2); 00133 if (two == NULL) return(NULL); 00134 cuddRef(two); 00135 00136 if (addCheckPositiveCube(manager, cube) == 0) { 00137 (void) fprintf(manager->err,"Error: Can only abstract cubes"); 00138 return(NULL); 00139 } 00140 00141 do { 00142 manager->reordered = 0; 00143 res = cuddAddExistAbstractRecur(manager, f, cube); 00144 } while (manager->reordered == 1); 00145 00146 if (res == NULL) { 00147 Cudd_RecursiveDeref(manager,two); 00148 return(NULL); 00149 } 00150 cuddRef(res); 00151 Cudd_RecursiveDeref(manager,two); 00152 cuddDeref(res); 00153 00154 return(res); 00155 00156 } /* end of Cudd_addExistAbstract */
AutomaticEnd Function********************************************************************
Synopsis [Finds the maximum discriminant of f.]
Description [Returns a pointer to a constant ADD.]
SideEffects [None]
Definition at line 120 of file cuddAddFind.c.
00123 { 00124 DdNode *t, *e, *res; 00125 00126 statLine(dd); 00127 if (cuddIsConstant(f)) { 00128 return(f); 00129 } 00130 00131 res = cuddCacheLookup1(dd,Cudd_addFindMax,f); 00132 if (res != NULL) { 00133 return(res); 00134 } 00135 00136 t = Cudd_addFindMax(dd,cuddT(f)); 00137 if (t == DD_PLUS_INFINITY(dd)) return(t); 00138 00139 e = Cudd_addFindMax(dd,cuddE(f)); 00140 00141 res = (cuddV(t) >= cuddV(e)) ? t : e; 00142 00143 cuddCacheInsert1(dd,Cudd_addFindMax,f,res); 00144 00145 return(res); 00146 00147 } /* end of Cudd_addFindMax */
Function********************************************************************
Synopsis [Finds the minimum discriminant of f.]
Description [Returns a pointer to a constant ADD.]
SideEffects [None]
Definition at line 160 of file cuddAddFind.c.
00163 { 00164 DdNode *t, *e, *res; 00165 00166 statLine(dd); 00167 if (cuddIsConstant(f)) { 00168 return(f); 00169 } 00170 00171 res = cuddCacheLookup1(dd,Cudd_addFindMin,f); 00172 if (res != NULL) { 00173 return(res); 00174 } 00175 00176 t = Cudd_addFindMin(dd,cuddT(f)); 00177 if (t == DD_MINUS_INFINITY(dd)) return(t); 00178 00179 e = Cudd_addFindMin(dd,cuddE(f)); 00180 00181 res = (cuddV(t) <= cuddV(e)) ? t : e; 00182 00183 cuddCacheInsert1(dd,Cudd_addFindMin,f,res); 00184 00185 return(res); 00186 00187 } /* end of Cudd_addFindMin */
DdNode* Cudd_addGeneralVectorCompose | ( | DdManager * | dd, | |
DdNode * | f, | |||
DdNode ** | vectorOn, | |||
DdNode ** | vectorOff | |||
) |
Function********************************************************************
Synopsis [Composes an ADD with a vector of ADDs.]
Description [Given a vector of ADDs, creates a new ADD by substituting the ADDs for the variables of the ADD f. vectorOn contains ADDs to be substituted for the x_v and vectorOff the ADDs to be substituted for x_v'. There should be an entry in vector for each variable in the manager. If no substitution is sought for a given variable, the corresponding projection function should be specified in the vector. This function implements simultaneous composition. Returns a pointer to the resulting ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addVectorCompose Cudd_addNonSimCompose Cudd_addPermute Cudd_addCompose Cudd_bddVectorCompose]
Definition at line 617 of file cuddCompose.c.
00622 { 00623 DdHashTable *table; 00624 DdNode *res; 00625 int deepest; 00626 int i; 00627 00628 do { 00629 dd->reordered = 0; 00630 /* Initialize local cache. */ 00631 table = cuddHashTableInit(dd,1,2); 00632 if (table == NULL) return(NULL); 00633 00634 /* Find deepest real substitution. */ 00635 for (deepest = dd->size - 1; deepest >= 0; deepest--) { 00636 i = dd->invperm[deepest]; 00637 if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) { 00638 break; 00639 } 00640 } 00641 00642 /* Recursively solve the problem. */ 00643 res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn, 00644 vectorOff,deepest); 00645 if (res != NULL) cuddRef(res); 00646 00647 /* Dispose of local cache. */ 00648 cuddHashTableQuit(table); 00649 } while (dd->reordered == 1); 00650 00651 if (res != NULL) cuddDeref(res); 00652 return(res); 00653 00654 } /* end of Cudd_addGeneralVectorCompose */
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 */
int Cudd_addHarwell | ( | FILE * | fp, | |
DdManager * | dd, | |||
DdNode ** | E, | |||
DdNode *** | x, | |||
DdNode *** | y, | |||
DdNode *** | xn, | |||
DdNode *** | yn_, | |||
int * | nx, | |||
int * | ny, | |||
int * | m, | |||
int * | n, | |||
int | bx, | |||
int | sx, | |||
int | by, | |||
int | sy, | |||
int | pr | |||
) |
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Reads in a matrix in the format of the Harwell-Boeing benchmark suite.]
Description [Reads in a matrix in the format of the Harwell-Boeing benchmark suite. The variables are ordered as follows: <blockquote> x\[0\] y\[0\] x\[1\] y\[1\] ... </blockquote> 0 is the most significant bit. On input, nx and ny hold the numbers of row and column variables already in existence. On output, they hold the numbers of row and column variables actually used by the matrix. m and n are set to the numbers of rows and columns of the matrix. Their values on input are immaterial. Returns 1 on success; 0 otherwise. The ADD for the sparse matrix is returned in E, and its reference count is > 0.]
SideEffects [None]
SeeAlso [Cudd_addRead Cudd_bddRead]
Definition at line 120 of file cuddHarwell.c.
00137 { 00138 DdNode *one, *zero; 00139 DdNode *w; 00140 DdNode *cubex, *cubey, *minterm1; 00141 int u, v, err, i, j, nv; 00142 double val; 00143 DdNode **lx, **ly, **lxn, **lyn; /* local copies of x, y, xn, yn_ */ 00144 int lnx, lny; /* local copies of nx and ny */ 00145 char title[73], key[9], mxtype[4], rhstyp[4]; 00146 int totcrd, ptrcrd, indcrd, valcrd, rhscrd, 00147 nrow, ncol, nnzero, neltvl, 00148 nrhs, nrhsix; 00149 int *colptr, *rowind; 00150 #if 0 00151 int nguess, nexact; 00152 int *rhsptr, *rhsind; 00153 #endif 00154 00155 if (*nx < 0 || *ny < 0) return(0); 00156 00157 one = DD_ONE(dd); 00158 zero = DD_ZERO(dd); 00159 00160 /* Read the header */ 00161 err = fscanf(fp, "%72c %8c", title, key); 00162 if (err == EOF) { 00163 return(0); 00164 } else if (err != 2) { 00165 return(0); 00166 } 00167 title[72] = (char) 0; 00168 key[8] = (char) 0; 00169 00170 err = fscanf(fp, "%d %d %d %d %d", &totcrd, &ptrcrd, &indcrd, 00171 &valcrd, &rhscrd); 00172 if (err == EOF) { 00173 return(0); 00174 } else if (err != 5) { 00175 return(0); 00176 } 00177 00178 err = fscanf(fp, "%3s %d %d %d %d", mxtype, &nrow, &ncol, 00179 &nnzero, &neltvl); 00180 if (err == EOF) { 00181 return(0); 00182 } else if (err != 5) { 00183 return(0); 00184 } 00185 00186 /* Skip FORTRAN formats */ 00187 if (rhscrd == 0) { 00188 err = fscanf(fp, "%*s %*s %*s \n"); 00189 } else { 00190 err = fscanf(fp, "%*s %*s %*s %*s \n"); 00191 } 00192 if (err == EOF) { 00193 return(0); 00194 } else if (err != 0) { 00195 return(0); 00196 } 00197 00198 /* Print out some stuff if requested to be verbose */ 00199 if (pr>0) { 00200 (void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key, 00201 mxtype, nrow, ncol, nnzero); 00202 if (pr>1) (void) fprintf(dd->out,"%s\n", title); 00203 } 00204 00205 /* Check matrix type */ 00206 if (mxtype[0] != 'R' || mxtype[1] != 'U' || mxtype[2] != 'A') { 00207 (void) fprintf(dd->err,"%s: Illegal matrix type: %s\n", 00208 key, mxtype); 00209 return(0); 00210 } 00211 if (neltvl != 0) return(0); 00212 00213 /* Read optional 5-th line */ 00214 if (rhscrd != 0) { 00215 err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix); 00216 if (err == EOF) { 00217 return(0); 00218 } else if (err != 3) { 00219 return(0); 00220 } 00221 rhstyp[3] = (char) 0; 00222 if (rhstyp[0] != 'F') { 00223 (void) fprintf(dd->err, 00224 "%s: Sparse right-hand side not yet supported\n", key); 00225 return(0); 00226 } 00227 if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs); 00228 } else { 00229 nrhs = 0; 00230 } 00231 00232 /* Compute the number of variables */ 00233 00234 /* row and column numbers start from 0 */ 00235 u = nrow - 1; 00236 for (i=0; u > 0; i++) { 00237 u >>= 1; 00238 } 00239 lnx = i; 00240 if (nrhs == 0) { 00241 v = ncol - 1; 00242 } else { 00243 v = 2* (ddMax(ncol, nrhs) - 1); 00244 } 00245 for (i=0; v > 0; i++) { 00246 v >>= 1; 00247 } 00248 lny = i; 00249 00250 /* Allocate or reallocate arrays for variables as needed */ 00251 if (*nx == 0) { 00252 if (lnx > 0) { 00253 *x = lx = ALLOC(DdNode *,lnx); 00254 if (lx == NULL) { 00255 dd->errorCode = CUDD_MEMORY_OUT; 00256 return(0); 00257 } 00258 *xn = lxn = ALLOC(DdNode *,lnx); 00259 if (lxn == NULL) { 00260 dd->errorCode = CUDD_MEMORY_OUT; 00261 return(0); 00262 } 00263 } else { 00264 *x = *xn = NULL; 00265 } 00266 } else if (lnx > *nx) { 00267 *x = lx = REALLOC(DdNode *, *x, lnx); 00268 if (lx == NULL) { 00269 dd->errorCode = CUDD_MEMORY_OUT; 00270 return(0); 00271 } 00272 *xn = lxn = REALLOC(DdNode *, *xn, lnx); 00273 if (lxn == NULL) { 00274 dd->errorCode = CUDD_MEMORY_OUT; 00275 return(0); 00276 } 00277 } else { 00278 lx = *x; 00279 lxn = *xn; 00280 } 00281 if (*ny == 0) { 00282 if (lny >0) { 00283 *y = ly = ALLOC(DdNode *,lny); 00284 if (ly == NULL) { 00285 dd->errorCode = CUDD_MEMORY_OUT; 00286 return(0); 00287 } 00288 *yn_ = lyn = ALLOC(DdNode *,lny); 00289 if (lyn == NULL) { 00290 dd->errorCode = CUDD_MEMORY_OUT; 00291 return(0); 00292 } 00293 } else { 00294 *y = *yn_ = NULL; 00295 } 00296 } else if (lny > *ny) { 00297 *y = ly = REALLOC(DdNode *, *y, lny); 00298 if (ly == NULL) { 00299 dd->errorCode = CUDD_MEMORY_OUT; 00300 return(0); 00301 } 00302 *yn_ = lyn = REALLOC(DdNode *, *yn_, lny); 00303 if (lyn == NULL) { 00304 dd->errorCode = CUDD_MEMORY_OUT; 00305 return(0); 00306 } 00307 } else { 00308 ly = *y; 00309 lyn = *yn_; 00310 } 00311 00312 /* Create new variables as needed */ 00313 for (i= *nx,nv=bx+(*nx)*sx; i < lnx; i++,nv+=sx) { 00314 do { 00315 dd->reordered = 0; 00316 lx[i] = cuddUniqueInter(dd, nv, one, zero); 00317 } while (dd->reordered == 1); 00318 if (lx[i] == NULL) return(0); 00319 cuddRef(lx[i]); 00320 do { 00321 dd->reordered = 0; 00322 lxn[i] = cuddUniqueInter(dd, nv, zero, one); 00323 } while (dd->reordered == 1); 00324 if (lxn[i] == NULL) return(0); 00325 cuddRef(lxn[i]); 00326 } 00327 for (i= *ny,nv=by+(*ny)*sy; i < lny; i++,nv+=sy) { 00328 do { 00329 dd->reordered = 0; 00330 ly[i] = cuddUniqueInter(dd, nv, one, zero); 00331 } while (dd->reordered == 1); 00332 if (ly[i] == NULL) return(0); 00333 cuddRef(ly[i]); 00334 do { 00335 dd->reordered = 0; 00336 lyn[i] = cuddUniqueInter(dd, nv, zero, one); 00337 } while (dd->reordered == 1); 00338 if (lyn[i] == NULL) return(0); 00339 cuddRef(lyn[i]); 00340 } 00341 00342 /* Update matrix parameters */ 00343 *nx = lnx; 00344 *ny = lny; 00345 *m = nrow; 00346 if (nrhs == 0) { 00347 *n = ncol; 00348 } else { 00349 *n = (1 << (lny - 1)) + nrhs; 00350 } 00351 00352 /* Read structure data */ 00353 colptr = ALLOC(int, ncol+1); 00354 if (colptr == NULL) { 00355 dd->errorCode = CUDD_MEMORY_OUT; 00356 return(0); 00357 } 00358 rowind = ALLOC(int, nnzero); 00359 if (rowind == NULL) { 00360 dd->errorCode = CUDD_MEMORY_OUT; 00361 return(0); 00362 } 00363 00364 for (i=0; i<ncol+1; i++) { 00365 err = fscanf(fp, " %d ", &u); 00366 if (err == EOF){ 00367 FREE(colptr); 00368 FREE(rowind); 00369 return(0); 00370 } else if (err != 1) { 00371 FREE(colptr); 00372 FREE(rowind); 00373 return(0); 00374 } 00375 colptr[i] = u - 1; 00376 } 00377 if (colptr[0] != 0) { 00378 (void) fprintf(dd->err,"%s: Unexpected colptr[0] (%d)\n", 00379 key,colptr[0]); 00380 FREE(colptr); 00381 FREE(rowind); 00382 return(0); 00383 } 00384 for (i=0; i<nnzero; i++) { 00385 err = fscanf(fp, " %d ", &u); 00386 if (err == EOF){ 00387 FREE(colptr); 00388 FREE(rowind); 00389 return(0); 00390 } else if (err != 1) { 00391 FREE(colptr); 00392 FREE(rowind); 00393 return(0); 00394 } 00395 rowind[i] = u - 1; 00396 } 00397 00398 *E = zero; cuddRef(*E); 00399 00400 for (j=0; j<ncol; j++) { 00401 v = j; 00402 cubey = one; cuddRef(cubey); 00403 for (nv = lny - 1; nv>=0; nv--) { 00404 if (v & 1) { 00405 w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); 00406 } else { 00407 w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); 00408 } 00409 if (w == NULL) { 00410 Cudd_RecursiveDeref(dd, cubey); 00411 FREE(colptr); 00412 FREE(rowind); 00413 return(0); 00414 } 00415 cuddRef(w); 00416 Cudd_RecursiveDeref(dd, cubey); 00417 cubey = w; 00418 v >>= 1; 00419 } 00420 for (i=colptr[j]; i<colptr[j+1]; i++) { 00421 u = rowind[i]; 00422 err = fscanf(fp, " %lf ", &val); 00423 if (err == EOF || err != 1){ 00424 Cudd_RecursiveDeref(dd, cubey); 00425 FREE(colptr); 00426 FREE(rowind); 00427 return(0); 00428 } 00429 /* Create new Constant node if necessary */ 00430 cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val); 00431 if (cubex == NULL) { 00432 Cudd_RecursiveDeref(dd, cubey); 00433 FREE(colptr); 00434 FREE(rowind); 00435 return(0); 00436 } 00437 cuddRef(cubex); 00438 00439 for (nv = lnx - 1; nv>=0; nv--) { 00440 if (u & 1) { 00441 w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); 00442 } else { 00443 w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); 00444 } 00445 if (w == NULL) { 00446 Cudd_RecursiveDeref(dd, cubey); 00447 Cudd_RecursiveDeref(dd, cubex); 00448 FREE(colptr); 00449 FREE(rowind); 00450 return(0); 00451 } 00452 cuddRef(w); 00453 Cudd_RecursiveDeref(dd, cubex); 00454 cubex = w; 00455 u >>= 1; 00456 } 00457 minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); 00458 if (minterm1 == NULL) { 00459 Cudd_RecursiveDeref(dd, cubey); 00460 Cudd_RecursiveDeref(dd, cubex); 00461 FREE(colptr); 00462 FREE(rowind); 00463 return(0); 00464 } 00465 cuddRef(minterm1); 00466 Cudd_RecursiveDeref(dd, cubex); 00467 w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); 00468 if (w == NULL) { 00469 Cudd_RecursiveDeref(dd, cubey); 00470 FREE(colptr); 00471 FREE(rowind); 00472 return(0); 00473 } 00474 cuddRef(w); 00475 Cudd_RecursiveDeref(dd, minterm1); 00476 Cudd_RecursiveDeref(dd, *E); 00477 *E = w; 00478 } 00479 Cudd_RecursiveDeref(dd, cubey); 00480 } 00481 FREE(colptr); 00482 FREE(rowind); 00483 00484 /* Read right-hand sides */ 00485 for (j=0; j<nrhs; j++) { 00486 v = j + (1<< (lny-1)); 00487 cubey = one; cuddRef(cubey); 00488 for (nv = lny - 1; nv>=0; nv--) { 00489 if (v & 1) { 00490 w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); 00491 } else { 00492 w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); 00493 } 00494 if (w == NULL) { 00495 Cudd_RecursiveDeref(dd, cubey); 00496 return(0); 00497 } 00498 cuddRef(w); 00499 Cudd_RecursiveDeref(dd, cubey); 00500 cubey = w; 00501 v >>= 1; 00502 } 00503 for (i=0; i<nrow; i++) { 00504 u = i; 00505 err = fscanf(fp, " %lf ", &val); 00506 if (err == EOF || err != 1){ 00507 Cudd_RecursiveDeref(dd, cubey); 00508 return(0); 00509 } 00510 /* Create new Constant node if necessary */ 00511 if (val == (double) 0.0) continue; 00512 cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val); 00513 if (cubex == NULL) { 00514 Cudd_RecursiveDeref(dd, cubey); 00515 return(0); 00516 } 00517 cuddRef(cubex); 00518 00519 for (nv = lnx - 1; nv>=0; nv--) { 00520 if (u & 1) { 00521 w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); 00522 } else { 00523 w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); 00524 } 00525 if (w == NULL) { 00526 Cudd_RecursiveDeref(dd, cubey); 00527 Cudd_RecursiveDeref(dd, cubex); 00528 return(0); 00529 } 00530 cuddRef(w); 00531 Cudd_RecursiveDeref(dd, cubex); 00532 cubex = w; 00533 u >>= 1; 00534 } 00535 minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); 00536 if (minterm1 == NULL) { 00537 Cudd_RecursiveDeref(dd, cubey); 00538 Cudd_RecursiveDeref(dd, cubex); 00539 return(0); 00540 } 00541 cuddRef(minterm1); 00542 Cudd_RecursiveDeref(dd, cubex); 00543 w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); 00544 if (w == NULL) { 00545 Cudd_RecursiveDeref(dd, cubey); 00546 return(0); 00547 } 00548 cuddRef(w); 00549 Cudd_RecursiveDeref(dd, minterm1); 00550 Cudd_RecursiveDeref(dd, *E); 00551 *E = w; 00552 } 00553 Cudd_RecursiveDeref(dd, cubey); 00554 } 00555 00556 return(1); 00557 00558 } /* end of Cudd_addHarwell */
int Cudd_AddHook | ( | DdManager * | dd, | |
DD_HFP | f, | |||
Cudd_HookType | where | |||
) |
Function********************************************************************
Synopsis [Adds a function to a hook.]
Description [Adds a function to a hook. A hook is a list of application-provided functions called on certain occasions by the package. Returns 1 if the function is successfully added; 2 if the function was already in the list; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_RemoveHook]
Definition at line 3241 of file cuddAPI.c.
03245 { 03246 DdHook **hook, *nextHook, *newHook; 03247 03248 switch (where) { 03249 case CUDD_PRE_GC_HOOK: 03250 hook = &(dd->preGCHook); 03251 break; 03252 case CUDD_POST_GC_HOOK: 03253 hook = &(dd->postGCHook); 03254 break; 03255 case CUDD_PRE_REORDERING_HOOK: 03256 hook = &(dd->preReorderingHook); 03257 break; 03258 case CUDD_POST_REORDERING_HOOK: 03259 hook = &(dd->postReorderingHook); 03260 break; 03261 default: 03262 return(0); 03263 } 03264 /* Scan the list and find whether the function is already there. 03265 ** If so, just return. */ 03266 nextHook = *hook; 03267 while (nextHook != NULL) { 03268 if (nextHook->f == f) { 03269 return(2); 03270 } 03271 hook = &(nextHook->next); 03272 nextHook = nextHook->next; 03273 } 03274 /* The function was not in the list. Create a new item and append it 03275 ** to the end of the list. */ 03276 newHook = ALLOC(DdHook,1); 03277 if (newHook == NULL) { 03278 dd->errorCode = CUDD_MEMORY_OUT; 03279 return(0); 03280 } 03281 newHook->next = NULL; 03282 newHook->f = f; 03283 *hook = newHook; 03284 return(1); 03285 03286 } /* end of Cudd_AddHook */
AutomaticEnd Function********************************************************************
Synopsis [Implements ITE(f,g,h).]
Description [Implements ITE(f,g,h). This procedure assumes that f is a 0-1 ADD. Returns a pointer to the resulting ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addIteConstant Cudd_addApply]
Definition at line 125 of file cuddAddIte.c.
00130 { 00131 DdNode *res; 00132 00133 do { 00134 dd->reordered = 0; 00135 res = cuddAddIteRecur(dd,f,g,h); 00136 } while (dd->reordered == 1); 00137 return(res); 00138 00139 } /* end of Cudd_addIte */
Function********************************************************************
Synopsis [Implements ITEconstant for ADDs.]
Description [Implements ITEconstant for ADDs. f must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may or may not be constant) or DD_NON_CONSTANT. No new nodes are created. This function can be used, for instance, to check that g has a constant value (specified by h) whenever f is 1. If the constant value is unknown, then one should use Cudd_addEvalConst.]
SideEffects [None]
SeeAlso [Cudd_addIte Cudd_addEvalConst Cudd_bddIteConstant]
Definition at line 159 of file cuddAddIte.c.
00164 { 00165 DdNode *one,*zero; 00166 DdNode *Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*r,*t,*e; 00167 unsigned int topf,topg,toph,v; 00168 00169 statLine(dd); 00170 /* Trivial cases. */ 00171 if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ 00172 return(g); 00173 } 00174 if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ 00175 return(h); 00176 } 00177 00178 /* From now on, f is known not to be a constant. */ 00179 addVarToConst(f,&g,&h,one,zero); 00180 00181 /* Check remaining one variable cases. */ 00182 if (g == h) { /* ITE(F,G,G) = G */ 00183 return(g); 00184 } 00185 if (cuddIsConstant(g) && cuddIsConstant(h)) { 00186 return(DD_NON_CONSTANT); 00187 } 00188 00189 topf = cuddI(dd,f->index); 00190 topg = cuddI(dd,g->index); 00191 toph = cuddI(dd,h->index); 00192 v = ddMin(topg,toph); 00193 00194 /* ITE(F,G,H) = (x,G,H) (non constant) if F = (x,1,0), x < top(G,H). */ 00195 if (topf < v && cuddIsConstant(cuddT(f)) && cuddIsConstant(cuddE(f))) { 00196 return(DD_NON_CONSTANT); 00197 } 00198 00199 /* Check cache. */ 00200 r = cuddConstantLookup(dd,DD_ADD_ITE_CONSTANT_TAG,f,g,h); 00201 if (r != NULL) { 00202 return(r); 00203 } 00204 00205 /* Compute cofactors. */ 00206 if (topf <= v) { 00207 v = ddMin(topf,v); /* v = top_var(F,G,H) */ 00208 Fv = cuddT(f); Fnv = cuddE(f); 00209 } else { 00210 Fv = Fnv = f; 00211 } 00212 if (topg == v) { 00213 Gv = cuddT(g); Gnv = cuddE(g); 00214 } else { 00215 Gv = Gnv = g; 00216 } 00217 if (toph == v) { 00218 Hv = cuddT(h); Hnv = cuddE(h); 00219 } else { 00220 Hv = Hnv = h; 00221 } 00222 00223 /* Recursive step. */ 00224 t = Cudd_addIteConstant(dd,Fv,Gv,Hv); 00225 if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { 00226 cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); 00227 return(DD_NON_CONSTANT); 00228 } 00229 e = Cudd_addIteConstant(dd,Fnv,Gnv,Hnv); 00230 if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { 00231 cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); 00232 return(DD_NON_CONSTANT); 00233 } 00234 cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, t); 00235 return(t); 00236 00237 } /* end of Cudd_addIteConstant */
Function********************************************************************
Synopsis [Extracts the i-th bit from an ADD.]
Description [Produces an ADD from another ADD by replacing all discriminants whose i-th bit is equal to 1 with 1, and all other discriminants with 0. The i-th bit refers to the integer representation of the leaf value. If the value is has a fractional part, it is ignored. Repeated calls to this procedure allow one to transform an integer-valued ADD into an array of ADDs, one for each bit of the leaf values. Returns a pointer to the resulting ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addBddIthBit]
Definition at line 209 of file cuddAddFind.c.
00213 { 00214 DdNode *res; 00215 DdNode *index; 00216 00217 /* Use a constant node to remember the bit, so that we can use the 00218 ** global cache. 00219 */ 00220 index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit); 00221 if (index == NULL) return(NULL); 00222 cuddRef(index); 00223 00224 do { 00225 dd->reordered = 0; 00226 res = addDoIthBit(dd, f, index); 00227 } while (dd->reordered == 1); 00228 00229 if (res == NULL) { 00230 Cudd_RecursiveDeref(dd, index); 00231 return(NULL); 00232 } 00233 cuddRef(res); 00234 Cudd_RecursiveDeref(dd, index); 00235 cuddDeref(res); 00236 return(res); 00237 00238 } /* end of Cudd_addIthBit */
Function********************************************************************
Synopsis [Returns the ADD variable with index i.]
Description [Retrieves the ADD variable with index i if it already exists, or creates a new ADD variable. Returns a pointer to the variable if successful; NULL otherwise. An ADD variable differs from a BDD variable because it points to the arithmetic zero, instead of having a complement pointer to 1. ]
SideEffects [None]
SeeAlso [Cudd_addNewVar Cudd_bddIthVar Cudd_addConst Cudd_addNewVarAtLevel]
Definition at line 380 of file cuddAPI.c.
00383 { 00384 DdNode *res; 00385 00386 if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); 00387 do { 00388 dd->reordered = 0; 00389 res = cuddUniqueInter(dd,i,DD_ONE(dd),DD_ZERO(dd)); 00390 } while (dd->reordered == 1); 00391 00392 return(res); 00393 00394 } /* end of Cudd_addIthVar */
Function********************************************************************
Synopsis [Determines whether f is less than or equal to g.]
Description [Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are created. This procedure works for arbitrary ADDs. For 0-1 ADDs Cudd_addEvalConst is more efficient.]
SideEffects [None]
SeeAlso [Cudd_addIteConstant Cudd_addEvalConst Cudd_bddLeq]
Definition at line 372 of file cuddAddIte.c.
00376 { 00377 DdNode *tmp, *fv, *fvn, *gv, *gvn; 00378 unsigned int topf, topg, res; 00379 00380 /* Terminal cases. */ 00381 if (f == g) return(1); 00382 00383 statLine(dd); 00384 if (cuddIsConstant(f)) { 00385 if (cuddIsConstant(g)) return(cuddV(f) <= cuddV(g)); 00386 if (f == DD_MINUS_INFINITY(dd)) return(1); 00387 if (f == DD_PLUS_INFINITY(dd)) return(0); /* since f != g */ 00388 } 00389 if (g == DD_PLUS_INFINITY(dd)) return(1); 00390 if (g == DD_MINUS_INFINITY(dd)) return(0); /* since f != g */ 00391 00392 /* Check cache. */ 00393 tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g); 00394 if (tmp != NULL) { 00395 return(tmp == DD_ONE(dd)); 00396 } 00397 00398 /* Compute cofactors. One of f and g is not constant. */ 00399 topf = cuddI(dd,f->index); 00400 topg = cuddI(dd,g->index); 00401 if (topf <= topg) { 00402 fv = cuddT(f); fvn = cuddE(f); 00403 } else { 00404 fv = fvn = f; 00405 } 00406 if (topg <= topf) { 00407 gv = cuddT(g); gvn = cuddE(g); 00408 } else { 00409 gv = gvn = g; 00410 } 00411 00412 res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv); 00413 00414 /* Store result in cache and return. */ 00415 cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq,f,g, 00416 Cudd_NotCond(DD_ONE(dd),res==0)); 00417 return(res); 00418 00419 } /* end of Cudd_addLeq */
Function********************************************************************
Synopsis [Natural logarithm of an ADD.]
Description [Natural logarithm of an ADDs. Returns NULL if not a terminal case; log(f) otherwise. The discriminants of f must be positive double's.]
SideEffects [None]
SeeAlso [Cudd_addMonadicApply]
Definition at line 773 of file cuddAddApply.c.
00776 { 00777 if (cuddIsConstant(f)) { 00778 CUDD_VALUE_TYPE value = log(cuddV(f)); 00779 DdNode *res = cuddUniqueConst(dd,value); 00780 return(res); 00781 } 00782 return(NULL); 00783 00784 } /* end of Cudd_addLog */
AutomaticEnd Function********************************************************************
Synopsis [Calculates the product of two matrices represented as ADDs.]
Description [Calculates the product of two matrices, A and B, represented as ADDs. This procedure implements the quasiring multiplication algorithm. A is assumed to depend on variables x (rows) and z (columns). B is assumed to depend on variables z (rows) and y (columns). The product of A and B then depends on x (rows) and y (columns). Only the z variables have to be explicitly identified; they are the "summation" variables. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addTimesPlus Cudd_addTriangle Cudd_bddAndAbstract]
Definition at line 128 of file cuddMatMult.c.
00134 { 00135 int i, nvars, *vars; 00136 DdNode *res; 00137 00138 /* Array vars says what variables are "summation" variables. */ 00139 nvars = dd->size; 00140 vars = ALLOC(int,nvars); 00141 if (vars == NULL) { 00142 dd->errorCode = CUDD_MEMORY_OUT; 00143 return(NULL); 00144 } 00145 for (i = 0; i < nvars; i++) { 00146 vars[i] = 0; 00147 } 00148 for (i = 0; i < nz; i++) { 00149 vars[z[i]->index] = 1; 00150 } 00151 00152 do { 00153 dd->reordered = 0; 00154 res = addMMRecur(dd,A,B,-1,vars); 00155 } while (dd->reordered == 1); 00156 FREE(vars); 00157 return(res); 00158 00159 } /* end of Cudd_addMatrixMultiply */
Function********************************************************************
Synopsis [Integer and floating point max.]
Description [Integer and floating point max for Cudd_addApply. Returns NULL if not a terminal case; max(f,g) otherwise.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 426 of file cuddAddApply.c.
00430 { 00431 DdNode *F, *G; 00432 00433 F = *f; G = *g; 00434 if (F == G) return(F); 00435 if (F == DD_MINUS_INFINITY(dd)) return(G); 00436 if (G == DD_MINUS_INFINITY(dd)) return(F); 00437 #if 0 00438 /* These special cases probably do not pay off. */ 00439 if (F == DD_PLUS_INFINITY(dd)) return(F); 00440 if (G == DD_PLUS_INFINITY(dd)) return(G); 00441 #endif 00442 if (cuddIsConstant(F) && cuddIsConstant(G)) { 00443 if (cuddV(F) >= cuddV(G)) { 00444 return(F); 00445 } else { 00446 return(G); 00447 } 00448 } 00449 if (F > G) { /* swap f and g */ 00450 *f = G; 00451 *g = F; 00452 } 00453 return(NULL); 00454 00455 } /* end of Cudd_addMaximum */
Function********************************************************************
Synopsis [Integer and floating point min.]
Description [Integer and floating point min for Cudd_addApply. Returns NULL if not a terminal case; min(f,g) otherwise.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 381 of file cuddAddApply.c.
00385 { 00386 DdNode *F, *G; 00387 00388 F = *f; G = *g; 00389 if (F == DD_PLUS_INFINITY(dd)) return(G); 00390 if (G == DD_PLUS_INFINITY(dd)) return(F); 00391 if (F == G) return(F); 00392 #if 0 00393 /* These special cases probably do not pay off. */ 00394 if (F == DD_MINUS_INFINITY(dd)) return(F); 00395 if (G == DD_MINUS_INFINITY(dd)) return(G); 00396 #endif 00397 if (cuddIsConstant(F) && cuddIsConstant(G)) { 00398 if (cuddV(F) <= cuddV(G)) { 00399 return(F); 00400 } else { 00401 return(G); 00402 } 00403 } 00404 if (F > G) { /* swap f and g */ 00405 *f = G; 00406 *g = F; 00407 } 00408 return(NULL); 00409 00410 } /* end of Cudd_addMinimum */
Function********************************************************************
Synopsis [Integer and floating point subtraction.]
Description [Integer and floating point subtraction. Returns NULL if not a terminal case; f - g otherwise.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 345 of file cuddAddApply.c.
00349 { 00350 DdNode *res; 00351 DdNode *F, *G; 00352 CUDD_VALUE_TYPE value; 00353 00354 F = *f; G = *g; 00355 if (F == G) return(DD_ZERO(dd)); 00356 if (F == DD_ZERO(dd)) return(cuddAddNegateRecur(dd,G)); 00357 if (G == DD_ZERO(dd)) return(F); 00358 if (cuddIsConstant(F) && cuddIsConstant(G)) { 00359 value = cuddV(F)-cuddV(G); 00360 res = cuddUniqueConst(dd,value); 00361 return(res); 00362 } 00363 return(NULL); 00364 00365 } /* end of Cudd_addMinus */
Function********************************************************************
Synopsis [NAND of two 0-1 ADDs.]
Description [NAND of two 0-1 ADDs. Returns NULL if not a terminal case; f NAND g otherwise.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 611 of file cuddAddApply.c.
00615 { 00616 DdNode *F, *G; 00617 00618 F = *f; G = *g; 00619 if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ONE(dd)); 00620 if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); 00621 if (F > G) { /* swap f and g */ 00622 *f = G; 00623 *g = F; 00624 } 00625 return(NULL); 00626 00627 } /* end of Cudd_addNand */
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Computes the additive inverse of an ADD.]
Description [Computes the additive inverse of an ADD. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addCmpl]
Definition at line 116 of file cuddAddNeg.c.
00119 { 00120 DdNode *res; 00121 00122 do { 00123 res = cuddAddNegateRecur(dd,f); 00124 } while (dd->reordered == 1); 00125 return(res); 00126 00127 } /* end of Cudd_addNegate */
AutomaticStart
AutomaticEnd Function********************************************************************
Synopsis [Returns a new ADD variable.]
Description [Creates a new ADD variable. The new variable has an index equal to the largest previous index plus 1. Returns a pointer to the new variable if successful; NULL otherwise. An ADD variable differs from a BDD variable because it points to the arithmetic zero, instead of having a complement pointer to 1. ]
SideEffects [None]
SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_addConst Cudd_addNewVarAtLevel]
Definition at line 255 of file cuddAPI.c.
00257 { 00258 DdNode *res; 00259 00260 if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); 00261 do { 00262 dd->reordered = 0; 00263 res = cuddUniqueInter(dd,dd->size,DD_ONE(dd),DD_ZERO(dd)); 00264 } while (dd->reordered == 1); 00265 00266 return(res); 00267 00268 } /* end of Cudd_addNewVar */
Function********************************************************************
Synopsis [Returns a new ADD variable at a specified level.]
Description [Creates a new ADD variable. The new variable has an index equal to the largest previous index plus 1 and is positioned at the specified level in the order. Returns a pointer to the new variable if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel]
Definition at line 286 of file cuddAPI.c.
00289 { 00290 DdNode *res; 00291 00292 if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); 00293 if (level >= dd->size) return(Cudd_addIthVar(dd,level)); 00294 if (!cuddInsertSubtables(dd,1,level)) return(NULL); 00295 do { 00296 dd->reordered = 0; 00297 res = cuddUniqueInter(dd,dd->size - 1,DD_ONE(dd),DD_ZERO(dd)); 00298 } while (dd->reordered == 1); 00299 00300 return(res); 00301 00302 } /* end of Cudd_addNewVarAtLevel */
Function********************************************************************
Synopsis [Composes an ADD with a vector of 0-1 ADDs.]
Description [Given a vector of 0-1 ADDs, creates a new ADD by substituting the 0-1 ADDs for the variables of the ADD f. There should be an entry in vector for each variable in the manager. This function implements non-simultaneous composition. If any of the functions being composed depends on any of the variables being substituted, then the result depends on the order of composition, which in turn depends on the variable order: The variables farther from the roots in the order are substituted first. Returns a pointer to the resulting ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addVectorCompose Cudd_addPermute Cudd_addCompose]
Definition at line 678 of file cuddCompose.c.
00682 { 00683 DdNode *cube, *key, *var, *tmp, *piece; 00684 DdNode *res; 00685 int i, lastsub; 00686 00687 /* The cache entry for this function is composed of three parts: 00688 ** f itself, the replacement relation, and the cube of the 00689 ** variables being substituted. 00690 ** The replacement relation is the product of the terms (yi EXNOR gi). 00691 ** This apporach allows us to use the global cache for this function, 00692 ** with great savings in memory with respect to using arrays for the 00693 ** cache entries. 00694 ** First we build replacement relation and cube of substituted 00695 ** variables from the vector specifying the desired composition. 00696 */ 00697 key = DD_ONE(dd); 00698 cuddRef(key); 00699 cube = DD_ONE(dd); 00700 cuddRef(cube); 00701 for (i = (int) dd->size - 1; i >= 0; i--) { 00702 if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) { 00703 continue; 00704 } 00705 var = Cudd_addIthVar(dd,i); 00706 if (var == NULL) { 00707 Cudd_RecursiveDeref(dd,key); 00708 Cudd_RecursiveDeref(dd,cube); 00709 return(NULL); 00710 } 00711 cuddRef(var); 00712 /* Update cube. */ 00713 tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube); 00714 if (tmp == NULL) { 00715 Cudd_RecursiveDeref(dd,key); 00716 Cudd_RecursiveDeref(dd,cube); 00717 Cudd_RecursiveDeref(dd,var); 00718 return(NULL); 00719 } 00720 cuddRef(tmp); 00721 Cudd_RecursiveDeref(dd,cube); 00722 cube = tmp; 00723 /* Update replacement relation. */ 00724 piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]); 00725 if (piece == NULL) { 00726 Cudd_RecursiveDeref(dd,key); 00727 Cudd_RecursiveDeref(dd,var); 00728 return(NULL); 00729 } 00730 cuddRef(piece); 00731 Cudd_RecursiveDeref(dd,var); 00732 tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece); 00733 if (tmp == NULL) { 00734 Cudd_RecursiveDeref(dd,key); 00735 Cudd_RecursiveDeref(dd,piece); 00736 return(NULL); 00737 } 00738 cuddRef(tmp); 00739 Cudd_RecursiveDeref(dd,key); 00740 Cudd_RecursiveDeref(dd,piece); 00741 key = tmp; 00742 } 00743 00744 /* Now try composition, until no reordering occurs. */ 00745 do { 00746 /* Find real substitution with largest index. */ 00747 for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) { 00748 if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) { 00749 break; 00750 } 00751 } 00752 00753 /* Recursively solve the problem. */ 00754 dd->reordered = 0; 00755 res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1); 00756 if (res != NULL) cuddRef(res); 00757 00758 } while (dd->reordered == 1); 00759 00760 Cudd_RecursiveDeref(dd,key); 00761 Cudd_RecursiveDeref(dd,cube); 00762 if (res != NULL) cuddDeref(res); 00763 return(res); 00764 00765 } /* end of Cudd_addNonSimCompose */
Function********************************************************************
Synopsis [NOR of two 0-1 ADDs.]
Description [NOR of two 0-1 ADDs. Returns NULL if not a terminal case; f NOR g otherwise.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 643 of file cuddAddApply.c.
00647 { 00648 DdNode *F, *G; 00649 00650 F = *f; G = *g; 00651 if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ZERO(dd)); 00652 if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ONE(dd)); 00653 if (F > G) { /* swap f and g */ 00654 *f = G; 00655 *g = F; 00656 } 00657 return(NULL); 00658 00659 } /* end of Cudd_addNor */
Function********************************************************************
Synopsis [Returns 1 if f > g and 0 otherwise.]
Description [Returns 1 if f > g and 0 otherwise. Used in conjunction with Cudd_addApply. Returns NULL if not a terminal case.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 472 of file cuddAddApply.c.
00476 { 00477 00478 if (*f == *g) return(DD_ZERO(dd)); 00479 if (*g == DD_PLUS_INFINITY(dd)) 00480 return DD_ZERO(dd); 00481 if (cuddIsConstant(*f) && cuddIsConstant(*g)) { 00482 if (cuddV(*f) > cuddV(*g)) { 00483 return(DD_ONE(dd)); 00484 } else { 00485 return(DD_ZERO(dd)); 00486 } 00487 } 00488 00489 return(NULL); 00490 00491 } /* end of Cudd_addOneZeroMaximum */
Function********************************************************************
Synopsis [Disjunction of two 0-1 ADDs.]
Description [Disjunction of two 0-1 ADDs. Returns NULL if not a terminal case; f OR g otherwise.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 577 of file cuddAddApply.c.
00581 { 00582 DdNode *F, *G; 00583 00584 F = *f; G = *g; 00585 if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ONE(dd)); 00586 if (cuddIsConstant(F)) return(G); 00587 if (cuddIsConstant(G)) return(F); 00588 if (F == G) return(F); 00589 if (F > G) { /* swap f and g */ 00590 *f = G; 00591 *g = F; 00592 } 00593 return(NULL); 00594 00595 } /* end of Cudd_addOr */
Function********************************************************************
Synopsis [Disjunctively abstracts all the variables in cube from the 0-1 ADD f.]
Description [Abstracts all the variables in cube from the 0-1 ADD f by taking the disjunction over all possible values taken by the variables. Returns the abstracted ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addUnivAbstract Cudd_addExistAbstract]
Definition at line 212 of file cuddAddAbs.c.
00216 { 00217 DdNode *res; 00218 00219 if (addCheckPositiveCube(manager, cube) == 0) { 00220 (void) fprintf(manager->err,"Error: Can only abstract cubes"); 00221 return(NULL); 00222 } 00223 00224 do { 00225 manager->reordered = 0; 00226 res = cuddAddOrAbstractRecur(manager, f, cube); 00227 } while (manager->reordered == 1); 00228 return(res); 00229 00230 } /* end of Cudd_addOrAbstract */
Function********************************************************************
Synopsis [Takes the minimum of a matrix and the outer sum of two vectors.]
Description [Takes the pointwise minimum of a matrix and the outer sum of two vectors. This procedure is used in the Floyd-Warshall all-pair shortest path algorithm. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 292 of file cuddMatMult.c.
00297 { 00298 DdNode *res; 00299 00300 do { 00301 dd->reordered = 0; 00302 res = cuddAddOuterSumRecur(dd, M, r, c); 00303 } while (dd->reordered == 1); 00304 return(res); 00305 00306 } /* end of Cudd_addOuterSum */
Function********************************************************************
Synopsis [Permutes the variables of an ADD.]
Description [Given a permutation in array permut, creates a new ADD with permuted variables. There should be an entry in array permut for each variable in the manager. The i-th entry of permut holds the index of the variable that is to substitute the i-th variable. Returns a pointer to the resulting ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddPermute Cudd_addSwapVariables]
Definition at line 238 of file cuddCompose.c.
00242 { 00243 DdHashTable *table; 00244 DdNode *res; 00245 00246 do { 00247 manager->reordered = 0; 00248 table = cuddHashTableInit(manager,1,2); 00249 if (table == NULL) return(NULL); 00250 /* Recursively solve the problem. */ 00251 res = cuddAddPermuteRecur(manager,table,node,permut); 00252 if (res != NULL) cuddRef(res); 00253 /* Dispose of local cache. */ 00254 cuddHashTableQuit(table); 00255 } while (manager->reordered == 1); 00256 00257 if (res != NULL) cuddDeref(res); 00258 return(res); 00259 00260 } /* end of Cudd_addPermute */
Function********************************************************************
Synopsis [Integer and floating point addition.]
Description [Integer and floating point addition. Returns NULL if not a terminal case; f+g otherwise.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 164 of file cuddAddApply.c.
00168 { 00169 DdNode *res; 00170 DdNode *F, *G; 00171 CUDD_VALUE_TYPE value; 00172 00173 F = *f; G = *g; 00174 if (F == DD_ZERO(dd)) return(G); 00175 if (G == DD_ZERO(dd)) return(F); 00176 if (cuddIsConstant(F) && cuddIsConstant(G)) { 00177 value = cuddV(F)+cuddV(G); 00178 res = cuddUniqueConst(dd,value); 00179 return(res); 00180 } 00181 if (F > G) { /* swap f and g */ 00182 *f = G; 00183 *g = F; 00184 } 00185 return(NULL); 00186 00187 } /* end of Cudd_addPlus */
int Cudd_addRead | ( | FILE * | fp, | |
DdManager * | dd, | |||
DdNode ** | E, | |||
DdNode *** | x, | |||
DdNode *** | y, | |||
DdNode *** | xn, | |||
DdNode *** | yn_, | |||
int * | nx, | |||
int * | ny, | |||
int * | m, | |||
int * | n, | |||
int | bx, | |||
int | sx, | |||
int | by, | |||
int | sy | |||
) |
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Reads in a sparse matrix.]
Description [Reads in a sparse matrix specified in a simple format. The first line of the input contains the numbers of rows and columns. The remaining lines contain the elements of the matrix, one per line. Given a background value (specified by the background field of the manager), only the values different from it are explicitly listed. Each foreground element is described by two integers, i.e., the row and column number, and a real number, i.e., the value.
Cudd_addRead produces an ADD that depends on two sets of variables: x and y. The x variables (x\[0\] ... x\[nx-1\]) encode the row index and the y variables (y\[0\] ... y\[ny-1\]) encode the column index. x\[0\] and y\[0\] are the most significant bits in the indices. The variables may already exist or may be created by the function. The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.
On input, nx and ny hold the numbers of row and column variables already in existence. On output, they hold the numbers of row and column variables actually used by the matrix. When Cudd_addRead creates the variable arrays, the index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy. When some variables already exist Cudd_addRead expects the indices of the existing x variables to be bx+i*sx, and the indices of the existing y variables to be by+i*sy.
m and n are set to the numbers of rows and columns of the matrix. Their values on input are immaterial. The ADD for the sparse matrix is returned in E, and its reference count is > 0. Cudd_addRead returns 1 in case of success; 0 otherwise.]
SideEffects [nx and ny are set to the numbers of row and column variables. m and n are set to the numbers of rows and columns. x and y are possibly extended to represent the array of row and column variables. Similarly for xn and yn_, which hold on return from Cudd_addRead the complements of the row and column variables.]
SeeAlso [Cudd_addHarwell Cudd_bddRead]
Definition at line 142 of file cuddRead.c.
00158 { 00159 DdNode *one, *zero; 00160 DdNode *w, *neW; 00161 DdNode *minterm1; 00162 int u, v, err, i, nv; 00163 int lnx, lny; 00164 CUDD_VALUE_TYPE val; 00165 DdNode **lx, **ly, **lxn, **lyn; 00166 00167 one = DD_ONE(dd); 00168 zero = DD_ZERO(dd); 00169 00170 err = fscanf(fp, "%d %d", &u, &v); 00171 if (err == EOF) { 00172 return(0); 00173 } else if (err != 2) { 00174 return(0); 00175 } 00176 00177 *m = u; 00178 /* Compute the number of x variables. */ 00179 lx = *x; lxn = *xn; 00180 u--; /* row and column numbers start from 0 */ 00181 for (lnx=0; u > 0; lnx++) { 00182 u >>= 1; 00183 } 00184 /* Here we rely on the fact that REALLOC of a null pointer is 00185 ** translates to an ALLOC. 00186 */ 00187 if (lnx > *nx) { 00188 *x = lx = REALLOC(DdNode *, *x, lnx); 00189 if (lx == NULL) { 00190 dd->errorCode = CUDD_MEMORY_OUT; 00191 return(0); 00192 } 00193 *xn = lxn = REALLOC(DdNode *, *xn, lnx); 00194 if (lxn == NULL) { 00195 dd->errorCode = CUDD_MEMORY_OUT; 00196 return(0); 00197 } 00198 } 00199 00200 *n = v; 00201 /* Compute the number of y variables. */ 00202 ly = *y; lyn = *yn_; 00203 v--; /* row and column numbers start from 0 */ 00204 for (lny=0; v > 0; lny++) { 00205 v >>= 1; 00206 } 00207 /* Here we rely on the fact that REALLOC of a null pointer is 00208 ** translates to an ALLOC. 00209 */ 00210 if (lny > *ny) { 00211 *y = ly = REALLOC(DdNode *, *y, lny); 00212 if (ly == NULL) { 00213 dd->errorCode = CUDD_MEMORY_OUT; 00214 return(0); 00215 } 00216 *yn_ = lyn = REALLOC(DdNode *, *yn_, lny); 00217 if (lyn == NULL) { 00218 dd->errorCode = CUDD_MEMORY_OUT; 00219 return(0); 00220 } 00221 } 00222 00223 /* Create all new variables. */ 00224 for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) { 00225 do { 00226 dd->reordered = 0; 00227 lx[i] = cuddUniqueInter(dd, nv, one, zero); 00228 } while (dd->reordered == 1); 00229 if (lx[i] == NULL) return(0); 00230 cuddRef(lx[i]); 00231 do { 00232 dd->reordered = 0; 00233 lxn[i] = cuddUniqueInter(dd, nv, zero, one); 00234 } while (dd->reordered == 1); 00235 if (lxn[i] == NULL) return(0); 00236 cuddRef(lxn[i]); 00237 } 00238 for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) { 00239 do { 00240 dd->reordered = 0; 00241 ly[i] = cuddUniqueInter(dd, nv, one, zero); 00242 } while (dd->reordered == 1); 00243 if (ly[i] == NULL) return(0); 00244 cuddRef(ly[i]); 00245 do { 00246 dd->reordered = 0; 00247 lyn[i] = cuddUniqueInter(dd, nv, zero, one); 00248 } while (dd->reordered == 1); 00249 if (lyn[i] == NULL) return(0); 00250 cuddRef(lyn[i]); 00251 } 00252 *nx = lnx; 00253 *ny = lny; 00254 00255 *E = dd->background; /* this call will never cause reordering */ 00256 cuddRef(*E); 00257 00258 while (! feof(fp)) { 00259 err = fscanf(fp, "%d %d %lf", &u, &v, &val); 00260 if (err == EOF) { 00261 break; 00262 } else if (err != 3) { 00263 return(0); 00264 } else if (u >= *m || v >= *n || u < 0 || v < 0) { 00265 return(0); 00266 } 00267 00268 minterm1 = one; cuddRef(minterm1); 00269 00270 /* Build minterm1 corresponding to this arc */ 00271 for (i = lnx - 1; i>=0; i--) { 00272 if (u & 1) { 00273 w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lx[i]); 00274 } else { 00275 w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lxn[i]); 00276 } 00277 if (w == NULL) { 00278 Cudd_RecursiveDeref(dd, minterm1); 00279 return(0); 00280 } 00281 cuddRef(w); 00282 Cudd_RecursiveDeref(dd, minterm1); 00283 minterm1 = w; 00284 u >>= 1; 00285 } 00286 for (i = lny - 1; i>=0; i--) { 00287 if (v & 1) { 00288 w = Cudd_addApply(dd, Cudd_addTimes, minterm1, ly[i]); 00289 } else { 00290 w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lyn[i]); 00291 } 00292 if (w == NULL) { 00293 Cudd_RecursiveDeref(dd, minterm1); 00294 return(0); 00295 } 00296 cuddRef(w); 00297 Cudd_RecursiveDeref(dd, minterm1); 00298 minterm1 = w; 00299 v >>= 1; 00300 } 00301 /* Create new constant node if necessary. 00302 ** This call will never cause reordering. 00303 */ 00304 neW = cuddUniqueConst(dd, val); 00305 if (neW == NULL) { 00306 Cudd_RecursiveDeref(dd, minterm1); 00307 return(0); 00308 } 00309 cuddRef(neW); 00310 00311 w = Cudd_addIte(dd, minterm1, neW, *E); 00312 if (w == NULL) { 00313 Cudd_RecursiveDeref(dd, minterm1); 00314 Cudd_RecursiveDeref(dd, neW); 00315 return(0); 00316 } 00317 cuddRef(w); 00318 Cudd_RecursiveDeref(dd, minterm1); 00319 Cudd_RecursiveDeref(dd, neW); 00320 Cudd_RecursiveDeref(dd, *E); 00321 *E = w; 00322 } 00323 return(1); 00324 00325 } /* end of Cudd_addRead */
Function********************************************************************
Synopsis [Builds an ADD for the residue modulo m of an n-bit number.]
Description [Builds an ADD for the residue modulo m of an n-bit number. The modulus must be at least 2, and the number of bits at least 1. Parameter options specifies whether the MSB should be on top or the LSB; and whther the number whose residue is computed is in two's complement notation or not. The macro CUDD_RESIDUE_DEFAULT specifies LSB on top and unsigned number. The macro CUDD_RESIDUE_MSB specifies MSB on top, and the macro CUDD_RESIDUE_TC specifies two's complement residue. To request MSB on top and two's complement residue simultaneously, one can OR the two macros: CUDD_RESIDUE_MSB | CUDD_RESIDUE_TC. Cudd_addResidue returns a pointer to the resulting ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 157 of file cuddAddWalsh.c.
00163 { 00164 int msbLsb; /* MSB on top (1) or LSB on top (0) */ 00165 int tc; /* two's complement (1) or unsigned (0) */ 00166 int i, j, k, t, residue, thisOne, previous, index; 00167 DdNode **array[2], *var, *tmp, *res; 00168 00169 /* Sanity check. */ 00170 if (n < 1 && m < 2) return(NULL); 00171 00172 msbLsb = options & CUDD_RESIDUE_MSB; 00173 tc = options & CUDD_RESIDUE_TC; 00174 00175 /* Allocate and initialize working arrays. */ 00176 array[0] = ALLOC(DdNode *,m); 00177 if (array[0] == NULL) { 00178 dd->errorCode = CUDD_MEMORY_OUT; 00179 return(NULL); 00180 } 00181 array[1] = ALLOC(DdNode *,m); 00182 if (array[1] == NULL) { 00183 FREE(array[0]); 00184 dd->errorCode = CUDD_MEMORY_OUT; 00185 return(NULL); 00186 } 00187 for (i = 0; i < m; i++) { 00188 array[0][i] = array[1][i] = NULL; 00189 } 00190 00191 /* Initialize residues. */ 00192 for (i = 0; i < m; i++) { 00193 tmp = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) i); 00194 if (tmp == NULL) { 00195 for (j = 0; j < i; j++) { 00196 Cudd_RecursiveDeref(dd,array[1][j]); 00197 } 00198 FREE(array[0]); 00199 FREE(array[1]); 00200 return(NULL); 00201 } 00202 cuddRef(tmp); 00203 array[1][i] = tmp; 00204 } 00205 00206 /* Main iteration. */ 00207 residue = 1; /* residue of 2**0 */ 00208 for (k = 0; k < n; k++) { 00209 /* Choose current and previous arrays. */ 00210 thisOne = k & 1; 00211 previous = thisOne ^ 1; 00212 /* Build an ADD projection function. */ 00213 if (msbLsb) { 00214 index = top+n-k-1; 00215 } else { 00216 index = top+k; 00217 } 00218 var = cuddUniqueInter(dd,index,DD_ONE(dd),DD_ZERO(dd)); 00219 if (var == NULL) { 00220 for (j = 0; j < m; j++) { 00221 Cudd_RecursiveDeref(dd,array[previous][j]); 00222 } 00223 FREE(array[0]); 00224 FREE(array[1]); 00225 return(NULL); 00226 } 00227 cuddRef(var); 00228 for (i = 0; i < m; i ++) { 00229 t = (i + residue) % m; 00230 tmp = Cudd_addIte(dd,var,array[previous][t],array[previous][i]); 00231 if (tmp == NULL) { 00232 for (j = 0; j < i; j++) { 00233 Cudd_RecursiveDeref(dd,array[thisOne][j]); 00234 } 00235 for (j = 0; j < m; j++) { 00236 Cudd_RecursiveDeref(dd,array[previous][j]); 00237 } 00238 FREE(array[0]); 00239 FREE(array[1]); 00240 return(NULL); 00241 } 00242 cuddRef(tmp); 00243 array[thisOne][i] = tmp; 00244 } 00245 /* One layer completed. Free the other array for the next iteration. */ 00246 for (i = 0; i < m; i++) { 00247 Cudd_RecursiveDeref(dd,array[previous][i]); 00248 } 00249 Cudd_RecursiveDeref(dd,var); 00250 /* Update residue of 2**k. */ 00251 residue = (2 * residue) % m; 00252 /* Adjust residue for MSB, if this is a two's complement number. */ 00253 if (tc && (k == n - 1)) { 00254 residue = (m - residue) % m; 00255 } 00256 } 00257 00258 /* We are only interested in the 0-residue node of the top layer. */ 00259 for (i = 1; i < m; i++) { 00260 Cudd_RecursiveDeref(dd,array[(n - 1) & 1][i]); 00261 } 00262 res = array[(n - 1) & 1][0]; 00263 00264 FREE(array[0]); 00265 FREE(array[1]); 00266 00267 cuddDeref(res); 00268 return(res); 00269 00270 } /* end of Cudd_addResidue */
Function********************************************************************
Synopsis [ADD restrict according to Coudert and Madre's algorithm (ICCAD90).]
Description [ADD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns the restricted ADD if successful; otherwise NULL. If application of restrict results in an ADD larger than the input ADD, the input ADD is returned.]
SideEffects [None]
SeeAlso [Cudd_addConstrain Cudd_bddRestrict]
Definition at line 427 of file cuddGenCof.c.
00431 { 00432 DdNode *supp_f, *supp_c; 00433 DdNode *res, *commonSupport; 00434 int intersection; 00435 int sizeF, sizeRes; 00436 00437 /* Check if supports intersect. */ 00438 supp_f = Cudd_Support(dd, f); 00439 if (supp_f == NULL) { 00440 return(NULL); 00441 } 00442 cuddRef(supp_f); 00443 supp_c = Cudd_Support(dd, c); 00444 if (supp_c == NULL) { 00445 Cudd_RecursiveDeref(dd,supp_f); 00446 return(NULL); 00447 } 00448 cuddRef(supp_c); 00449 commonSupport = Cudd_bddLiteralSetIntersection(dd, supp_f, supp_c); 00450 if (commonSupport == NULL) { 00451 Cudd_RecursiveDeref(dd,supp_f); 00452 Cudd_RecursiveDeref(dd,supp_c); 00453 return(NULL); 00454 } 00455 cuddRef(commonSupport); 00456 Cudd_RecursiveDeref(dd,supp_f); 00457 Cudd_RecursiveDeref(dd,supp_c); 00458 intersection = commonSupport != DD_ONE(dd); 00459 Cudd_RecursiveDeref(dd,commonSupport); 00460 00461 if (intersection) { 00462 do { 00463 dd->reordered = 0; 00464 res = cuddAddRestrictRecur(dd, f, c); 00465 } while (dd->reordered == 1); 00466 sizeF = Cudd_DagSize(f); 00467 sizeRes = Cudd_DagSize(res); 00468 if (sizeF <= sizeRes) { 00469 cuddRef(res); 00470 Cudd_RecursiveDeref(dd, res); 00471 return(f); 00472 } else { 00473 return(res); 00474 } 00475 } else { 00476 return(f); 00477 } 00478 00479 } /* end of Cudd_addRestrict */
Function********************************************************************
Synopsis [Rounds off the discriminants of an ADD.]
Description [Rounds off the discriminants of an ADD. The discriminants are rounded off to N digits after the decimal. Returns a pointer to the result ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 144 of file cuddAddNeg.c.
00148 { 00149 DdNode *res; 00150 double trunc = pow(10.0,(double)N); 00151 00152 do { 00153 res = cuddAddRoundOffRecur(dd,f,trunc); 00154 } while (dd->reordered == 1); 00155 return(res); 00156 00157 } /* end of Cudd_addRoundOff */
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Computes the scalar inverse of an ADD.]
Description [Computes an n ADD where the discriminants are the multiplicative inverses of the corresponding discriminants of the argument ADD. Returns a pointer to the resulting ADD in case of success. Returns NULL if any discriminants smaller than epsilon is encountered.]
SideEffects [None]
Definition at line 116 of file cuddAddInv.c.
00120 { 00121 DdNode *res; 00122 00123 if (!cuddIsConstant(epsilon)) { 00124 (void) fprintf(dd->err,"Invalid epsilon\n"); 00125 return(NULL); 00126 } 00127 do { 00128 dd->reordered = 0; 00129 res = cuddAddScalarInverseRecur(dd,f,epsilon); 00130 } while (dd->reordered == 1); 00131 return(res); 00132 00133 } /* end of Cudd_addScalarInverse */
Function********************************************************************
Synopsis [This operator sets f to the value of g wherever g != 0.]
Description [This operator sets f to the value of g wherever g != 0. Returns NULL if not a terminal case; f op g otherwise.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 278 of file cuddAddApply.c.
00282 { 00283 DdNode *F, *G; 00284 00285 F = *f; G = *g; 00286 if (F == G) return(F); 00287 if (F == DD_ZERO(dd)) return(G); 00288 if (G == DD_ZERO(dd)) return(F); 00289 if (cuddIsConstant(G)) return(G); 00290 return(NULL); 00291 00292 } /* end of Cudd_addSetNZ */
Function********************************************************************
Synopsis [Swaps two sets of variables of the same size (x and y) in the ADD f.]
Description [Swaps two sets of variables of the same size (x and y) in the ADD f. The size is given by n. The two sets of variables are assumed to be disjoint. Returns a pointer to the resulting ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addPermute Cudd_bddSwapVariables]
Definition at line 279 of file cuddCompose.c.
00285 { 00286 DdNode *swapped; 00287 int i, j, k; 00288 int *permut; 00289 00290 permut = ALLOC(int,dd->size); 00291 if (permut == NULL) { 00292 dd->errorCode = CUDD_MEMORY_OUT; 00293 return(NULL); 00294 } 00295 for (i = 0; i < dd->size; i++) permut[i] = i; 00296 for (i = 0; i < n; i++) { 00297 j = x[i]->index; 00298 k = y[i]->index; 00299 permut[j] = k; 00300 permut[k] = j; 00301 } 00302 00303 swapped = Cudd_addPermute(dd,f,permut); 00304 FREE(permut); 00305 00306 return(swapped); 00307 00308 } /* end of Cudd_addSwapVariables */
Function********************************************************************
Synopsis [f if f>=g; 0 if f<g.]
Description [Threshold operator for Apply (f if f >=g; 0 if f<g). Returns NULL if not a terminal case; f op g otherwise.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 244 of file cuddAddApply.c.
00248 { 00249 DdNode *F, *G; 00250 00251 F = *f; G = *g; 00252 if (F == G || F == DD_PLUS_INFINITY(dd)) return(F); 00253 if (cuddIsConstant(F) && cuddIsConstant(G)) { 00254 if (cuddV(F) >= cuddV(G)) { 00255 return(F); 00256 } else { 00257 return(DD_ZERO(dd)); 00258 } 00259 } 00260 return(NULL); 00261 00262 } /* end of Cudd_addThreshold */
Function********************************************************************
Synopsis [Integer and floating point multiplication.]
Description [Integer and floating point multiplication. Returns NULL if not a terminal case; f * g otherwise. This function can be used also to take the AND of two 0-1 ADDs.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 204 of file cuddAddApply.c.
00208 { 00209 DdNode *res; 00210 DdNode *F, *G; 00211 CUDD_VALUE_TYPE value; 00212 00213 F = *f; G = *g; 00214 if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ZERO(dd)); 00215 if (F == DD_ONE(dd)) return(G); 00216 if (G == DD_ONE(dd)) return(F); 00217 if (cuddIsConstant(F) && cuddIsConstant(G)) { 00218 value = cuddV(F)*cuddV(G); 00219 res = cuddUniqueConst(dd,value); 00220 return(res); 00221 } 00222 if (F > G) { /* swap f and g */ 00223 *f = G; 00224 *g = F; 00225 } 00226 return(NULL); 00227 00228 } /* end of Cudd_addTimes */
Function********************************************************************
Synopsis [Calculates the product of two matrices represented as ADDs.]
Description [Calculates the product of two matrices, A and B, represented as ADDs, using the CMU matrix by matrix multiplication procedure by Clarke et al.. Matrix A has x's as row variables and z's as column variables, while matrix B has z's as row variables and y's as column variables. Returns the pointer to the result if successful; NULL otherwise. The resulting matrix has x's as row variables and y's as column variables.]
SideEffects [None]
SeeAlso [Cudd_addMatrixMultiply]
Definition at line 181 of file cuddMatMult.c.
00187 { 00188 DdNode *w, *cube, *tmp, *res; 00189 int i; 00190 tmp = Cudd_addApply(dd,Cudd_addTimes,A,B); 00191 if (tmp == NULL) return(NULL); 00192 Cudd_Ref(tmp); 00193 Cudd_Ref(cube = DD_ONE(dd)); 00194 for (i = nz-1; i >= 0; i--) { 00195 w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd)); 00196 if (w == NULL) { 00197 Cudd_RecursiveDeref(dd,tmp); 00198 return(NULL); 00199 } 00200 Cudd_Ref(w); 00201 Cudd_RecursiveDeref(dd,cube); 00202 cube = w; 00203 } 00204 res = Cudd_addExistAbstract(dd,tmp,cube); 00205 if (res == NULL) { 00206 Cudd_RecursiveDeref(dd,tmp); 00207 Cudd_RecursiveDeref(dd,cube); 00208 return(NULL); 00209 } 00210 Cudd_Ref(res); 00211 Cudd_RecursiveDeref(dd,cube); 00212 Cudd_RecursiveDeref(dd,tmp); 00213 Cudd_Deref(res); 00214 return(res); 00215 00216 } /* end of Cudd_addTimesPlus */
Function********************************************************************
Synopsis [Performs the triangulation step for the shortest path computation.]
Description [Implements the semiring multiplication algorithm used in the triangulation step for the shortest path computation. f is assumed to depend on variables x (rows) and z (columns). g is assumed to depend on variables z (rows) and y (columns). The product of f and g then depends on x (rows) and y (columns). Only the z variables have to be explicitly identified; they are the "abstraction" variables. Returns a pointer to the result if successful; NULL otherwise. ]
SideEffects [None]
SeeAlso [Cudd_addMatrixMultiply Cudd_bddAndAbstract]
Definition at line 239 of file cuddMatMult.c.
00245 { 00246 int i, nvars, *vars; 00247 DdNode *res, *cube; 00248 00249 nvars = dd->size; 00250 vars = ALLOC(int, nvars); 00251 if (vars == NULL) { 00252 dd->errorCode = CUDD_MEMORY_OUT; 00253 return(NULL); 00254 } 00255 for (i = 0; i < nvars; i++) vars[i] = -1; 00256 for (i = 0; i < nz; i++) vars[z[i]->index] = i; 00257 cube = Cudd_addComputeCube(dd, z, NULL, nz); 00258 if (cube == NULL) { 00259 FREE(vars); 00260 return(NULL); 00261 } 00262 cuddRef(cube); 00263 00264 do { 00265 dd->reordered = 0; 00266 res = addTriangleRecur(dd, f, g, vars, cube); 00267 } while (dd->reordered == 1); 00268 if (res != NULL) cuddRef(res); 00269 Cudd_RecursiveDeref(dd,cube); 00270 if (res != NULL) cuddDeref(res); 00271 FREE(vars); 00272 return(res); 00273 00274 } /* end of Cudd_addTriangle */
Function********************************************************************
Synopsis [Universally Abstracts all the variables in cube from f.]
Description [Abstracts all the variables in cube from f by taking the product over all possible values taken by the variable. Returns the abstracted ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addExistAbstract Cudd_bddUnivAbstract Cudd_addOrAbstract]
Definition at line 174 of file cuddAddAbs.c.
00178 { 00179 DdNode *res; 00180 00181 if (addCheckPositiveCube(manager, cube) == 0) { 00182 (void) fprintf(manager->err,"Error: Can only abstract cubes"); 00183 return(NULL); 00184 } 00185 00186 do { 00187 manager->reordered = 0; 00188 res = cuddAddUnivAbstractRecur(manager, f, cube); 00189 } while (manager->reordered == 1); 00190 00191 return(res); 00192 00193 } /* end of Cudd_addUnivAbstract */
Function********************************************************************
Synopsis [Composes an ADD with a vector of 0-1 ADDs.]
Description [Given a vector of 0-1 ADDs, creates a new ADD by substituting the 0-1 ADDs for the variables of the ADD f. There should be an entry in vector for each variable in the manager. If no substitution is sought for a given variable, the corresponding projection function should be specified in the vector. This function implements simultaneous composition. Returns a pointer to the resulting ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addNonSimCompose Cudd_addPermute Cudd_addCompose Cudd_bddVectorCompose]
Definition at line 559 of file cuddCompose.c.
00563 { 00564 DdHashTable *table; 00565 DdNode *res; 00566 int deepest; 00567 int i; 00568 00569 do { 00570 dd->reordered = 0; 00571 /* Initialize local cache. */ 00572 table = cuddHashTableInit(dd,1,2); 00573 if (table == NULL) return(NULL); 00574 00575 /* Find deepest real substitution. */ 00576 for (deepest = dd->size - 1; deepest >= 0; deepest--) { 00577 i = dd->invperm[deepest]; 00578 if (!ddIsIthAddVar(dd,vector[i],i)) { 00579 break; 00580 } 00581 } 00582 00583 /* Recursively solve the problem. */ 00584 res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest); 00585 if (res != NULL) cuddRef(res); 00586 00587 /* Dispose of local cache. */ 00588 cuddHashTableQuit(table); 00589 } while (dd->reordered == 1); 00590 00591 if (res != NULL) cuddDeref(res); 00592 return(res); 00593 00594 } /* end of Cudd_addVectorCompose */
AutomaticEnd Function********************************************************************
Synopsis [Generates a Walsh matrix in ADD form.]
Description [Generates a Walsh matrix in ADD form. Returns a pointer to the matrixi if successful; NULL otherwise.]
SideEffects [None]
Definition at line 116 of file cuddAddWalsh.c.
00121 { 00122 DdNode *res; 00123 00124 do { 00125 dd->reordered = 0; 00126 res = addWalshInt(dd, x, y, n); 00127 } while (dd->reordered == 1); 00128 return(res); 00129 00130 } /* end of Cudd_addWalsh */
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 [XNOR of two 0-1 ADDs.]
Description [XNOR of two 0-1 ADDs. Returns NULL if not a terminal case; f XNOR g otherwise.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 709 of file cuddAddApply.c.
00713 { 00714 DdNode *F, *G; 00715 00716 F = *f; G = *g; 00717 if (F == G) return(DD_ONE(dd)); 00718 if (F == DD_ONE(dd) && G == DD_ONE(dd)) return(DD_ONE(dd)); 00719 if (G == DD_ZERO(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd)); 00720 if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); 00721 if (F > G) { /* swap f and g */ 00722 *f = G; 00723 *g = F; 00724 } 00725 return(NULL); 00726 00727 } /* end of Cudd_addXnor */
Function********************************************************************
Synopsis [XOR of two 0-1 ADDs.]
Description [XOR of two 0-1 ADDs. Returns NULL if not a terminal case; f XOR g otherwise.]
SideEffects [None]
SeeAlso [Cudd_addApply]
Definition at line 675 of file cuddAddApply.c.
00679 { 00680 DdNode *F, *G; 00681 00682 F = *f; G = *g; 00683 if (F == G) return(DD_ZERO(dd)); 00684 if (F == DD_ONE(dd) && G == DD_ZERO(dd)) return(DD_ONE(dd)); 00685 if (G == DD_ONE(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd)); 00686 if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); 00687 if (F > G) { /* swap f and g */ 00688 *f = G; 00689 *g = F; 00690 } 00691 return(NULL); 00692 00693 } /* end of Cudd_addXor */
DdApaDigit Cudd_ApaAdd | ( | int | digits, | |
DdApaNumber | a, | |||
DdApaNumber | b, | |||
DdApaNumber | sum | |||
) |
Function********************************************************************
Synopsis [Adds two arbitrary precision integers.]
Description [Adds two arbitrary precision integers. Returns the carry out of the most significant digit.]
SideEffects [The result of the sum is stored in parameter sum
.]
SeeAlso []
Definition at line 217 of file cuddApa.c.
00222 { 00223 int i; 00224 DdApaDoubleDigit partial = 0; 00225 00226 for (i = digits - 1; i >= 0; i--) { 00227 partial = a[i] + b[i] + DD_MSDIGIT(partial); 00228 sum[i] = (DdApaDigit) DD_LSDIGIT(partial); 00229 } 00230 return((DdApaDigit) DD_MSDIGIT(partial)); 00231 00232 } /* end of Cudd_ApaAdd */
int Cudd_ApaCompare | ( | int | digitsFirst, | |
DdApaNumber | first, | |||
int | digitsSecond, | |||
DdApaNumber | second | |||
) |
Function********************************************************************
Synopsis [Compares two arbitrary precision integers.]
Description [Compares two arbitrary precision integers. Returns 1 if the first number is larger; 0 if they are equal; -1 if the second number is larger.]
SideEffects [None]
SeeAlso []
Definition at line 445 of file cuddApa.c.
00450 { 00451 int i; 00452 int firstNZ, secondNZ; 00453 00454 /* Find first non-zero in both numbers. */ 00455 for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++) 00456 if (first[firstNZ] != 0) break; 00457 for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++) 00458 if (second[secondNZ] != 0) break; 00459 if (digitsFirst - firstNZ > digitsSecond - secondNZ) return(1); 00460 else if (digitsFirst - firstNZ < digitsSecond - secondNZ) return(-1); 00461 for (i = 0; i < digitsFirst - firstNZ; i++) { 00462 if (first[firstNZ + i] > second[secondNZ + i]) return(1); 00463 else if (first[firstNZ + i] < second[secondNZ + i]) return(-1); 00464 } 00465 return(0); 00466 00467 } /* end of Cudd_ApaCompare */
int Cudd_ApaCompareRatios | ( | int | digitsFirst, | |
DdApaNumber | firstNum, | |||
unsigned int | firstDen, | |||
int | digitsSecond, | |||
DdApaNumber | secondNum, | |||
unsigned int | secondDen | |||
) |
Function********************************************************************
Synopsis [Compares the ratios of two arbitrary precision integers to two unsigned ints.]
Description [Compares the ratios of two arbitrary precision integers to two unsigned ints. Returns 1 if the first number is larger; 0 if they are equal; -1 if the second number is larger.]
SideEffects [None]
SeeAlso []
Definition at line 485 of file cuddApa.c.
00492 { 00493 int result; 00494 DdApaNumber first, second; 00495 unsigned int firstRem, secondRem; 00496 00497 first = Cudd_NewApaNumber(digitsFirst); 00498 firstRem = Cudd_ApaIntDivision(digitsFirst,firstNum,firstDen,first); 00499 second = Cudd_NewApaNumber(digitsSecond); 00500 secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second); 00501 result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second); 00502 FREE(first); 00503 FREE(second); 00504 if (result == 0) { 00505 if ((double)firstRem/firstDen > (double)secondRem/secondDen) 00506 return(1); 00507 else if ((double)firstRem/firstDen < (double)secondRem/secondDen) 00508 return(-1); 00509 } 00510 return(result); 00511 00512 } /* end of Cudd_ApaCompareRatios */
void Cudd_ApaCopy | ( | int | digits, | |
DdApaNumber | source, | |||
DdApaNumber | dest | |||
) |
Function********************************************************************
Synopsis [Makes a copy of an arbitrary precision integer.]
Description [Makes a copy of an arbitrary precision integer.]
SideEffects [Changes parameter dest
.]
SeeAlso []
DdApaNumber Cudd_ApaCountMinterm | ( | DdManager * | manager, | |
DdNode * | node, | |||
int | nvars, | |||
int * | digits | |||
) |
Function********************************************************************
Synopsis [Counts the number of minterms of a DD.]
Description [Counts the number of minterms of a DD. The function is assumed to depend on nvars variables. The minterm count is represented as an arbitrary precision unsigned integer, to allow for any number of variables CUDD supports. Returns a pointer to the array representing the number of minterms of the function rooted at node if successful; NULL otherwise.]
SideEffects [The number of digits of the result is returned in parameter digits
.]
SeeAlso [Cudd_CountMinterm]
Definition at line 680 of file cuddApa.c.
00685 { 00686 DdApaNumber max, min; 00687 st_table *table; 00688 DdApaNumber i,count; 00689 00690 background = manager->background; 00691 zero = Cudd_Not(manager->one); 00692 00693 *digits = Cudd_ApaNumberOfDigits(nvars+1); 00694 max = Cudd_NewApaNumber(*digits); 00695 if (max == NULL) { 00696 return(NULL); 00697 } 00698 Cudd_ApaPowerOfTwo(*digits,max,nvars); 00699 min = Cudd_NewApaNumber(*digits); 00700 if (min == NULL) { 00701 FREE(max); 00702 return(NULL); 00703 } 00704 Cudd_ApaSetToLiteral(*digits,min,0); 00705 table = st_init_table(st_ptrcmp,st_ptrhash); 00706 if (table == NULL) { 00707 FREE(max); 00708 FREE(min); 00709 return(NULL); 00710 } 00711 i = cuddApaCountMintermAux(Cudd_Regular(node),*digits,max,min,table); 00712 if (i == NULL) { 00713 FREE(max); 00714 FREE(min); 00715 st_foreach(table, cuddApaStCountfree, NULL); 00716 st_free_table(table); 00717 return(NULL); 00718 } 00719 count = Cudd_NewApaNumber(*digits); 00720 if (count == NULL) { 00721 FREE(max); 00722 FREE(min); 00723 st_foreach(table, cuddApaStCountfree, NULL); 00724 st_free_table(table); 00725 if (Cudd_Regular(node)->ref == 1) FREE(i); 00726 return(NULL); 00727 } 00728 if (Cudd_IsComplement(node)) { 00729 (void) Cudd_ApaSubtract(*digits,max,i,count); 00730 } else { 00731 Cudd_ApaCopy(*digits,i,count); 00732 } 00733 FREE(max); 00734 FREE(min); 00735 st_foreach(table, cuddApaStCountfree, NULL); 00736 st_free_table(table); 00737 if (Cudd_Regular(node)->ref == 1) FREE(i); 00738 return(count); 00739 00740 } /* end of Cudd_ApaCountMinterm */
unsigned int Cudd_ApaIntDivision | ( | int | digits, | |
DdApaNumber | dividend, | |||
unsigned int | divisor, | |||
DdApaNumber | quotient | |||
) |
Function********************************************************************
Synopsis [Divides an arbitrary precision integer by an integer.]
Description [Divides an arbitrary precision integer by a 32-bit unsigned integer. Returns the remainder of the division. This procedure relies on the assumption that the number of bits of a DdApaDigit plus the number of bits of an unsigned int is less the number of bits of the mantissa of a double. This guarantees that the product of a DdApaDigit and an unsigned int can be represented without loss of precision by a double. On machines where this assumption is not satisfied, this procedure will malfunction.]
SideEffects [The quotient is returned in parameter quotient
.]
SeeAlso [Cudd_ApaShortDivision]
Definition at line 320 of file cuddApa.c.
00325 { 00326 int i; 00327 double partial; 00328 unsigned int remainder = 0; 00329 double ddiv = (double) divisor; 00330 00331 for (i = 0; i < digits; i++) { 00332 partial = (double) remainder * DD_APA_BASE + dividend[i]; 00333 quotient[i] = (DdApaDigit) (partial / ddiv); 00334 remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv)); 00335 } 00336 00337 return(remainder); 00338 00339 } /* end of Cudd_ApaIntDivision */
int Cudd_ApaNumberOfDigits | ( | int | binaryDigits | ) |
AutomaticEnd Function********************************************************************
Synopsis [Finds the number of digits for an arbitrary precision integer.]
Description [Finds the number of digits for an arbitrary precision integer given the maximum number of binary digits. The number of binary digits should be positive. Returns the number of digits if successful; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 143 of file cuddApa.c.
00145 { 00146 int digits; 00147 00148 digits = binaryDigits / DD_APA_BITS; 00149 if ((digits * DD_APA_BITS) != binaryDigits) 00150 digits++; 00151 return(digits); 00152 00153 } /* end of Cudd_ApaNumberOfDigits */
void Cudd_ApaPowerOfTwo | ( | int | digits, | |
DdApaNumber | number, | |||
int | power | |||
) |
Function********************************************************************
Synopsis [Sets an arbitrary precision integer to a power of two.]
Description [Sets an arbitrary precision integer to a power of two. If the power of two is too large to be represented, the number is set to 0.]
SideEffects [The result is returned in parameter number
.]
SeeAlso []
Definition at line 413 of file cuddApa.c.
00417 { 00418 int i; 00419 int index; 00420 00421 for (i = 0; i < digits; i++) 00422 number[i] = 0; 00423 i = digits - 1 - power / DD_APA_BITS; 00424 if (i < 0) return; 00425 index = power & (DD_APA_BITS - 1); 00426 number[i] = 1 << index; 00427 00428 } /* end of Cudd_ApaPowerOfTwo */
int Cudd_ApaPrintDecimal | ( | FILE * | fp, | |
int | digits, | |||
DdApaNumber | number | |||
) |
Function********************************************************************
Synopsis [Prints an arbitrary precision integer in decimal format.]
Description [Prints an arbitrary precision integer in decimal format. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintExponential]
Definition at line 558 of file cuddApa.c.
00562 { 00563 int i, result; 00564 DdApaDigit remainder; 00565 DdApaNumber work; 00566 unsigned char *decimal; 00567 int leadingzero; 00568 int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; 00569 00570 work = Cudd_NewApaNumber(digits); 00571 if (work == NULL) 00572 return(0); 00573 decimal = ALLOC(unsigned char, decimalDigits); 00574 if (decimal == NULL) { 00575 FREE(work); 00576 return(0); 00577 } 00578 Cudd_ApaCopy(digits,number,work); 00579 for (i = decimalDigits - 1; i >= 0; i--) { 00580 remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); 00581 decimal[i] = (unsigned char) remainder; 00582 } 00583 FREE(work); 00584 00585 leadingzero = 1; 00586 for (i = 0; i < decimalDigits; i++) { 00587 leadingzero = leadingzero && (decimal[i] == 0); 00588 if ((!leadingzero) || (i == (decimalDigits - 1))) { 00589 result = fprintf(fp,"%1d",decimal[i]); 00590 if (result == EOF) { 00591 FREE(decimal); 00592 return(0); 00593 } 00594 } 00595 } 00596 FREE(decimal); 00597 return(1); 00598 00599 } /* end of Cudd_ApaPrintDecimal */
Function********************************************************************
Synopsis [Prints the density of a BDD or ADD using arbitrary precision arithmetic.]
Description [Prints the density of a BDD or ADD using arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 834 of file cuddApa.c.
00839 { 00840 int digits; 00841 int result; 00842 DdApaNumber count,density; 00843 unsigned int size, remainder, fractional; 00844 00845 count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); 00846 if (count == NULL) 00847 return(0); 00848 size = Cudd_DagSize(node); 00849 density = Cudd_NewApaNumber(digits); 00850 remainder = Cudd_ApaIntDivision(digits,count,size,density); 00851 result = Cudd_ApaPrintDecimal(fp,digits,density); 00852 FREE(count); 00853 FREE(density); 00854 fractional = (unsigned int)((double)remainder / size * 1000000); 00855 if (fprintf(fp,".%u\n", fractional) == EOF) { 00856 return(0); 00857 } 00858 return(result); 00859 00860 } /* end of Cudd_ApaPrintDensity */
int Cudd_ApaPrintExponential | ( | FILE * | fp, | |
int | digits, | |||
DdApaNumber | number, | |||
int | precision | |||
) |
Function********************************************************************
Synopsis [Prints an arbitrary precision integer in exponential format.]
Description [Prints an arbitrary precision integer in exponential format. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintDecimal]
Definition at line 615 of file cuddApa.c.
00620 { 00621 int i, first, last, result; 00622 DdApaDigit remainder; 00623 DdApaNumber work; 00624 unsigned char *decimal; 00625 int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; 00626 00627 work = Cudd_NewApaNumber(digits); 00628 if (work == NULL) 00629 return(0); 00630 decimal = ALLOC(unsigned char, decimalDigits); 00631 if (decimal == NULL) { 00632 FREE(work); 00633 return(0); 00634 } 00635 Cudd_ApaCopy(digits,number,work); 00636 first = decimalDigits - 1; 00637 for (i = decimalDigits - 1; i >= 0; i--) { 00638 remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); 00639 decimal[i] = (unsigned char) remainder; 00640 if (remainder != 0) first = i; /* keep track of MS non-zero */ 00641 } 00642 FREE(work); 00643 last = ddMin(first + precision, decimalDigits); 00644 00645 for (i = first; i < last; i++) { 00646 result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]); 00647 if (result == EOF) { 00648 FREE(decimal); 00649 return(0); 00650 } 00651 } 00652 FREE(decimal); 00653 result = fprintf(fp,"e+%d",decimalDigits - first - 1); 00654 if (result == EOF) { 00655 return(0); 00656 } 00657 return(1); 00658 00659 } /* end of Cudd_ApaPrintExponential */
int Cudd_ApaPrintHex | ( | FILE * | fp, | |
int | digits, | |||
DdApaNumber | number | |||
) |
Function********************************************************************
Synopsis [Prints an arbitrary precision integer in hexadecimal format.]
Description [Prints an arbitrary precision integer in hexadecimal format. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_ApaPrintDecimal Cudd_ApaPrintExponential]
Definition at line 528 of file cuddApa.c.
00532 { 00533 int i, result; 00534 00535 for (i = 0; i < digits; i++) { 00536 result = fprintf(fp,DD_APA_HEXPRINT,number[i]); 00537 if (result == EOF) 00538 return(0); 00539 } 00540 return(1); 00541 00542 } /* end of Cudd_ApaPrintHex */
Function********************************************************************
Synopsis [Prints the number of minterms of a BDD or ADD using arbitrary precision arithmetic.]
Description [Prints the number of minterms of a BDD or ADD using arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_ApaPrintMintermExp]
Definition at line 757 of file cuddApa.c.
00762 { 00763 int digits; 00764 int result; 00765 DdApaNumber count; 00766 00767 count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); 00768 if (count == NULL) 00769 return(0); 00770 result = Cudd_ApaPrintDecimal(fp,digits,count); 00771 FREE(count); 00772 if (fprintf(fp,"\n") == EOF) { 00773 return(0); 00774 } 00775 return(result); 00776 00777 } /* end of Cudd_ApaPrintMinterm */
Function********************************************************************
Synopsis [Prints the number of minterms of a BDD or ADD in exponential format using arbitrary precision arithmetic.]
Description [Prints the number of minterms of a BDD or ADD in exponential format using arbitrary precision arithmetic. Parameter precision controls the number of signficant digits printed. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_ApaPrintMinterm]
Definition at line 796 of file cuddApa.c.
00802 { 00803 int digits; 00804 int result; 00805 DdApaNumber count; 00806 00807 count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); 00808 if (count == NULL) 00809 return(0); 00810 result = Cudd_ApaPrintExponential(fp,digits,count,precision); 00811 FREE(count); 00812 if (fprintf(fp,"\n") == EOF) { 00813 return(0); 00814 } 00815 return(result); 00816 00817 } /* end of Cudd_ApaPrintMintermExp */
void Cudd_ApaSetToLiteral | ( | int | digits, | |
DdApaNumber | number, | |||
DdApaDigit | literal | |||
) |
Function********************************************************************
Synopsis [Sets an arbitrary precision integer to a one-digit literal.]
Description [Sets an arbitrary precision integer to a one-digit literal.]
SideEffects [The result is returned in parameter number
.]
SeeAlso []
void Cudd_ApaShiftRight | ( | int | digits, | |
DdApaDigit | in, | |||
DdApaNumber | a, | |||
DdApaNumber | b | |||
) |
Function********************************************************************
Synopsis [Shifts right an arbitrary precision integer by one binary place.]
Description [Shifts right an arbitrary precision integer by one binary place. The most significant binary digit of the result is taken from parameter in
.]
SideEffects [The result is returned in parameter b
.]
SeeAlso []
Definition at line 357 of file cuddApa.c.
00362 { 00363 int i; 00364 00365 for (i = digits - 1; i > 0; i--) { 00366 b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1)); 00367 } 00368 b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1)); 00369 00370 } /* end of Cudd_ApaShiftRight */
DdApaDigit Cudd_ApaShortDivision | ( | int | digits, | |
DdApaNumber | dividend, | |||
DdApaDigit | divisor, | |||
DdApaNumber | quotient | |||
) |
Function********************************************************************
Synopsis [Divides an arbitrary precision integer by a digit.]
Description [Divides an arbitrary precision integer by a digit.]
SideEffects [The quotient is returned in parameter quotient
.]
SeeAlso []
Definition at line 279 of file cuddApa.c.
00284 { 00285 int i; 00286 DdApaDigit remainder; 00287 DdApaDoubleDigit partial; 00288 00289 remainder = 0; 00290 for (i = 0; i < digits; i++) { 00291 partial = remainder * DD_APA_BASE + dividend[i]; 00292 quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor); 00293 remainder = (DdApaDigit) (partial % divisor); 00294 } 00295 00296 return(remainder); 00297 00298 } /* end of Cudd_ApaShortDivision */
DdApaDigit Cudd_ApaSubtract | ( | int | digits, | |
DdApaNumber | a, | |||
DdApaNumber | b, | |||
DdApaNumber | diff | |||
) |
Function********************************************************************
Synopsis [Subtracts two arbitrary precision integers.]
Description [Subtracts two arbitrary precision integers. Returns the borrow out of the most significant digit.]
SideEffects [The result of the subtraction is stored in parameter diff
.]
SeeAlso []
Definition at line 249 of file cuddApa.c.
00254 { 00255 int i; 00256 DdApaDoubleDigit partial = DD_APA_BASE; 00257 00258 for (i = digits - 1; i >= 0; i--) { 00259 partial = DD_MSDIGIT(partial) + DD_APA_MASK + a[i] - b[i]; 00260 diff[i] = (DdApaDigit) DD_LSDIGIT(partial); 00261 } 00262 return((DdApaDigit) DD_MSDIGIT(partial) - 1); 00263 00264 } /* end of Cudd_ApaSubtract */
void Cudd_AutodynDisable | ( | DdManager * | unique | ) |
Function********************************************************************
Synopsis [Disables automatic dynamic reordering.]
Description []
SideEffects [None]
SeeAlso [Cudd_AutodynEnable Cudd_ReorderingStatus Cudd_AutodynDisableZdd]
Definition at line 704 of file cuddAPI.c.
00706 { 00707 unique->autoDyn = 0; 00708 return; 00709 00710 } /* end of Cudd_AutodynDisable */
void Cudd_AutodynDisableZdd | ( | DdManager * | unique | ) |
Function********************************************************************
Synopsis [Disables automatic dynamic reordering of ZDDs.]
Description []
SideEffects [None]
SeeAlso [Cudd_AutodynEnableZdd Cudd_ReorderingStatusZdd Cudd_AutodynDisable]
Definition at line 782 of file cuddAPI.c.
00784 { 00785 unique->autoDynZ = 0; 00786 return; 00787 00788 } /* end of Cudd_AutodynDisableZdd */
void Cudd_AutodynEnable | ( | DdManager * | unique, | |
Cudd_ReorderingType | method | |||
) |
Function********************************************************************
Synopsis [Enables automatic dynamic reordering of BDDs and ADDs.]
Description [Enables automatic dynamic reordering of BDDs and ADDs. Parameter method is used to determine the method used for reordering. If CUDD_REORDER_SAME is passed, the method is unchanged.]
SideEffects [None]
SeeAlso [Cudd_AutodynDisable Cudd_ReorderingStatus Cudd_AutodynEnableZdd]
Definition at line 665 of file cuddAPI.c.
00668 { 00669 unique->autoDyn = 1; 00670 if (method != CUDD_REORDER_SAME) { 00671 unique->autoMethod = method; 00672 } 00673 #ifndef DD_NO_DEATH_ROW 00674 /* If reordering is enabled, using the death row causes too many 00675 ** invocations. Hence, we shrink the death row to just one entry. 00676 */ 00677 cuddClearDeathRow(unique); 00678 unique->deathRowDepth = 1; 00679 unique->deadMask = unique->deathRowDepth - 1; 00680 if ((unsigned) unique->nextDead > unique->deadMask) { 00681 unique->nextDead = 0; 00682 } 00683 unique->deathRow = REALLOC(DdNodePtr, unique->deathRow, 00684 unique->deathRowDepth); 00685 #endif 00686 return; 00687 00688 } /* end of Cudd_AutodynEnable */
void Cudd_AutodynEnableZdd | ( | DdManager * | unique, | |
Cudd_ReorderingType | method | |||
) |
Function********************************************************************
Synopsis [Enables automatic dynamic reordering of ZDDs.]
Description [Enables automatic dynamic reordering of ZDDs. Parameter method is used to determine the method used for reordering ZDDs. If CUDD_REORDER_SAME is passed, the method is unchanged.]
SideEffects [None]
SeeAlso [Cudd_AutodynDisableZdd Cudd_ReorderingStatusZdd Cudd_AutodynEnable]
Definition at line 756 of file cuddAPI.c.
00759 { 00760 unique->autoDynZ = 1; 00761 if (method != CUDD_REORDER_SAME) { 00762 unique->autoMethodZ = method; 00763 } 00764 return; 00765 00766 } /* end of Cudd_AutodynEnableZdd */
double Cudd_AverageDistance | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Computes the average distance between adjacent nodes.]
Description [Computes the average distance between adjacent nodes in the manager. Adjacent nodes are node pairs such that the second node is the then child, else child, or next node in the collision list.]
SideEffects [None]
SeeAlso []
Definition at line 2610 of file cuddUtil.c.
02612 { 02613 double tetotal, nexttotal; 02614 double tesubtotal, nextsubtotal; 02615 double temeasured, nextmeasured; 02616 int i, j; 02617 int slots, nvars; 02618 long diff; 02619 DdNode *scan; 02620 DdNodePtr *nodelist; 02621 DdNode *sentinel = &(dd->sentinel); 02622 02623 nvars = dd->size; 02624 if (nvars == 0) return(0.0); 02625 02626 /* Initialize totals. */ 02627 tetotal = 0.0; 02628 nexttotal = 0.0; 02629 temeasured = 0.0; 02630 nextmeasured = 0.0; 02631 02632 /* Scan the variable subtables. */ 02633 for (i = 0; i < nvars; i++) { 02634 nodelist = dd->subtables[i].nodelist; 02635 tesubtotal = 0.0; 02636 nextsubtotal = 0.0; 02637 slots = dd->subtables[i].slots; 02638 for (j = 0; j < slots; j++) { 02639 scan = nodelist[j]; 02640 while (scan != sentinel) { 02641 diff = (long) scan - (long) cuddT(scan); 02642 tesubtotal += (double) ddAbs(diff); 02643 diff = (long) scan - (long) Cudd_Regular(cuddE(scan)); 02644 tesubtotal += (double) ddAbs(diff); 02645 temeasured += 2.0; 02646 if (scan->next != sentinel) { 02647 diff = (long) scan - (long) scan->next; 02648 nextsubtotal += (double) ddAbs(diff); 02649 nextmeasured += 1.0; 02650 } 02651 scan = scan->next; 02652 } 02653 } 02654 tetotal += tesubtotal; 02655 nexttotal += nextsubtotal; 02656 } 02657 02658 /* Scan the constant table. */ 02659 nodelist = dd->constants.nodelist; 02660 nextsubtotal = 0.0; 02661 slots = dd->constants.slots; 02662 for (j = 0; j < slots; j++) { 02663 scan = nodelist[j]; 02664 while (scan != NULL) { 02665 if (scan->next != NULL) { 02666 diff = (long) scan - (long) scan->next; 02667 nextsubtotal += (double) ddAbs(diff); 02668 nextmeasured += 1.0; 02669 } 02670 scan = scan->next; 02671 } 02672 } 02673 nexttotal += nextsubtotal; 02674 02675 return((tetotal + nexttotal) / (temeasured + nextmeasured)); 02676 02677 } /* end of Cudd_AverageDistance */
Function********************************************************************
Synopsis [Rearranges a set of variables in the BDD B.]
Description [Rearranges a set of variables in the BDD B. The size of the set is given by n. This procedure is intended for the `randomization' of the priority functions. Returns a pointer to the BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_PrioritySelect]
Definition at line 508 of file cuddCompose.c.
00513 { 00514 DdNode *swapped; 00515 int i, j, k; 00516 int *permut; 00517 00518 permut = ALLOC(int,dd->size); 00519 if (permut == NULL) { 00520 dd->errorCode = CUDD_MEMORY_OUT; 00521 return(NULL); 00522 } 00523 for (i = 0; i < dd->size; i++) permut[i] = i; 00524 for (i = 0; i < n-2; i += 3) { 00525 j = x[i]->index; 00526 k = x[i+1]->index; 00527 permut[j] = k; 00528 permut[k] = j; 00529 } 00530 00531 swapped = Cudd_bddPermute(dd,B,permut); 00532 FREE(permut); 00533 00534 return(swapped); 00535 00536 } /* end of Cudd_bddAdjPermuteX */
Function********************************************************************
Synopsis [Computes the conjunction of two BDDs f and g.]
Description [Computes the conjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAndAbstract Cudd_bddIntersect Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]
Definition at line 310 of file cuddBddIte.c.
00314 { 00315 DdNode *res; 00316 00317 do { 00318 dd->reordered = 0; 00319 res = cuddBddAndRecur(dd,f,g); 00320 } while (dd->reordered == 1); 00321 return(res); 00322 00323 } /* end of Cudd_bddAnd */
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Takes the AND of two BDDs and simultaneously abstracts the variables in cube.]
Description [Takes the AND of two BDDs and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the result is successful; NULL otherwise. Cudd_bddAndAbstract implements the semiring matrix multiplication algorithm for the boolean semiring.]
SideEffects [None]
SeeAlso [Cudd_addMatrixMultiply Cudd_addTriangle Cudd_bddAnd]
Definition at line 120 of file cuddAndAbs.c.
00125 { 00126 DdNode *res; 00127 00128 do { 00129 manager->reordered = 0; 00130 res = cuddBddAndAbstractRecur(manager, f, g, cube); 00131 } while (manager->reordered == 1); 00132 return(res); 00133 00134 } /* end of Cudd_bddAndAbstract */
DdNode* Cudd_bddAndAbstractLimit | ( | DdManager * | manager, | |
DdNode * | f, | |||
DdNode * | g, | |||
DdNode * | cube, | |||
unsigned int | limit | |||
) |
Function********************************************************************
Synopsis [Takes the AND of two BDDs and simultaneously abstracts the variables in cube. Returns NULL if too many nodes are required.]
Description [Takes the AND of two BDDs and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the result is successful; NULL otherwise. In particular, if the number of new nodes created exceeds limit
, this function returns NULL.]
SideEffects [None]
SeeAlso [Cudd_bddAndAbstract]
Definition at line 154 of file cuddAndAbs.c.
00160 { 00161 DdNode *res; 00162 unsigned int saveLimit = manager->maxLive; 00163 00164 manager->maxLive = (manager->keys - manager->dead) + 00165 (manager->keysZ - manager->deadZ) + limit; 00166 do { 00167 manager->reordered = 0; 00168 res = cuddBddAndAbstractRecur(manager, f, g, cube); 00169 } while (manager->reordered == 1); 00170 manager->maxLive = saveLimit; 00171 return(res); 00172 00173 } /* end of Cudd_bddAndAbstractLimit */
Function********************************************************************
Synopsis [Computes the conjunction of two BDDs f and g. Returns NULL if too many nodes are required.]
Description [Computes the conjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up or more new nodes than limit
are required.]
SideEffects [None]
SeeAlso [Cudd_bddAnd]
Definition at line 342 of file cuddBddIte.c.
00347 { 00348 DdNode *res; 00349 unsigned int saveLimit = dd->maxLive; 00350 00351 dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; 00352 do { 00353 dd->reordered = 0; 00354 res = cuddBddAndRecur(dd,f,g); 00355 } while (dd->reordered == 1); 00356 dd->maxLive = saveLimit; 00357 return(res); 00358 00359 } /* end of Cudd_bddAndLimit */
AutomaticEnd Function********************************************************************
Synopsis [Performs two-way conjunctive decomposition of a BDD.]
Description [Performs two-way conjunctive decomposition of a BDD. This procedure owes its name to the use of supersetting to obtain an initial factor of the given function. Returns the number of conjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise. The conjuncts produced by this procedure tend to be imbalanced.]
SideEffects [The factors are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the conjuncts are already referenced. If the function returns 0, the array for the conjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]
SeeAlso [Cudd_bddApproxDisjDecomp Cudd_bddIterConjDecomp Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox Cudd_bddSqueeze Cudd_bddLICompaction]
Definition at line 171 of file cuddDecomp.c.
00175 { 00176 DdNode *superset1, *superset2, *glocal, *hlocal; 00177 int nvars = Cudd_SupportSize(dd,f); 00178 00179 /* Find a tentative first factor by overapproximation and minimization. */ 00180 superset1 = Cudd_RemapOverApprox(dd,f,nvars,0,1.0); 00181 if (superset1 == NULL) return(0); 00182 cuddRef(superset1); 00183 superset2 = Cudd_bddSqueeze(dd,f,superset1); 00184 if (superset2 == NULL) { 00185 Cudd_RecursiveDeref(dd,superset1); 00186 return(0); 00187 } 00188 cuddRef(superset2); 00189 Cudd_RecursiveDeref(dd,superset1); 00190 00191 /* Compute the second factor by minimization. */ 00192 hlocal = Cudd_bddLICompaction(dd,f,superset2); 00193 if (hlocal == NULL) { 00194 Cudd_RecursiveDeref(dd,superset2); 00195 return(0); 00196 } 00197 cuddRef(hlocal); 00198 00199 /* Refine the first factor by minimization. If h turns out to be f, this 00200 ** step guarantees that g will be 1. */ 00201 glocal = Cudd_bddLICompaction(dd,superset2,hlocal); 00202 if (glocal == NULL) { 00203 Cudd_RecursiveDeref(dd,superset2); 00204 Cudd_RecursiveDeref(dd,hlocal); 00205 return(0); 00206 } 00207 cuddRef(glocal); 00208 Cudd_RecursiveDeref(dd,superset2); 00209 00210 if (glocal != DD_ONE(dd)) { 00211 if (hlocal != DD_ONE(dd)) { 00212 *conjuncts = ALLOC(DdNode *,2); 00213 if (*conjuncts == NULL) { 00214 Cudd_RecursiveDeref(dd,glocal); 00215 Cudd_RecursiveDeref(dd,hlocal); 00216 dd->errorCode = CUDD_MEMORY_OUT; 00217 return(0); 00218 } 00219 (*conjuncts)[0] = glocal; 00220 (*conjuncts)[1] = hlocal; 00221 return(2); 00222 } else { 00223 Cudd_RecursiveDeref(dd,hlocal); 00224 *conjuncts = ALLOC(DdNode *,1); 00225 if (*conjuncts == NULL) { 00226 Cudd_RecursiveDeref(dd,glocal); 00227 dd->errorCode = CUDD_MEMORY_OUT; 00228 return(0); 00229 } 00230 (*conjuncts)[0] = glocal; 00231 return(1); 00232 } 00233 } else { 00234 Cudd_RecursiveDeref(dd,glocal); 00235 *conjuncts = ALLOC(DdNode *,1); 00236 if (*conjuncts == NULL) { 00237 Cudd_RecursiveDeref(dd,hlocal); 00238 dd->errorCode = CUDD_MEMORY_OUT; 00239 return(0); 00240 } 00241 (*conjuncts)[0] = hlocal; 00242 return(1); 00243 } 00244 00245 } /* end of Cudd_bddApproxConjDecomp */
Function********************************************************************
Synopsis [Performs two-way disjunctive decomposition of a BDD.]
Description [Performs two-way disjunctive decomposition of a BDD. Returns the number of disjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise. The disjuncts produced by this procedure tend to be imbalanced.]
SideEffects [The two disjuncts are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the disjuncts are already referenced. If the function returns 0, the array for the disjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]
SeeAlso [Cudd_bddApproxConjDecomp Cudd_bddIterDisjDecomp Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp]
Definition at line 269 of file cuddDecomp.c.
00273 { 00274 int result, i; 00275 00276 result = Cudd_bddApproxConjDecomp(dd,Cudd_Not(f),disjuncts); 00277 for (i = 0; i < result; i++) { 00278 (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); 00279 } 00280 return(result); 00281 00282 } /* end of Cudd_bddApproxDisjDecomp */
int Cudd_bddBindVar | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Prevents sifting of a variable.]
Description [This function sets a flag to prevent sifting of a variable. Returns 1 if successful; 0 otherwise (i.e., invalid variable index).]
SideEffects [Changes the "bindVar" flag in DdSubtable.]
SeeAlso [Cudd_bddUnbindVar]
Function********************************************************************
Synopsis [Computes the boolean difference of f with respect to x.]
Description [Computes the boolean difference of f with respect to the variable with index x. Returns the BDD of the boolean difference if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 242 of file cuddBddAbs.c.
00246 { 00247 DdNode *res, *var; 00248 00249 /* If the variable is not currently in the manager, f cannot 00250 ** depend on it. 00251 */ 00252 if (x >= manager->size) return(Cudd_Not(DD_ONE(manager))); 00253 var = manager->vars[x]; 00254 00255 do { 00256 manager->reordered = 0; 00257 res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var); 00258 } while (manager->reordered == 1); 00259 00260 return(res); 00261 00262 } /* end of Cudd_bddBooleanDiff */
Function********************************************************************
Synopsis [Computes a vector whose image equals a non-zero function.]
Description [Computes a vector of BDDs whose image equals a non-zero function. The result depends on the variable order. The i-th component of the vector depends only on the first i variables in the order. Each BDD in the vector is not larger than the BDD of the given characteristic function. This function is based on the description of char-to-vect in "Verification of Sequential Machines Using Boolean Functional Vectors" by O. Coudert, C. Berthet and J. C. Madre. Returns a pointer to an array containing the result if successful; NULL otherwise. The size of the array equals the number of variables in the manager. The components of the solution have their reference counts already incremented (unlike the results of most other functions in the package).]
SideEffects [None]
SeeAlso [Cudd_bddConstrain]
Definition at line 506 of file cuddGenCof.c.
00509 { 00510 int i, j; 00511 DdNode **vect; 00512 DdNode *res = NULL; 00513 00514 if (f == Cudd_Not(DD_ONE(dd))) return(NULL); 00515 00516 vect = ALLOC(DdNode *, dd->size); 00517 if (vect == NULL) { 00518 dd->errorCode = CUDD_MEMORY_OUT; 00519 return(NULL); 00520 } 00521 00522 do { 00523 dd->reordered = 0; 00524 for (i = 0; i < dd->size; i++) { 00525 res = cuddBddCharToVect(dd,f,dd->vars[dd->invperm[i]]); 00526 if (res == NULL) { 00527 /* Clean up the vector array in case reordering took place. */ 00528 for (j = 0; j < i; j++) { 00529 Cudd_IterDerefBdd(dd, vect[dd->invperm[j]]); 00530 } 00531 break; 00532 } 00533 cuddRef(res); 00534 vect[dd->invperm[i]] = res; 00535 } 00536 } while (dd->reordered == 1); 00537 if (res == NULL) { 00538 FREE(vect); 00539 return(NULL); 00540 } 00541 return(vect); 00542 00543 } /* end of Cudd_bddCharToVect */
AutomaticEnd Function********************************************************************
Synopsis [Approximates the conjunction of two BDDs f and g.]
Description [Approximates the conjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddAnd]
Definition at line 125 of file cuddClip.c.
00131 { 00132 DdNode *res; 00133 00134 do { 00135 dd->reordered = 0; 00136 res = cuddBddClippingAnd(dd,f,g,maxDepth,direction); 00137 } while (dd->reordered == 1); 00138 return(res); 00139 00140 } /* end of Cudd_bddClippingAnd */
DdNode* Cudd_bddClippingAndAbstract | ( | DdManager * | dd, | |
DdNode * | f, | |||
DdNode * | g, | |||
DdNode * | cube, | |||
int | maxDepth, | |||
int | direction | |||
) |
Function********************************************************************
Synopsis [Approximates the conjunction of two BDDs f and g and simultaneously abstracts the variables in cube.]
Description [Approximates the conjunction of two BDDs f and g and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddAndAbstract Cudd_bddClippingAnd]
Definition at line 159 of file cuddClip.c.
00166 { 00167 DdNode *res; 00168 00169 do { 00170 dd->reordered = 0; 00171 res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction); 00172 } while (dd->reordered == 1); 00173 return(res); 00174 00175 } /* end of Cudd_bddClippingAndAbstract */
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 */
AutomaticEnd Function********************************************************************
Synopsis [Substitutes g for x_v in the BDD for f.]
Description [Substitutes g for x_v in the BDD for f. v is the index of the variable to be substituted. Cudd_bddCompose passes the corresponding projection function to the recursive procedure, so that the cache may be used. Returns the composed BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addCompose]
Definition at line 163 of file cuddCompose.c.
00168 { 00169 DdNode *proj, *res; 00170 00171 /* Sanity check. */ 00172 if (v < 0 || v >= dd->size) return(NULL); 00173 00174 proj = dd->vars[v]; 00175 do { 00176 dd->reordered = 0; 00177 res = cuddBddComposeRecur(dd,f,g,proj); 00178 } while (dd->reordered == 1); 00179 return(res); 00180 00181 } /* end of Cudd_bddCompose */
Function********************************************************************
Synopsis [Computes the cube of an array of BDD variables.]
Description [Computes the cube of an array of BDD variables. If non-null, the phase argument indicates which literal of each variable should appear in the cube. If phase\[i\] is nonzero, then the positive literal is used. If phase is NULL, the cube is positive unate. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addComputeCube Cudd_IndicesToCube Cudd_CubeArrayToBdd]
Definition at line 2192 of file cuddUtil.c.
02197 { 02198 DdNode *cube; 02199 DdNode *fn; 02200 int i; 02201 02202 cube = DD_ONE(dd); 02203 cuddRef(cube); 02204 02205 for (i = n - 1; i >= 0; i--) { 02206 if (phase == NULL || phase[i] != 0) { 02207 fn = Cudd_bddAnd(dd,vars[i],cube); 02208 } else { 02209 fn = Cudd_bddAnd(dd,Cudd_Not(vars[i]),cube); 02210 } 02211 if (fn == NULL) { 02212 Cudd_RecursiveDeref(dd,cube); 02213 return(NULL); 02214 } 02215 cuddRef(fn); 02216 Cudd_RecursiveDeref(dd,cube); 02217 cube = fn; 02218 } 02219 cuddDeref(cube); 02220 02221 return(cube); 02222 02223 } /* end of Cudd_bddComputeCube */
AutomaticEnd Function********************************************************************
Synopsis [Computes f constrain c.]
Description [Computes f constrain c (f @ c). Uses a canonical form: (f' @ c) = ( f @ c)'. (Note: this is not true for c.) List of special cases:
Returns a pointer to the result if successful; NULL otherwise. Note that if F=(f1,...,fn) and reordering takes place while computing F @ c, then the image restriction property (Img(F,c) = Img(F @ c)) is lost.]
SideEffects [None]
SeeAlso [Cudd_bddRestrict Cudd_addConstrain]
Definition at line 176 of file cuddGenCof.c.
00180 { 00181 DdNode *res; 00182 00183 do { 00184 dd->reordered = 0; 00185 res = cuddBddConstrainRecur(dd,f,c); 00186 } while (dd->reordered == 1); 00187 return(res); 00188 00189 } /* end of Cudd_bddConstrain */
Function********************************************************************
Synopsis [BDD conjunctive decomposition as in McMillan's CAV96 paper.]
Description [BDD conjunctive decomposition as in McMillan's CAV96 paper. The decomposition is canonical only for a given variable order. If canonicity is required, variable ordering must be disabled after the decomposition has been computed. Returns an array with one entry for each BDD variable in the manager if successful; otherwise NULL. The components of the solution have their reference counts already incremented (unlike the results of most other functions in the package.]
SideEffects [None]
SeeAlso [Cudd_bddConstrain Cudd_bddExistAbstract]
Definition at line 367 of file cuddGenCof.c.
00370 { 00371 DdNode **decomp; 00372 int res; 00373 int i; 00374 00375 /* Create an initialize decomposition array. */ 00376 decomp = ALLOC(DdNode *,dd->size); 00377 if (decomp == NULL) { 00378 dd->errorCode = CUDD_MEMORY_OUT; 00379 return(NULL); 00380 } 00381 for (i = 0; i < dd->size; i++) { 00382 decomp[i] = NULL; 00383 } 00384 do { 00385 dd->reordered = 0; 00386 /* Clean up the decomposition array in case reordering took place. */ 00387 for (i = 0; i < dd->size; i++) { 00388 if (decomp[i] != NULL) { 00389 Cudd_IterDerefBdd(dd, decomp[i]); 00390 decomp[i] = NULL; 00391 } 00392 } 00393 res = cuddBddConstrainDecomp(dd,f,decomp); 00394 } while (dd->reordered == 1); 00395 if (res == 0) { 00396 FREE(decomp); 00397 return(NULL); 00398 } 00399 /* Missing components are constant ones. */ 00400 for (i = 0; i < dd->size; i++) { 00401 if (decomp[i] == NULL) { 00402 decomp[i] = DD_ONE(dd); 00403 cuddRef(decomp[i]); 00404 } 00405 } 00406 return(decomp); 00407 00408 } /* end of Cudd_bddConstrainDecomp */
AutomaticEnd Function********************************************************************
Synopsis [Computes the correlation of f and g.]
Description [Computes the correlation of f and g. If f == g, their correlation is 1. If f == g', their correlation is 0. Returns the fraction of minterms in the ON-set of the EXNOR of f and g. If it runs out of memory, returns (double)CUDD_OUT_OF_MEM.]
SideEffects [None]
SeeAlso [Cudd_bddCorrelationWeights]
Definition at line 143 of file cuddBddCorr.c.
00147 { 00148 00149 st_table *table; 00150 double correlation; 00151 00152 #ifdef CORREL_STATS 00153 num_calls = 0; 00154 #endif 00155 00156 table = st_init_table(CorrelCompare,CorrelHash); 00157 if (table == NULL) return((double)CUDD_OUT_OF_MEM); 00158 correlation = bddCorrelationAux(manager,f,g,table); 00159 st_foreach(table, CorrelCleanUp, NIL(char)); 00160 st_free_table(table); 00161 return(correlation); 00162 00163 } /* end of Cudd_bddCorrelation */
Function********************************************************************
Synopsis [Computes the correlation of f and g for given input probabilities.]
Description [Computes the correlation of f and g for given input probabilities. On input, prob\[i\] is supposed to contain the probability of the i-th input variable to be 1. If f == g, their correlation is 1. If f == g', their correlation is 0. Returns the probability that f and g have the same value. If it runs out of memory, returns (double)CUDD_OUT_OF_MEM. The correlation of f and the constant one gives the probability of f.]
SideEffects [None]
SeeAlso [Cudd_bddCorrelation]
Definition at line 185 of file cuddBddCorr.c.
00190 { 00191 00192 st_table *table; 00193 double correlation; 00194 00195 #ifdef CORREL_STATS 00196 num_calls = 0; 00197 #endif 00198 00199 table = st_init_table(CorrelCompare,CorrelHash); 00200 if (table == NULL) return((double)CUDD_OUT_OF_MEM); 00201 correlation = bddCorrelationWeightsAux(manager,f,g,prob,table); 00202 st_foreach(table, CorrelCleanUp, NIL(char)); 00203 st_free_table(table); 00204 return(correlation); 00205 00206 } /* end of Cudd_bddCorrelationWeights */
AutomaticEnd Function********************************************************************
Synopsis [Existentially abstracts all the variables in cube from f.]
Description [Existentially abstracts all the variables in cube from f. Returns the abstracted BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddUnivAbstract Cudd_addExistAbstract]
Definition at line 126 of file cuddBddAbs.c.
00130 { 00131 DdNode *res; 00132 00133 if (bddCheckPositiveCube(manager, cube) == 0) { 00134 (void) fprintf(manager->err, 00135 "Error: Can only abstract positive cubes\n"); 00136 manager->errorCode = CUDD_INVALID_ARG; 00137 return(NULL); 00138 } 00139 00140 do { 00141 manager->reordered = 0; 00142 res = cuddBddExistAbstractRecur(manager, f, cube); 00143 } while (manager->reordered == 1); 00144 00145 return(res); 00146 00147 } /* end of Cudd_bddExistAbstract */
Function********************************************************************
Synopsis [Performs two-way conjunctive decomposition of a BDD.]
Description [Performs two-way conjunctive decomposition of a BDD. This procedure owes its name to the fact tht it generalizes the decomposition based on the cofactors with respect to one variable. Returns the number of conjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise. The conjuncts produced by this procedure tend to be balanced.]
SideEffects [The two factors are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the conjuncts are already referenced. If the function returns 0, the array for the conjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]
SeeAlso [Cudd_bddGenDisjDecomp Cudd_bddApproxConjDecomp Cudd_bddIterConjDecomp Cudd_bddVarConjDecomp]
Definition at line 492 of file cuddDecomp.c.
00496 { 00497 int result; 00498 DdNode *glocal, *hlocal; 00499 00500 one = DD_ONE(dd); 00501 zero = Cudd_Not(one); 00502 00503 do { 00504 dd->reordered = 0; 00505 result = cuddConjunctsAux(dd, f, &glocal, &hlocal); 00506 } while (dd->reordered == 1); 00507 00508 if (result == 0) { 00509 return(0); 00510 } 00511 00512 if (glocal != one) { 00513 if (hlocal != one) { 00514 *conjuncts = ALLOC(DdNode *,2); 00515 if (*conjuncts == NULL) { 00516 Cudd_RecursiveDeref(dd,glocal); 00517 Cudd_RecursiveDeref(dd,hlocal); 00518 dd->errorCode = CUDD_MEMORY_OUT; 00519 return(0); 00520 } 00521 (*conjuncts)[0] = glocal; 00522 (*conjuncts)[1] = hlocal; 00523 return(2); 00524 } else { 00525 Cudd_RecursiveDeref(dd,hlocal); 00526 *conjuncts = ALLOC(DdNode *,1); 00527 if (*conjuncts == NULL) { 00528 Cudd_RecursiveDeref(dd,glocal); 00529 dd->errorCode = CUDD_MEMORY_OUT; 00530 return(0); 00531 } 00532 (*conjuncts)[0] = glocal; 00533 return(1); 00534 } 00535 } else { 00536 Cudd_RecursiveDeref(dd,glocal); 00537 *conjuncts = ALLOC(DdNode *,1); 00538 if (*conjuncts == NULL) { 00539 Cudd_RecursiveDeref(dd,hlocal); 00540 dd->errorCode = CUDD_MEMORY_OUT; 00541 return(0); 00542 } 00543 (*conjuncts)[0] = hlocal; 00544 return(1); 00545 } 00546 00547 } /* end of Cudd_bddGenConjDecomp */
Function********************************************************************
Synopsis [Performs two-way disjunctive decomposition of a BDD.]
Description [Performs two-way disjunctive decomposition of a BDD. Returns the number of disjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise. The disjuncts produced by this procedure tend to be balanced.]
SideEffects [The two disjuncts are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the disjuncts are already referenced. If the function returns 0, the array for the disjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]
SeeAlso [Cudd_bddGenConjDecomp Cudd_bddApproxDisjDecomp Cudd_bddIterDisjDecomp Cudd_bddVarDisjDecomp]
Definition at line 571 of file cuddDecomp.c.
00575 { 00576 int result, i; 00577 00578 result = Cudd_bddGenConjDecomp(dd,Cudd_Not(f),disjuncts); 00579 for (i = 0; i < result; i++) { 00580 (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); 00581 } 00582 return(result); 00583 00584 } /* end of Cudd_bddGenDisjDecomp */
Function********************************************************************
Synopsis [Returns a function included in the intersection of f and g.]
Description [Computes a function included in the intersection of f and g. (That is, a witness that the intersection is not empty.) Cudd_bddIntersect tries to build as few new nodes as possible. If the only result of interest is whether f and g intersect, Cudd_bddLeq should be used instead.]
SideEffects [None]
SeeAlso [Cudd_bddLeq Cudd_bddIteConstant]
Definition at line 278 of file cuddBddIte.c.
00282 { 00283 DdNode *res; 00284 00285 do { 00286 dd->reordered = 0; 00287 res = cuddBddIntersectRecur(dd,f,g); 00288 } while (dd->reordered == 1); 00289 00290 return(res); 00291 00292 } /* end of Cudd_bddIntersect */
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 */
int Cudd_bddIsNsVar | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Checks whether a variable is next state.]
Description [Checks whether a variable is next state. Returns 1 if the variable's type is present state; 0 if the variable exists but is not a present state; -1 if the variable does not exist.]
SideEffects [none]
SeeAlso [Cudd_bddSetNsVar Cudd_bddIsPiVar Cudd_bddIsPsVar]
Definition at line 4095 of file cuddAPI.c.
04098 { 04099 if (index >= dd->size || index < 0) return -1; 04100 return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_NEXT_STATE); 04101 04102 } /* end of Cudd_bddIsNsVar */
Function********************************************************************
Synopsis [Computes a BDD in the interval between L and U with a simple sum-of-produuct cover.]
Description [Computes a BDD in the interval between L and U with a simple sum-of-produuct cover. This procedure is similar to Cudd_zddIsop, but it does not return the ZDD for the cover. Returns a pointer to the BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddIsop]
Definition at line 170 of file cuddZddIsop.c.
00174 { 00175 DdNode *res; 00176 00177 do { 00178 dd->reordered = 0; 00179 res = cuddBddIsop(dd, L, U); 00180 } while (dd->reordered == 1); 00181 return(res); 00182 00183 } /* end of Cudd_bddIsop */
int Cudd_bddIsPiVar | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Checks whether a variable is primary input.]
Description [Checks whether a variable is primary input. Returns 1 if the variable's type is primary input; 0 if the variable exists but is not a primary input; -1 if the variable does not exist.]
SideEffects [none]
SeeAlso [Cudd_bddSetPiVar Cudd_bddIsPsVar Cudd_bddIsNsVar]
Definition at line 4047 of file cuddAPI.c.
04050 { 04051 if (index >= dd->size || index < 0) return -1; 04052 return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRIMARY_INPUT); 04053 04054 } /* end of Cudd_bddIsPiVar */
int Cudd_bddIsPsVar | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Checks whether a variable is present state.]
Description [Checks whether a variable is present state. Returns 1 if the variable's type is present state; 0 if the variable exists but is not a present state; -1 if the variable does not exist.]
SideEffects [none]
SeeAlso [Cudd_bddSetPsVar Cudd_bddIsPiVar Cudd_bddIsNsVar]
Definition at line 4071 of file cuddAPI.c.
04074 { 04075 if (index >= dd->size || index < 0) return -1; 04076 return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRESENT_STATE); 04077 04078 } /* end of Cudd_bddIsPsVar */
Function********************************************************************
Synopsis [Determines whether a given variable is essential with a given phase in a BDD.]
Description [Determines whether a given variable is essential with a given phase in a BDD. Uses Cudd_bddIteConstant. Returns 1 if phase == 1 and f-->x_id, or if phase == 0 and f-->x_id'.]
SideEffects [None]
SeeAlso [Cudd_FindEssential]
Definition at line 235 of file cuddEssent.c.
00240 { 00241 DdNode *var; 00242 int res; 00243 00244 var = Cudd_bddIthVar(manager, id); 00245 00246 var = Cudd_NotCond(var,phase == 0); 00247 00248 res = Cudd_bddLeq(manager, f, var); 00249 00250 return(res); 00251 00252 } /* end of Cudd_bddIsVarEssential */
int Cudd_bddIsVarHardGroup | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Checks whether a variable is set to be in a hard group.]
Description [Checks whether a variable is set to be in a hard group. This function is used for lazy sifting. Returns 1 if the variable is marked to be in a hard group; 0 if the variable exists, but it is not marked to be in a hard group; -1 if the variable does not exist.]
SideEffects [none]
SeeAlso [Cudd_bddSetVarHardGroup]
Definition at line 4323 of file cuddAPI.c.
04326 { 04327 if (index >= dd->size || index < 0) return(-1); 04328 if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_HARD_GROUP) 04329 return(1); 04330 return(0); 04331 04332 } /* end of Cudd_bddIsVarToBeGrouped */
int Cudd_bddIsVarToBeGrouped | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Checks whether a variable is set to be grouped.]
Description [Checks whether a variable is set to be grouped. This function is used for lazy sifting.]
SideEffects [none]
SeeAlso []
Definition at line 4246 of file cuddAPI.c.
04249 { 04250 if (index >= dd->size || index < 0) return(-1); 04251 if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP) 04252 return(0); 04253 else 04254 return(dd->subtables[dd->perm[index]].varToBeGrouped); 04255 04256 } /* end of Cudd_bddIsVarToBeGrouped */
int Cudd_bddIsVarToBeUngrouped | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Checks whether a variable is set to be ungrouped.]
Description [Checks whether a variable is set to be ungrouped. This function is used for lazy sifting. Returns 1 if the variable is marked to be ungrouped; 0 if the variable exists, but it is not marked to be ungrouped; -1 if the variable does not exist.]
SideEffects [none]
SeeAlso [Cudd_bddSetVarToBeUngrouped]
Definition at line 4298 of file cuddAPI.c.
04301 { 04302 if (index >= dd->size || index < 0) return(-1); 04303 return dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP; 04304 04305 } /* end of Cudd_bddIsVarToBeGrouped */
AutomaticEnd Function********************************************************************
Synopsis [Implements ITE(f,g,h).]
Description [Implements ITE(f,g,h). Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_addIte Cudd_bddIteConstant Cudd_bddIntersect]
Definition at line 139 of file cuddBddIte.c.
00144 { 00145 DdNode *res; 00146 00147 do { 00148 dd->reordered = 0; 00149 res = cuddBddIteRecur(dd,f,g,h); 00150 } while (dd->reordered == 1); 00151 return(res); 00152 00153 } /* end of Cudd_bddIte */
Function********************************************************************
Synopsis [Implements ITEconstant(f,g,h).]
Description [Implements ITEconstant(f,g,h). Returns a pointer to the resulting BDD (which may or may not be constant) or DD_NON_CONSTANT. No new nodes are created.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_bddIntersect Cudd_bddLeq Cudd_addIteConstant]
Definition at line 170 of file cuddBddIte.c.
00175 { 00176 DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; 00177 DdNode *one = DD_ONE(dd); 00178 DdNode *zero = Cudd_Not(one); 00179 int comple; 00180 unsigned int topf, topg, toph, v; 00181 00182 statLine(dd); 00183 /* Trivial cases. */ 00184 if (f == one) /* ITE(1,G,H) => G */ 00185 return(g); 00186 00187 if (f == zero) /* ITE(0,G,H) => H */ 00188 return(h); 00189 00190 /* f now not a constant. */ 00191 bddVarToConst(f, &g, &h, one); /* possibly convert g or h */ 00192 /* to constants */ 00193 00194 if (g == h) /* ITE(F,G,G) => G */ 00195 return(g); 00196 00197 if (Cudd_IsConstant(g) && Cudd_IsConstant(h)) 00198 return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */ 00199 /* => DD_NON_CONSTANT */ 00200 00201 if (g == Cudd_Not(h)) 00202 return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */ 00203 /* if F != G and F != G' */ 00204 00205 comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph); 00206 00207 /* Cache lookup. */ 00208 r = cuddConstantLookup(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h); 00209 if (r != NULL) { 00210 return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT)); 00211 } 00212 00213 v = ddMin(topg, toph); 00214 00215 /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */ 00216 if (topf < v && cuddT(f) == one && cuddE(f) == zero) { 00217 return(DD_NON_CONSTANT); 00218 } 00219 00220 /* Compute cofactors. */ 00221 if (topf <= v) { 00222 v = ddMin(topf, v); /* v = top_var(F,G,H) */ 00223 Fv = cuddT(f); Fnv = cuddE(f); 00224 } else { 00225 Fv = Fnv = f; 00226 } 00227 00228 if (topg == v) { 00229 Gv = cuddT(g); Gnv = cuddE(g); 00230 } else { 00231 Gv = Gnv = g; 00232 } 00233 00234 if (toph == v) { 00235 H = Cudd_Regular(h); 00236 Hv = cuddT(H); Hnv = cuddE(H); 00237 if (Cudd_IsComplement(h)) { 00238 Hv = Cudd_Not(Hv); 00239 Hnv = Cudd_Not(Hnv); 00240 } 00241 } else { 00242 Hv = Hnv = h; 00243 } 00244 00245 /* Recursion. */ 00246 t = Cudd_bddIteConstant(dd, Fv, Gv, Hv); 00247 if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) { 00248 cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); 00249 return(DD_NON_CONSTANT); 00250 } 00251 e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv); 00252 if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) { 00253 cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); 00254 return(DD_NON_CONSTANT); 00255 } 00256 cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t); 00257 return(Cudd_NotCond(t,comple)); 00258 00259 } /* end of Cudd_bddIteConstant */
Function********************************************************************
Synopsis [Performs two-way conjunctive decomposition of a BDD.]
Description [Performs two-way conjunctive decomposition of a BDD. This procedure owes its name to the iterated use of supersetting to obtain a factor of the given function. Returns the number of conjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise. The conjuncts produced by this procedure tend to be imbalanced.]
SideEffects [The factors are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the conjuncts are already referenced. If the function returns 0, the array for the conjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]
SeeAlso [Cudd_bddIterDisjDecomp Cudd_bddApproxConjDecomp Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox Cudd_bddSqueeze Cudd_bddLICompaction]
Definition at line 309 of file cuddDecomp.c.
00313 { 00314 DdNode *superset1, *superset2, *old[2], *res[2]; 00315 int sizeOld, sizeNew; 00316 int nvars = Cudd_SupportSize(dd,f); 00317 00318 old[0] = DD_ONE(dd); 00319 cuddRef(old[0]); 00320 old[1] = f; 00321 cuddRef(old[1]); 00322 sizeOld = Cudd_SharingSize(old,2); 00323 00324 do { 00325 /* Find a tentative first factor by overapproximation and 00326 ** minimization. */ 00327 superset1 = Cudd_RemapOverApprox(dd,old[1],nvars,0,1.0); 00328 if (superset1 == NULL) { 00329 Cudd_RecursiveDeref(dd,old[0]); 00330 Cudd_RecursiveDeref(dd,old[1]); 00331 return(0); 00332 } 00333 cuddRef(superset1); 00334 superset2 = Cudd_bddSqueeze(dd,old[1],superset1); 00335 if (superset2 == NULL) { 00336 Cudd_RecursiveDeref(dd,old[0]); 00337 Cudd_RecursiveDeref(dd,old[1]); 00338 Cudd_RecursiveDeref(dd,superset1); 00339 return(0); 00340 } 00341 cuddRef(superset2); 00342 Cudd_RecursiveDeref(dd,superset1); 00343 res[0] = Cudd_bddAnd(dd,old[0],superset2); 00344 if (res[0] == NULL) { 00345 Cudd_RecursiveDeref(dd,superset2); 00346 Cudd_RecursiveDeref(dd,old[0]); 00347 Cudd_RecursiveDeref(dd,old[1]); 00348 return(0); 00349 } 00350 cuddRef(res[0]); 00351 Cudd_RecursiveDeref(dd,superset2); 00352 if (res[0] == old[0]) { 00353 Cudd_RecursiveDeref(dd,res[0]); 00354 break; /* avoid infinite loop */ 00355 } 00356 00357 /* Compute the second factor by minimization. */ 00358 res[1] = Cudd_bddLICompaction(dd,old[1],res[0]); 00359 if (res[1] == NULL) { 00360 Cudd_RecursiveDeref(dd,old[0]); 00361 Cudd_RecursiveDeref(dd,old[1]); 00362 return(0); 00363 } 00364 cuddRef(res[1]); 00365 00366 sizeNew = Cudd_SharingSize(res,2); 00367 if (sizeNew <= sizeOld) { 00368 Cudd_RecursiveDeref(dd,old[0]); 00369 old[0] = res[0]; 00370 Cudd_RecursiveDeref(dd,old[1]); 00371 old[1] = res[1]; 00372 sizeOld = sizeNew; 00373 } else { 00374 Cudd_RecursiveDeref(dd,res[0]); 00375 Cudd_RecursiveDeref(dd,res[1]); 00376 break; 00377 } 00378 00379 } while (1); 00380 00381 /* Refine the first factor by minimization. If h turns out to 00382 ** be f, this step guarantees that g will be 1. */ 00383 superset1 = Cudd_bddLICompaction(dd,old[0],old[1]); 00384 if (superset1 == NULL) { 00385 Cudd_RecursiveDeref(dd,old[0]); 00386 Cudd_RecursiveDeref(dd,old[1]); 00387 return(0); 00388 } 00389 cuddRef(superset1); 00390 Cudd_RecursiveDeref(dd,old[0]); 00391 old[0] = superset1; 00392 00393 if (old[0] != DD_ONE(dd)) { 00394 if (old[1] != DD_ONE(dd)) { 00395 *conjuncts = ALLOC(DdNode *,2); 00396 if (*conjuncts == NULL) { 00397 Cudd_RecursiveDeref(dd,old[0]); 00398 Cudd_RecursiveDeref(dd,old[1]); 00399 dd->errorCode = CUDD_MEMORY_OUT; 00400 return(0); 00401 } 00402 (*conjuncts)[0] = old[0]; 00403 (*conjuncts)[1] = old[1]; 00404 return(2); 00405 } else { 00406 Cudd_RecursiveDeref(dd,old[1]); 00407 *conjuncts = ALLOC(DdNode *,1); 00408 if (*conjuncts == NULL) { 00409 Cudd_RecursiveDeref(dd,old[0]); 00410 dd->errorCode = CUDD_MEMORY_OUT; 00411 return(0); 00412 } 00413 (*conjuncts)[0] = old[0]; 00414 return(1); 00415 } 00416 } else { 00417 Cudd_RecursiveDeref(dd,old[0]); 00418 *conjuncts = ALLOC(DdNode *,1); 00419 if (*conjuncts == NULL) { 00420 Cudd_RecursiveDeref(dd,old[1]); 00421 dd->errorCode = CUDD_MEMORY_OUT; 00422 return(0); 00423 } 00424 (*conjuncts)[0] = old[1]; 00425 return(1); 00426 } 00427 00428 } /* end of Cudd_bddIterConjDecomp */
Function********************************************************************
Synopsis [Performs two-way disjunctive decomposition of a BDD.]
Description [Performs two-way disjunctive decomposition of a BDD. Returns the number of disjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise. The disjuncts produced by this procedure tend to be imbalanced.]
SideEffects [The two disjuncts are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the disjuncts are already referenced. If the function returns 0, the array for the disjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]
SeeAlso [Cudd_bddIterConjDecomp Cudd_bddApproxDisjDecomp Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp]
Definition at line 452 of file cuddDecomp.c.
00456 { 00457 int result, i; 00458 00459 result = Cudd_bddIterConjDecomp(dd,Cudd_Not(f),disjuncts); 00460 for (i = 0; i < result; i++) { 00461 (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); 00462 } 00463 return(result); 00464 00465 } /* end of Cudd_bddIterDisjDecomp */
Function********************************************************************
Synopsis [Returns the BDD variable with index i.]
Description [Retrieves the BDD variable with index i if it already exists, or creates a new BDD variable. Returns a pointer to the variable if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel Cudd_ReadVars]
Definition at line 412 of file cuddAPI.c.
00415 { 00416 DdNode *res; 00417 00418 if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); 00419 if (i < dd->size) { 00420 res = dd->vars[i]; 00421 } else { 00422 res = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); 00423 } 00424 00425 return(res); 00426 00427 } /* end of Cudd_bddIthVar */
Function********************************************************************
Synopsis [Determines whether f is less than or equal to g.]
Description [Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are created.]
SideEffects [None]
SeeAlso [Cudd_bddIteConstant Cudd_addEvalConst]
Definition at line 532 of file cuddBddIte.c.
00536 { 00537 DdNode *one, *zero, *tmp, *F, *fv, *fvn, *gv, *gvn; 00538 unsigned int topf, topg, res; 00539 00540 statLine(dd); 00541 /* Terminal cases and normalization. */ 00542 if (f == g) return(1); 00543 00544 if (Cudd_IsComplement(g)) { 00545 /* Special case: if f is regular and g is complemented, 00546 ** f(1,...,1) = 1 > 0 = g(1,...,1). 00547 */ 00548 if (!Cudd_IsComplement(f)) return(0); 00549 /* Both are complemented: Swap and complement because 00550 ** f <= g <=> g' <= f' and we want the second argument to be regular. 00551 */ 00552 tmp = g; 00553 g = Cudd_Not(f); 00554 f = Cudd_Not(tmp); 00555 } else if (Cudd_IsComplement(f) && g < f) { 00556 tmp = g; 00557 g = Cudd_Not(f); 00558 f = Cudd_Not(tmp); 00559 } 00560 00561 /* Now g is regular and, if f is not regular, f < g. */ 00562 one = DD_ONE(dd); 00563 if (g == one) return(1); /* no need to test against zero */ 00564 if (f == one) return(0); /* since at this point g != one */ 00565 if (Cudd_Not(f) == g) return(0); /* because neither is constant */ 00566 zero = Cudd_Not(one); 00567 if (f == zero) return(1); 00568 00569 /* Here neither f nor g is constant. */ 00570 00571 /* Check cache. */ 00572 tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g); 00573 if (tmp != NULL) { 00574 return(tmp == one); 00575 } 00576 00577 /* Compute cofactors. */ 00578 F = Cudd_Regular(f); 00579 topf = dd->perm[F->index]; 00580 topg = dd->perm[g->index]; 00581 if (topf <= topg) { 00582 fv = cuddT(F); fvn = cuddE(F); 00583 if (f != F) { 00584 fv = Cudd_Not(fv); 00585 fvn = Cudd_Not(fvn); 00586 } 00587 } else { 00588 fv = fvn = f; 00589 } 00590 if (topg <= topf) { 00591 gv = cuddT(g); gvn = cuddE(g); 00592 } else { 00593 gv = gvn = g; 00594 } 00595 00596 /* Recursive calls. Since we want to maximize the probability of 00597 ** the special case f(1,...,1) > g(1,...,1), we consider the negative 00598 ** cofactors first. Indeed, the complementation parity of the positive 00599 ** cofactors is the same as the one of the parent functions. 00600 */ 00601 res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv); 00602 00603 /* Store result in cache and return. */ 00604 cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero)); 00605 return(res); 00606 00607 } /* end of Cudd_bddLeq */
Function********************************************************************
Synopsis [Tells whether f is less than of equal to G unless D is 1.]
Description [Tells whether f is less than of equal to G unless D is 1. f, g, and D are BDDs. The function returns 1 if f is less than of equal to G, and 0 otherwise. No new nodes are created.]
SideEffects [None]
SeeAlso [Cudd_EquivDC Cudd_bddLeq Cudd_bddIteConstant]
Definition at line 618 of file cuddSat.c.
00623 { 00624 DdNode *tmp, *One, *F, *G; 00625 DdNode *Ft, *Fe, *Gt, *Ge, *Dt, *De; 00626 int res; 00627 unsigned int flevel, glevel, dlevel, top; 00628 00629 statLine(dd); 00630 00631 One = DD_ONE(dd); 00632 00633 /* Check terminal cases. */ 00634 if (f == g || g == One || f == Cudd_Not(One) || D == One || 00635 D == f || D == Cudd_Not(g)) return(1); 00636 /* Check for two-operand cases. */ 00637 if (D == Cudd_Not(One) || D == g || D == Cudd_Not(f)) 00638 return(Cudd_bddLeq(dd,f,g)); 00639 if (g == Cudd_Not(One) || g == Cudd_Not(f)) return(Cudd_bddLeq(dd,f,D)); 00640 if (f == One) return(Cudd_bddLeq(dd,Cudd_Not(g),D)); 00641 00642 /* From now on, f, g, and D are non-constant, distinct, and 00643 ** non-complementary. */ 00644 00645 /* Normalize call to increase cache efficiency. We rely on the 00646 ** fact that f <= g unless D is equivalent to not(g) <= not(f) 00647 ** unless D and to f <= D unless g. We make sure that D is 00648 ** regular, and that at most one of f and g is complemented. We also 00649 ** ensure that when two operands can be swapped, the one with the 00650 ** lowest address comes first. */ 00651 00652 if (Cudd_IsComplement(D)) { 00653 if (Cudd_IsComplement(g)) { 00654 /* Special case: if f is regular and g is complemented, 00655 ** f(1,...,1) = 1 > 0 = g(1,...,1). If D(1,...,1) = 0, return 0. 00656 */ 00657 if (!Cudd_IsComplement(f)) return(0); 00658 /* !g <= D unless !f or !D <= g unless !f */ 00659 tmp = D; 00660 D = Cudd_Not(f); 00661 if (g < tmp) { 00662 f = Cudd_Not(g); 00663 g = tmp; 00664 } else { 00665 f = Cudd_Not(tmp); 00666 } 00667 } else { 00668 if (Cudd_IsComplement(f)) { 00669 /* !D <= !f unless g or !D <= g unless !f */ 00670 tmp = f; 00671 f = Cudd_Not(D); 00672 if (tmp < g) { 00673 D = g; 00674 g = Cudd_Not(tmp); 00675 } else { 00676 D = Cudd_Not(tmp); 00677 } 00678 } else { 00679 /* f <= D unless g or !D <= !f unless g */ 00680 tmp = D; 00681 D = g; 00682 if (tmp < f) { 00683 g = Cudd_Not(f); 00684 f = Cudd_Not(tmp); 00685 } else { 00686 g = tmp; 00687 } 00688 } 00689 } 00690 } else { 00691 if (Cudd_IsComplement(g)) { 00692 if (Cudd_IsComplement(f)) { 00693 /* !g <= !f unless D or !g <= D unless !f */ 00694 tmp = f; 00695 f = Cudd_Not(g); 00696 if (D < tmp) { 00697 g = D; 00698 D = Cudd_Not(tmp); 00699 } else { 00700 g = Cudd_Not(tmp); 00701 } 00702 } else { 00703 /* f <= g unless D or !g <= !f unless D */ 00704 if (g < f) { 00705 tmp = g; 00706 g = Cudd_Not(f); 00707 f = Cudd_Not(tmp); 00708 } 00709 } 00710 } else { 00711 /* f <= g unless D or f <= D unless g */ 00712 if (D < g) { 00713 tmp = D; 00714 D = g; 00715 g = tmp; 00716 } 00717 } 00718 } 00719 00720 /* From now on, D is regular. */ 00721 00722 /* Check cache. */ 00723 tmp = cuddCacheLookup(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D); 00724 if (tmp != NULL) return(tmp == One); 00725 00726 /* Find splitting variable. */ 00727 F = Cudd_Regular(f); 00728 flevel = dd->perm[F->index]; 00729 G = Cudd_Regular(g); 00730 glevel = dd->perm[G->index]; 00731 top = ddMin(flevel,glevel); 00732 dlevel = dd->perm[D->index]; 00733 top = ddMin(top,dlevel); 00734 00735 /* Compute cofactors. */ 00736 if (top == flevel) { 00737 Ft = cuddT(F); 00738 Fe = cuddE(F); 00739 if (F != f) { 00740 Ft = Cudd_Not(Ft); 00741 Fe = Cudd_Not(Fe); 00742 } 00743 } else { 00744 Ft = Fe = f; 00745 } 00746 if (top == glevel) { 00747 Gt = cuddT(G); 00748 Ge = cuddE(G); 00749 if (G != g) { 00750 Gt = Cudd_Not(Gt); 00751 Ge = Cudd_Not(Ge); 00752 } 00753 } else { 00754 Gt = Ge = g; 00755 } 00756 if (top == dlevel) { 00757 Dt = cuddT(D); 00758 De = cuddE(D); 00759 } else { 00760 Dt = De = D; 00761 } 00762 00763 /* Solve recursively. */ 00764 res = Cudd_bddLeqUnless(dd,Ft,Gt,Dt); 00765 if (res != 0) { 00766 res = Cudd_bddLeqUnless(dd,Fe,Ge,De); 00767 } 00768 cuddCacheInsert(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D,Cudd_NotCond(One,!res)); 00769 00770 return(res); 00771 00772 } /* end of Cudd_bddLeqUnless */
Function********************************************************************
Synopsis [Performs safe minimization of a BDD.]
Description [Performs safe minimization of a BDD. Given the BDD f
of a function to be minimized and a BDD c
representing the care set, Cudd_bddLICompaction produces the BDD of a function that agrees with f
wherever c
is 1. Safe minimization means that the size of the result is guaranteed not to exceed the size of f
. This function is based on the DAC97 paper by Hong et al.. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddRestrict]
Definition at line 566 of file cuddGenCof.c.
00570 { 00571 DdNode *res; 00572 00573 do { 00574 dd->reordered = 0; 00575 res = cuddBddLICompaction(dd,f,c); 00576 } while (dd->reordered == 1); 00577 return(res); 00578 00579 } /* end of Cudd_bddLICompaction */
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Computes the intesection of two sets of literals represented as BDDs.]
Description [Computes the intesection of two sets of literals represented as BDDs. Each set is represented as a cube of the literals in the set. The empty set is represented by the constant 1. No variable can be simultaneously present in both phases in a set. Returns a pointer to the BDD representing the intersected sets, if successful; NULL otherwise.]
SideEffects [None]
Definition at line 114 of file cuddLiteral.c.
00118 { 00119 DdNode *res; 00120 00121 do { 00122 dd->reordered = 0; 00123 res = cuddBddLiteralSetIntersectionRecur(dd,f,g); 00124 } while (dd->reordered == 1); 00125 return(res); 00126 00127 } /* end of Cudd_bddLiteralSetIntersection */
Function********************************************************************
Synopsis [Expands cube to a prime implicant of f.]
Description [Expands cube to a prime implicant of f. Returns the prime if successful; NULL otherwise. In particular, NULL is returned if cube is not a real cube or is not an implicant of f.]
SideEffects [None]
SeeAlso []
Definition at line 860 of file cuddSat.c.
00864 { 00865 DdNode *res; 00866 00867 if (!Cudd_bddLeq(dd,cube,f)) return(NULL); 00868 00869 do { 00870 dd->reordered = 0; 00871 res = cuddBddMakePrime(dd,cube,f); 00872 } while (dd->reordered == 1); 00873 return(res); 00874 00875 } /* end of Cudd_bddMakePrime */
Function********************************************************************
Synopsis [Finds a small BDD that agrees with f
over c
.]
Description [Finds a small BDD that agrees with f
over c
. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction Cudd_bddSqueeze]
Definition at line 649 of file cuddGenCof.c.
00653 { 00654 DdNode *cplus, *res; 00655 00656 if (c == Cudd_Not(DD_ONE(dd))) return(c); 00657 if (Cudd_IsConstant(f)) return(f); 00658 if (f == c) return(DD_ONE(dd)); 00659 if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd))); 00660 00661 cplus = Cudd_RemapOverApprox(dd,c,0,0,1.0); 00662 if (cplus == NULL) return(NULL); 00663 cuddRef(cplus); 00664 res = Cudd_bddLICompaction(dd,f,cplus); 00665 if (res == NULL) { 00666 Cudd_IterDerefBdd(dd,cplus); 00667 return(NULL); 00668 } 00669 cuddRef(res); 00670 Cudd_IterDerefBdd(dd,cplus); 00671 cuddDeref(res); 00672 return(res); 00673 00674 } /* end of Cudd_bddMinimize */
Function********************************************************************
Synopsis [Computes the NAND of two BDDs f and g.]
Description [Computes the NAND of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNor Cudd_bddXor Cudd_bddXnor]
Definition at line 409 of file cuddBddIte.c.
00413 { 00414 DdNode *res; 00415 00416 do { 00417 dd->reordered = 0; 00418 res = cuddBddAndRecur(dd,f,g); 00419 } while (dd->reordered == 1); 00420 res = Cudd_NotCond(res,res != NULL); 00421 return(res); 00422 00423 } /* end of Cudd_bddNand */
Function********************************************************************
Synopsis [Returns a new BDD variable.]
Description [Creates a new BDD variable. The new variable has an index equal to the largest previous index plus 1. Returns a pointer to the new variable if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel]
Definition at line 319 of file cuddAPI.c.
00321 { 00322 DdNode *res; 00323 00324 if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); 00325 res = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); 00326 00327 return(res); 00328 00329 } /* end of Cudd_bddNewVar */
Function********************************************************************
Synopsis [Returns a new BDD variable at a specified level.]
Description [Creates a new BDD variable. The new variable has an index equal to the largest previous index plus 1 and is positioned at the specified level in the order. Returns a pointer to the new variable if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddNewVar Cudd_bddIthVar Cudd_addNewVarAtLevel]
Definition at line 347 of file cuddAPI.c.
00350 { 00351 DdNode *res; 00352 00353 if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); 00354 if (level >= dd->size) return(Cudd_bddIthVar(dd,level)); 00355 if (!cuddInsertSubtables(dd,1,level)) return(NULL); 00356 res = dd->vars[dd->size - 1]; 00357 00358 return(res); 00359 00360 } /* end of Cudd_bddNewVarAtLevel */
Function********************************************************************
Synopsis [Computes the NOR of two BDDs f and g.]
Description [Computes the NOR of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddXor Cudd_bddXnor]
Definition at line 441 of file cuddBddIte.c.
Function********************************************************************
Synopsis [Computes f non-polluting-and g.]
Description [Computes f non-polluting-and g. The non-polluting AND of f and g is a hybrid of AND and Restrict. From Restrict, this operation takes the idea of existentially quantifying the top variable of the second operand if it does not appear in the first. Therefore, the variables that appear in the result also appear in f. For the rest, the function behaves like AND. Since the two operands play different roles, non-polluting AND is not commutative.
Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddConstrain Cudd_bddRestrict]
Definition at line 295 of file cuddGenCof.c.
00299 { 00300 DdNode *res; 00301 00302 do { 00303 dd->reordered = 0; 00304 res = cuddBddNPAndRecur(dd,f,g); 00305 } while (dd->reordered == 1); 00306 return(res); 00307 00308 } /* end of Cudd_bddNPAnd */
Function********************************************************************
Synopsis [Computes the disjunction of two BDDs f and g.]
Description [Computes the disjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]
Definition at line 377 of file cuddBddIte.c.
00381 { 00382 DdNode *res; 00383 00384 do { 00385 dd->reordered = 0; 00386 res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); 00387 } while (dd->reordered == 1); 00388 res = Cudd_NotCond(res,res != NULL); 00389 return(res); 00390 00391 } /* end of Cudd_bddOr */
Function********************************************************************
Synopsis [Permutes the variables of a BDD.]
Description [Given a permutation in array permut, creates a new BDD with permuted variables. There should be an entry in array permut for each variable in the manager. The i-th entry of permut holds the index of the variable that is to substitute the i-th variable. Returns a pointer to the resulting BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addPermute Cudd_bddSwapVariables]
Definition at line 328 of file cuddCompose.c.
00332 { 00333 DdHashTable *table; 00334 DdNode *res; 00335 00336 do { 00337 manager->reordered = 0; 00338 table = cuddHashTableInit(manager,1,2); 00339 if (table == NULL) return(NULL); 00340 res = cuddBddPermuteRecur(manager,table,node,permut); 00341 if (res != NULL) cuddRef(res); 00342 /* Dispose of local cache. */ 00343 cuddHashTableQuit(table); 00344 00345 } while (manager->reordered == 1); 00346 00347 if (res != NULL) cuddDeref(res); 00348 return(res); 00349 00350 } /* end of Cudd_bddPermute */
Function********************************************************************
Synopsis [Picks k on-set minterms evenly distributed from given DD.]
Description [Picks k on-set minterms evenly distributed from given DD. The minterms are in terms of vars
. The array vars
should contain at least all variables in the support of f
; if this condition is not met the minterms built by this procedure may not be contained in f
. Builds an array of BDDs for the minterms and returns a pointer to it if successful; NULL otherwise. There are three reasons why the procedure may fail:
f
may be the constant 0; f
. ]
SideEffects [None]
SeeAlso [Cudd_bddPickOneMinterm Cudd_bddPickOneCube]
Definition at line 1389 of file cuddUtil.c.
01395 { 01396 char **string; 01397 int i, j, l, size; 01398 int *indices; 01399 int result; 01400 DdNode **old, *neW; 01401 double minterms; 01402 char *saveString; 01403 int saveFlag, savePoint, isSame; 01404 01405 minterms = Cudd_CountMinterm(dd,f,n); 01406 if ((double)k > minterms) { 01407 return(NULL); 01408 } 01409 01410 size = dd->size; 01411 string = ALLOC(char *, k); 01412 if (string == NULL) { 01413 dd->errorCode = CUDD_MEMORY_OUT; 01414 return(NULL); 01415 } 01416 for (i = 0; i < k; i++) { 01417 string[i] = ALLOC(char, size + 1); 01418 if (string[i] == NULL) { 01419 for (j = 0; j < i; j++) 01420 FREE(string[i]); 01421 FREE(string); 01422 dd->errorCode = CUDD_MEMORY_OUT; 01423 return(NULL); 01424 } 01425 for (j = 0; j < size; j++) string[i][j] = '2'; 01426 string[i][size] = '\0'; 01427 } 01428 indices = ALLOC(int,n); 01429 if (indices == NULL) { 01430 dd->errorCode = CUDD_MEMORY_OUT; 01431 for (i = 0; i < k; i++) 01432 FREE(string[i]); 01433 FREE(string); 01434 return(NULL); 01435 } 01436 01437 for (i = 0; i < n; i++) { 01438 indices[i] = vars[i]->index; 01439 } 01440 01441 result = ddPickArbitraryMinterms(dd,f,n,k,string); 01442 if (result == 0) { 01443 for (i = 0; i < k; i++) 01444 FREE(string[i]); 01445 FREE(string); 01446 FREE(indices); 01447 return(NULL); 01448 } 01449 01450 old = ALLOC(DdNode *, k); 01451 if (old == NULL) { 01452 dd->errorCode = CUDD_MEMORY_OUT; 01453 for (i = 0; i < k; i++) 01454 FREE(string[i]); 01455 FREE(string); 01456 FREE(indices); 01457 return(NULL); 01458 } 01459 saveString = ALLOC(char, size + 1); 01460 if (saveString == NULL) { 01461 dd->errorCode = CUDD_MEMORY_OUT; 01462 for (i = 0; i < k; i++) 01463 FREE(string[i]); 01464 FREE(string); 01465 FREE(indices); 01466 FREE(old); 01467 return(NULL); 01468 } 01469 saveFlag = 0; 01470 01471 /* Build result BDD array. */ 01472 for (i = 0; i < k; i++) { 01473 isSame = 0; 01474 if (!saveFlag) { 01475 for (j = i + 1; j < k; j++) { 01476 if (strcmp(string[i], string[j]) == 0) { 01477 savePoint = i; 01478 strcpy(saveString, string[i]); 01479 saveFlag = 1; 01480 break; 01481 } 01482 } 01483 } else { 01484 if (strcmp(string[i], saveString) == 0) { 01485 isSame = 1; 01486 } else { 01487 saveFlag = 0; 01488 for (j = i + 1; j < k; j++) { 01489 if (strcmp(string[i], string[j]) == 0) { 01490 savePoint = i; 01491 strcpy(saveString, string[i]); 01492 saveFlag = 1; 01493 break; 01494 } 01495 } 01496 } 01497 } 01498 /* Randomize choice for don't cares. */ 01499 for (j = 0; j < n; j++) { 01500 if (string[i][indices[j]] == '2') 01501 string[i][indices[j]] = 01502 (char) ((Cudd_Random() & 0x20) ? '1' : '0'); 01503 } 01504 01505 while (isSame) { 01506 isSame = 0; 01507 for (j = savePoint; j < i; j++) { 01508 if (strcmp(string[i], string[j]) == 0) { 01509 isSame = 1; 01510 break; 01511 } 01512 } 01513 if (isSame) { 01514 strcpy(string[i], saveString); 01515 /* Randomize choice for don't cares. */ 01516 for (j = 0; j < n; j++) { 01517 if (string[i][indices[j]] == '2') 01518 string[i][indices[j]] = 01519 (char) ((Cudd_Random() & 0x20) ? '1' : '0'); 01520 } 01521 } 01522 } 01523 01524 old[i] = Cudd_ReadOne(dd); 01525 cuddRef(old[i]); 01526 01527 for (j = 0; j < n; j++) { 01528 if (string[i][indices[j]] == '0') { 01529 neW = Cudd_bddAnd(dd,old[i],Cudd_Not(vars[j])); 01530 } else { 01531 neW = Cudd_bddAnd(dd,old[i],vars[j]); 01532 } 01533 if (neW == NULL) { 01534 FREE(saveString); 01535 for (l = 0; l < k; l++) 01536 FREE(string[l]); 01537 FREE(string); 01538 FREE(indices); 01539 for (l = 0; l <= i; l++) 01540 Cudd_RecursiveDeref(dd,old[l]); 01541 FREE(old); 01542 return(NULL); 01543 } 01544 cuddRef(neW); 01545 Cudd_RecursiveDeref(dd,old[i]); 01546 old[i] = neW; 01547 } 01548 01549 /* Test. */ 01550 if (!Cudd_bddLeq(dd,old[i],f)) { 01551 FREE(saveString); 01552 for (l = 0; l < k; l++) 01553 FREE(string[l]); 01554 FREE(string); 01555 FREE(indices); 01556 for (l = 0; l <= i; l++) 01557 Cudd_RecursiveDeref(dd,old[l]); 01558 FREE(old); 01559 return(NULL); 01560 } 01561 } 01562 01563 FREE(saveString); 01564 for (i = 0; i < k; i++) { 01565 cuddDeref(old[i]); 01566 FREE(string[i]); 01567 } 01568 FREE(string); 01569 FREE(indices); 01570 return(old); 01571 01572 } /* end of Cudd_bddPickArbitraryMinterms */
Function********************************************************************
Synopsis [Picks one on-set cube randomly from the given DD.]
Description [Picks one on-set cube randomly from the given DD. The cube is written into an array of characters. The array must have at least as many entries as there are variables. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddPickOneMinterm]
Definition at line 1217 of file cuddUtil.c.
01221 { 01222 DdNode *N, *T, *E; 01223 DdNode *one, *bzero; 01224 char dir; 01225 int i; 01226 01227 if (string == NULL || node == NULL) return(0); 01228 01229 /* The constant 0 function has no on-set cubes. */ 01230 one = DD_ONE(ddm); 01231 bzero = Cudd_Not(one); 01232 if (node == bzero) return(0); 01233 01234 for (i = 0; i < ddm->size; i++) string[i] = 2; 01235 01236 for (;;) { 01237 01238 if (node == one) break; 01239 01240 N = Cudd_Regular(node); 01241 01242 T = cuddT(N); E = cuddE(N); 01243 if (Cudd_IsComplement(node)) { 01244 T = Cudd_Not(T); E = Cudd_Not(E); 01245 } 01246 if (T == bzero) { 01247 string[N->index] = 0; 01248 node = E; 01249 } else if (E == bzero) { 01250 string[N->index] = 1; 01251 node = T; 01252 } else { 01253 dir = (char) ((Cudd_Random() & 0x2000) >> 13); 01254 string[N->index] = dir; 01255 node = dir ? T : E; 01256 } 01257 } 01258 return(1); 01259 01260 } /* end of Cudd_bddPickOneCube */
Function********************************************************************
Synopsis [Picks one on-set minterm randomly from the given DD.]
Description [Picks one on-set minterm randomly from the given DD. The minterm is in terms of vars
. The array vars
should contain at least all variables in the support of f
; if this condition is not met the minterm built by this procedure may not be contained in f
. Builds a BDD for the minterm and returns a pointer to it if successful; NULL otherwise. There are three reasons why the procedure may fail:
f
may be the constant 0; f
. ]
SideEffects [None]
SeeAlso [Cudd_bddPickOneCube]
Definition at line 1287 of file cuddUtil.c.
01292 { 01293 char *string; 01294 int i, size; 01295 int *indices; 01296 int result; 01297 DdNode *old, *neW; 01298 01299 size = dd->size; 01300 string = ALLOC(char, size); 01301 if (string == NULL) { 01302 dd->errorCode = CUDD_MEMORY_OUT; 01303 return(NULL); 01304 } 01305 indices = ALLOC(int,n); 01306 if (indices == NULL) { 01307 dd->errorCode = CUDD_MEMORY_OUT; 01308 FREE(string); 01309 return(NULL); 01310 } 01311 01312 for (i = 0; i < n; i++) { 01313 indices[i] = vars[i]->index; 01314 } 01315 01316 result = Cudd_bddPickOneCube(dd,f,string); 01317 if (result == 0) { 01318 FREE(string); 01319 FREE(indices); 01320 return(NULL); 01321 } 01322 01323 /* Randomize choice for don't cares. */ 01324 for (i = 0; i < n; i++) { 01325 if (string[indices[i]] == 2) 01326 string[indices[i]] = (char) ((Cudd_Random() & 0x20) >> 5); 01327 } 01328 01329 /* Build result BDD. */ 01330 old = Cudd_ReadOne(dd); 01331 cuddRef(old); 01332 01333 for (i = n-1; i >= 0; i--) { 01334 neW = Cudd_bddAnd(dd,old,Cudd_NotCond(vars[i],string[indices[i]]==0)); 01335 if (neW == NULL) { 01336 FREE(string); 01337 FREE(indices); 01338 Cudd_RecursiveDeref(dd,old); 01339 return(NULL); 01340 } 01341 cuddRef(neW); 01342 Cudd_RecursiveDeref(dd,old); 01343 old = neW; 01344 } 01345 01346 #ifdef DD_DEBUG 01347 /* Test. */ 01348 if (Cudd_bddLeq(dd,old,f)) { 01349 cuddDeref(old); 01350 } else { 01351 Cudd_RecursiveDeref(dd,old); 01352 old = NULL; 01353 } 01354 #else 01355 cuddDeref(old); 01356 #endif 01357 01358 FREE(string); 01359 FREE(indices); 01360 return(old); 01361 01362 } /* end of Cudd_bddPickOneMinterm */
Function********************************************************************
Synopsis [Prints a sum of prime implicants of a BDD.]
Description [Prints a sum of product cover for an incompletely specified function given by a lower bound and an upper bound. Each product is a prime implicant obtained by expanding the product corresponding to a path from node to the constant one. Uses the package default output file. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_PrintMinterm]
Definition at line 249 of file cuddUtil.c.
00253 { 00254 int *array; 00255 int q, result; 00256 DdNode *lb; 00257 #ifdef DD_DEBUG 00258 DdNode *cover; 00259 #endif 00260 00261 array = ALLOC(int, Cudd_ReadSize(dd)); 00262 if (array == NULL) return(0); 00263 lb = l; 00264 cuddRef(lb); 00265 #ifdef DD_DEBUG 00266 cover = Cudd_ReadLogicZero(dd); 00267 cuddRef(cover); 00268 #endif 00269 while (lb != Cudd_ReadLogicZero(dd)) { 00270 DdNode *implicant, *prime, *tmp; 00271 int length; 00272 implicant = Cudd_LargestCube(dd,lb,&length); 00273 if (implicant == NULL) { 00274 Cudd_RecursiveDeref(dd,lb); 00275 FREE(array); 00276 return(0); 00277 } 00278 cuddRef(implicant); 00279 prime = Cudd_bddMakePrime(dd,implicant,u); 00280 if (prime == NULL) { 00281 Cudd_RecursiveDeref(dd,lb); 00282 Cudd_RecursiveDeref(dd,implicant); 00283 FREE(array); 00284 return(0); 00285 } 00286 cuddRef(prime); 00287 Cudd_RecursiveDeref(dd,implicant); 00288 tmp = Cudd_bddAnd(dd,lb,Cudd_Not(prime)); 00289 if (tmp == NULL) { 00290 Cudd_RecursiveDeref(dd,lb); 00291 Cudd_RecursiveDeref(dd,prime); 00292 FREE(array); 00293 return(0); 00294 } 00295 cuddRef(tmp); 00296 Cudd_RecursiveDeref(dd,lb); 00297 lb = tmp; 00298 result = Cudd_BddToCubeArray(dd,prime,array); 00299 if (result == 0) { 00300 Cudd_RecursiveDeref(dd,lb); 00301 Cudd_RecursiveDeref(dd,prime); 00302 FREE(array); 00303 return(0); 00304 } 00305 for (q = 0; q < dd->size; q++) { 00306 switch (array[q]) { 00307 case 0: 00308 (void) fprintf(dd->out, "0"); 00309 break; 00310 case 1: 00311 (void) fprintf(dd->out, "1"); 00312 break; 00313 case 2: 00314 (void) fprintf(dd->out, "-"); 00315 break; 00316 default: 00317 (void) fprintf(dd->out, "?"); 00318 } 00319 } 00320 (void) fprintf(dd->out, " 1\n"); 00321 #ifdef DD_DEBUG 00322 tmp = Cudd_bddOr(dd,prime,cover); 00323 if (tmp == NULL) { 00324 Cudd_RecursiveDeref(dd,cover); 00325 Cudd_RecursiveDeref(dd,lb); 00326 Cudd_RecursiveDeref(dd,prime); 00327 FREE(array); 00328 return(0); 00329 } 00330 cuddRef(tmp); 00331 Cudd_RecursiveDeref(dd,cover); 00332 cover = tmp; 00333 #endif 00334 Cudd_RecursiveDeref(dd,prime); 00335 } 00336 (void) fprintf(dd->out, "\n"); 00337 Cudd_RecursiveDeref(dd,lb); 00338 FREE(array); 00339 #ifdef DD_DEBUG 00340 if (!Cudd_bddLeq(dd,cover,u) || !Cudd_bddLeq(dd,l,cover)) { 00341 Cudd_RecursiveDeref(dd,cover); 00342 return(0); 00343 } 00344 Cudd_RecursiveDeref(dd,cover); 00345 #endif 00346 return(1); 00347 00348 } /* end of Cudd_bddPrintCover */
int Cudd_bddRead | ( | FILE * | fp, | |
DdManager * | dd, | |||
DdNode ** | E, | |||
DdNode *** | x, | |||
DdNode *** | y, | |||
int * | nx, | |||
int * | ny, | |||
int * | m, | |||
int * | n, | |||
int | bx, | |||
int | sx, | |||
int | by, | |||
int | sy | |||
) |
Function********************************************************************
Synopsis [Reads in a graph (without labels) given as a list of arcs.]
Description [Reads in a graph (without labels) given as an adjacency matrix. The first line of the input contains the numbers of rows and columns of the adjacency matrix. The remaining lines contain the arcs of the graph, one per line. Each arc is described by two integers, i.e., the row and column number, or the indices of the two endpoints. Cudd_bddRead produces a BDD that depends on two sets of variables: x and y. The x variables (x\[0\] ... x\[nx-1\]) encode the row index and the y variables (y\[0\] ... y\[ny-1\]) encode the column index. x\[0\] and y\[0\] are the most significant bits in the indices. The variables may already exist or may be created by the function. The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.
On input, nx and ny hold the numbers of row and column variables already in existence. On output, they hold the numbers of row and column variables actually used by the matrix. When Cudd_bddRead creates the variable arrays, the index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy. When some variables already exist, Cudd_bddRead expects the indices of the existing x variables to be bx+i*sx, and the indices of the existing y variables to be by+i*sy.
m and n are set to the numbers of rows and columns of the matrix. Their values on input are immaterial. The BDD for the graph is returned in E, and its reference count is > 0. Cudd_bddRead returns 1 in case of success; 0 otherwise.]
SideEffects [nx and ny are set to the numbers of row and column variables. m and n are set to the numbers of rows and columns. x and y are possibly extended to represent the array of row and column variables.]
SeeAlso [Cudd_addHarwell Cudd_addRead]
Definition at line 365 of file cuddRead.c.
00379 { 00380 DdNode *one, *zero; 00381 DdNode *w; 00382 DdNode *minterm1; 00383 int u, v, err, i, nv; 00384 int lnx, lny; 00385 DdNode **lx, **ly; 00386 00387 one = DD_ONE(dd); 00388 zero = Cudd_Not(one); 00389 00390 err = fscanf(fp, "%d %d", &u, &v); 00391 if (err == EOF) { 00392 return(0); 00393 } else if (err != 2) { 00394 return(0); 00395 } 00396 00397 *m = u; 00398 /* Compute the number of x variables. */ 00399 lx = *x; 00400 u--; /* row and column numbers start from 0 */ 00401 for (lnx=0; u > 0; lnx++) { 00402 u >>= 1; 00403 } 00404 if (lnx > *nx) { 00405 *x = lx = REALLOC(DdNode *, *x, lnx); 00406 if (lx == NULL) { 00407 dd->errorCode = CUDD_MEMORY_OUT; 00408 return(0); 00409 } 00410 } 00411 00412 *n = v; 00413 /* Compute the number of y variables. */ 00414 ly = *y; 00415 v--; /* row and column numbers start from 0 */ 00416 for (lny=0; v > 0; lny++) { 00417 v >>= 1; 00418 } 00419 if (lny > *ny) { 00420 *y = ly = REALLOC(DdNode *, *y, lny); 00421 if (ly == NULL) { 00422 dd->errorCode = CUDD_MEMORY_OUT; 00423 return(0); 00424 } 00425 } 00426 00427 /* Create all new variables. */ 00428 for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) { 00429 do { 00430 dd->reordered = 0; 00431 lx[i] = cuddUniqueInter(dd, nv, one, zero); 00432 } while (dd->reordered == 1); 00433 if (lx[i] == NULL) return(0); 00434 cuddRef(lx[i]); 00435 } 00436 for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) { 00437 do { 00438 dd->reordered = 0; 00439 ly[i] = cuddUniqueInter(dd, nv, one, zero); 00440 } while (dd->reordered == 1); 00441 if (ly[i] == NULL) return(0); 00442 cuddRef(ly[i]); 00443 } 00444 *nx = lnx; 00445 *ny = lny; 00446 00447 *E = zero; /* this call will never cause reordering */ 00448 cuddRef(*E); 00449 00450 while (! feof(fp)) { 00451 err = fscanf(fp, "%d %d", &u, &v); 00452 if (err == EOF) { 00453 break; 00454 } else if (err != 2) { 00455 return(0); 00456 } else if (u >= *m || v >= *n || u < 0 || v < 0) { 00457 return(0); 00458 } 00459 00460 minterm1 = one; cuddRef(minterm1); 00461 00462 /* Build minterm1 corresponding to this arc. */ 00463 for (i = lnx - 1; i>=0; i--) { 00464 if (u & 1) { 00465 w = Cudd_bddAnd(dd, minterm1, lx[i]); 00466 } else { 00467 w = Cudd_bddAnd(dd, minterm1, Cudd_Not(lx[i])); 00468 } 00469 if (w == NULL) { 00470 Cudd_RecursiveDeref(dd, minterm1); 00471 return(0); 00472 } 00473 cuddRef(w); 00474 Cudd_RecursiveDeref(dd,minterm1); 00475 minterm1 = w; 00476 u >>= 1; 00477 } 00478 for (i = lny - 1; i>=0; i--) { 00479 if (v & 1) { 00480 w = Cudd_bddAnd(dd, minterm1, ly[i]); 00481 } else { 00482 w = Cudd_bddAnd(dd, minterm1, Cudd_Not(ly[i])); 00483 } 00484 if (w == NULL) { 00485 Cudd_RecursiveDeref(dd, minterm1); 00486 return(0); 00487 } 00488 cuddRef(w); 00489 Cudd_RecursiveDeref(dd, minterm1); 00490 minterm1 = w; 00491 v >>= 1; 00492 } 00493 00494 w = Cudd_bddAnd(dd, Cudd_Not(minterm1), Cudd_Not(*E)); 00495 if (w == NULL) { 00496 Cudd_RecursiveDeref(dd, minterm1); 00497 return(0); 00498 } 00499 w = Cudd_Not(w); 00500 cuddRef(w); 00501 Cudd_RecursiveDeref(dd, minterm1); 00502 Cudd_RecursiveDeref(dd, *E); 00503 *E = w; 00504 } 00505 return(1); 00506 00507 } /* end of Cudd_bddRead */
int Cudd_bddReadPairIndex | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Reads a corresponding pair index for a given index.]
Description [Reads a corresponding pair index for a given index. These pair indices are present and next state variable. Returns the corresponding variable index if the variable exists; -1 otherwise.]
SideEffects [modifies the manager]
SeeAlso [Cudd_bddSetPairIndex]
void Cudd_bddRealignDisable | ( | DdManager * | unique | ) |
Function********************************************************************
Synopsis [Disables realignment of ZDD order to BDD order.]
Description []
SideEffects [None]
SeeAlso [Cudd_bddRealignEnable Cudd_bddRealignmentEnabled Cudd_zddRealignEnable Cudd_zddRealignmentEnabled]
Definition at line 961 of file cuddAPI.c.
00963 { 00964 unique->realignZ = 0; 00965 return; 00966 00967 } /* end of Cudd_bddRealignDisable */
void Cudd_bddRealignEnable | ( | DdManager * | unique | ) |
Function********************************************************************
Synopsis [Enables realignment of BDD order to ZDD order.]
Description [Enables realignment of the BDD variable order to the ZDD variable order after the ZDDs have been reordered. The number of ZDD variables must be a multiple of the number of BDD variables for realignment to make sense. If this condition is not met, Cudd_zddReduceHeap will return 0. Let M
be the ratio of the two numbers. For the purpose of realignment, the ZDD variables from M*i
to (M+1)*i-1
are reagarded as corresponding to BDD variable i
. Realignment is initially disabled.]
SideEffects [None]
SeeAlso [Cudd_zddReduceHeap Cudd_bddRealignDisable Cudd_bddRealignmentEnabled Cudd_zddRealignDisable Cudd_zddRealignmentEnabled]
Definition at line 939 of file cuddAPI.c.
00941 { 00942 unique->realignZ = 1; 00943 return; 00944 00945 } /* end of Cudd_bddRealignEnable */
int Cudd_bddRealignmentEnabled | ( | DdManager * | unique | ) |
Function********************************************************************
Synopsis [Tells whether the realignment of BDD order to ZDD order is enabled.]
Description [Returns 1 if the realignment of BDD order to ZDD order is enabled; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddRealignEnable Cudd_bddRealignDisable Cudd_zddRealignEnable Cudd_zddRealignDisable]
Definition at line 909 of file cuddAPI.c.
00911 { 00912 return(unique->realignZ); 00913 00914 } /* end of Cudd_bddRealignmentEnabled */
int Cudd_bddResetVarToBeGrouped | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Resets a variable not to be grouped.]
Description [Resets a variable not to be grouped. This function is used for lazy sifting. Returns 1 if successful; 0 otherwise.]
SideEffects [modifies the manager]
SeeAlso [Cudd_bddSetVarToBeGrouped Cudd_bddSetVarHardGroup]
Definition at line 4219 of file cuddAPI.c.
04222 { 04223 if (index >= dd->size || index < 0) return(0); 04224 if (dd->subtables[dd->perm[index]].varToBeGrouped <= 04225 CUDD_LAZY_SOFT_GROUP) { 04226 dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_NONE; 04227 } 04228 return(1); 04229 04230 } /* end of Cudd_bddResetVarToBeGrouped */
Function********************************************************************
Synopsis [BDD restrict according to Coudert and Madre's algorithm (ICCAD90).]
Description [BDD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns the restricted BDD if successful; otherwise NULL. If application of restrict results in a BDD larger than the input BDD, the input BDD is returned.]
SideEffects [None]
SeeAlso [Cudd_bddConstrain Cudd_addRestrict]
Definition at line 208 of file cuddGenCof.c.
00212 { 00213 DdNode *suppF, *suppC, *commonSupport; 00214 DdNode *cplus, *res; 00215 int retval; 00216 int sizeF, sizeRes; 00217 00218 /* Check terminal cases here to avoid computing supports in trivial cases. 00219 ** This also allows us notto check later for the case c == 0, in which 00220 ** there is no common support. */ 00221 if (c == Cudd_Not(DD_ONE(dd))) return(Cudd_Not(DD_ONE(dd))); 00222 if (Cudd_IsConstant(f)) return(f); 00223 if (f == c) return(DD_ONE(dd)); 00224 if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd))); 00225 00226 /* Check if supports intersect. */ 00227 retval = Cudd_ClassifySupport(dd,f,c,&commonSupport,&suppF,&suppC); 00228 if (retval == 0) { 00229 return(NULL); 00230 } 00231 cuddRef(commonSupport); cuddRef(suppF); cuddRef(suppC); 00232 Cudd_IterDerefBdd(dd,suppF); 00233 00234 if (commonSupport == DD_ONE(dd)) { 00235 Cudd_IterDerefBdd(dd,commonSupport); 00236 Cudd_IterDerefBdd(dd,suppC); 00237 return(f); 00238 } 00239 Cudd_IterDerefBdd(dd,commonSupport); 00240 00241 /* Abstract from c the variables that do not appear in f. */ 00242 cplus = Cudd_bddExistAbstract(dd, c, suppC); 00243 if (cplus == NULL) { 00244 Cudd_IterDerefBdd(dd,suppC); 00245 return(NULL); 00246 } 00247 cuddRef(cplus); 00248 Cudd_IterDerefBdd(dd,suppC); 00249 00250 do { 00251 dd->reordered = 0; 00252 res = cuddBddRestrictRecur(dd, f, cplus); 00253 } while (dd->reordered == 1); 00254 if (res == NULL) { 00255 Cudd_IterDerefBdd(dd,cplus); 00256 return(NULL); 00257 } 00258 cuddRef(res); 00259 Cudd_IterDerefBdd(dd,cplus); 00260 /* Make restric safe by returning the smaller of the input and the 00261 ** result. */ 00262 sizeF = Cudd_DagSize(f); 00263 sizeRes = Cudd_DagSize(res); 00264 if (sizeF <= sizeRes) { 00265 Cudd_IterDerefBdd(dd, res); 00266 return(f); 00267 } else { 00268 cuddDeref(res); 00269 return(res); 00270 } 00271 00272 } /* end of Cudd_bddRestrict */
int Cudd_bddSetNsVar | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Sets a variable type to next state.]
Description [Sets a variable type to next state. The variable type is used by lazy sifting. Returns 1 if successful; 0 otherwise.]
SideEffects [modifies the manager]
SeeAlso [Cudd_bddSetPiVar Cudd_bddSetPsVar Cudd_bddIsNsVar]
Definition at line 4022 of file cuddAPI.c.
04025 { 04026 if (index >= dd->size || index < 0) return (0); 04027 dd->subtables[dd->perm[index]].varType = CUDD_VAR_NEXT_STATE; 04028 return(1); 04029 04030 } /* end of Cudd_bddSetNsVar */
int Cudd_bddSetPairIndex | ( | DdManager * | dd, | |
int | index, | |||
int | pairIndex | |||
) |
Function********************************************************************
Synopsis [Sets a corresponding pair index for a given index.]
Description [Sets a corresponding pair index for a given index. These pair indices are present and next state variable. Returns 1 if successful; 0 otherwise.]
SideEffects [modifies the manager]
SeeAlso [Cudd_bddReadPairIndex]
int Cudd_bddSetPiVar | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Sets a variable type to primary input.]
Description [Sets a variable type to primary input. The variable type is used by lazy sifting. Returns 1 if successful; 0 otherwise.]
SideEffects [modifies the manager]
SeeAlso [Cudd_bddSetPsVar Cudd_bddSetNsVar Cudd_bddIsPiVar]
Definition at line 3974 of file cuddAPI.c.
03977 { 03978 if (index >= dd->size || index < 0) return (0); 03979 dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRIMARY_INPUT; 03980 return(1); 03981 03982 } /* end of Cudd_bddSetPiVar */
int Cudd_bddSetPsVar | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Sets a variable type to present state.]
Description [Sets a variable type to present state. The variable type is used by lazy sifting. Returns 1 if successful; 0 otherwise.]
SideEffects [modifies the manager]
SeeAlso [Cudd_bddSetPiVar Cudd_bddSetNsVar Cudd_bddIsPsVar]
Definition at line 3998 of file cuddAPI.c.
04001 { 04002 if (index >= dd->size || index < 0) return (0); 04003 dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRESENT_STATE; 04004 return(1); 04005 04006 } /* end of Cudd_bddSetPsVar */
int Cudd_bddSetVarHardGroup | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Sets a variable to be a hard group.]
Description [Sets a variable to be a hard group. This function is used for lazy sifting. Returns 1 if successful; 0 otherwise.]
SideEffects [modifies the manager]
SeeAlso [Cudd_bddSetVarToBeGrouped Cudd_bddResetVarToBeGrouped Cudd_bddIsVarHardGroup]
Definition at line 4195 of file cuddAPI.c.
04198 { 04199 if (index >= dd->size || index < 0) return(0); 04200 dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_HARD_GROUP; 04201 return(1); 04202 04203 } /* end of Cudd_bddSetVarHardGrouped */
int Cudd_bddSetVarToBeGrouped | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Sets a variable to be grouped.]
Description [Sets a variable to be grouped. This function is used for lazy sifting. Returns 1 if successful; 0 otherwise.]
SideEffects [modifies the manager]
SeeAlso [Cudd_bddSetVarHardGroup Cudd_bddResetVarToBeGrouped]
Definition at line 4168 of file cuddAPI.c.
04171 { 04172 if (index >= dd->size || index < 0) return(0); 04173 if (dd->subtables[dd->perm[index]].varToBeGrouped <= CUDD_LAZY_SOFT_GROUP) { 04174 dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_SOFT_GROUP; 04175 } 04176 return(1); 04177 04178 } /* end of Cudd_bddSetVarToBeGrouped */
int Cudd_bddSetVarToBeUngrouped | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Sets a variable to be ungrouped.]
Description [Sets a variable to be ungrouped. This function is used for lazy sifting. Returns 1 if successful; 0 otherwise.]
SideEffects [modifies the manager]
SeeAlso [Cudd_bddIsVarToBeUngrouped]
Definition at line 4272 of file cuddAPI.c.
04275 { 04276 if (index >= dd->size || index < 0) return(0); 04277 dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_UNGROUP; 04278 return(1); 04279 04280 } /* end of Cudd_bddSetVarToBeGrouped */
Function********************************************************************
Synopsis [Finds a small BDD in a function interval.]
Description [Finds a small BDD in a function interval. Given BDDs l
and u
, representing the lower bound and upper bound of a function interval, Cudd_bddSqueeze produces the BDD of a function within the interval with a small BDD. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction]
Definition at line 598 of file cuddGenCof.c.
00602 { 00603 DdNode *res; 00604 int sizeRes, sizeL, sizeU; 00605 00606 do { 00607 dd->reordered = 0; 00608 res = cuddBddSqueeze(dd,l,u); 00609 } while (dd->reordered == 1); 00610 if (res == NULL) return(NULL); 00611 /* We now compare the result with the bounds and return the smallest. 00612 ** We first compare to u, so that in case l == 0 and u == 1, we return 00613 ** 0 as in other minimization algorithms. */ 00614 sizeRes = Cudd_DagSize(res); 00615 sizeU = Cudd_DagSize(u); 00616 if (sizeU <= sizeRes) { 00617 cuddRef(res); 00618 Cudd_IterDerefBdd(dd,res); 00619 res = u; 00620 sizeRes = sizeU; 00621 } 00622 sizeL = Cudd_DagSize(l); 00623 if (sizeL <= sizeRes) { 00624 cuddRef(res); 00625 Cudd_IterDerefBdd(dd,res); 00626 res = l; 00627 sizeRes = sizeL; 00628 } 00629 return(res); 00630 00631 } /* end of Cudd_bddSqueeze */
Function********************************************************************
Synopsis [Swaps two sets of variables of the same size (x and y) in the BDD f.]
Description [Swaps two sets of variables of the same size (x and y) in the BDD f. The size is given by n. The two sets of variables are assumed to be disjoint. Returns a pointer to the resulting BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddPermute Cudd_addSwapVariables]
Definition at line 460 of file cuddCompose.c.
00466 { 00467 DdNode *swapped; 00468 int i, j, k; 00469 int *permut; 00470 00471 permut = ALLOC(int,dd->size); 00472 if (permut == NULL) { 00473 dd->errorCode = CUDD_MEMORY_OUT; 00474 return(NULL); 00475 } 00476 for (i = 0; i < dd->size; i++) permut[i] = i; 00477 for (i = 0; i < n; i++) { 00478 j = x[i]->index; 00479 k = y[i]->index; 00480 permut[j] = k; 00481 permut[k] = j; 00482 } 00483 00484 swapped = Cudd_bddPermute(dd,f,permut); 00485 FREE(permut); 00486 00487 return(swapped); 00488 00489 } /* end of Cudd_bddSwapVariables */
Function********************************************************************
Synopsis [Converts a BDD to a 0-1 ADD.]
Description [Converts a BDD to a 0-1 ADD. Returns a pointer to the resulting ADD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_addBddPattern Cudd_addBddThreshold Cudd_addBddInterval Cudd_addBddStrictThreshold]
Definition at line 345 of file cuddBridge.c.
00348 { 00349 DdNode *res; 00350 00351 do { 00352 dd->reordered = 0; 00353 res = ddBddToAddRecur(dd, B); 00354 } while (dd->reordered ==1); 00355 return(res); 00356 00357 } /* end of Cudd_BddToAdd */
Function********************************************************************
Synopsis [Builds a positional array from the BDD of a cube.]
Description [Builds a positional array from the BDD of a cube. Array must have one entry for each BDD variable. The positional array has 1 in i-th position if the variable of index i appears in true form in the cube; it has 0 in i-th position if the variable of index i appears in complemented form in the cube; finally, it has 2 in i-th position if the variable of index i does not appear in the cube. Returns 1 if successful (the BDD is indeed a cube); 0 otherwise.]
SideEffects [The result is in the array passed by reference.]
SeeAlso [Cudd_CubeArrayToBdd]
Definition at line 2342 of file cuddUtil.c.
02346 { 02347 DdNode *scan, *t, *e; 02348 int i; 02349 int size = Cudd_ReadSize(dd); 02350 DdNode *zero = Cudd_Not(DD_ONE(dd)); 02351 02352 for (i = size-1; i >= 0; i--) { 02353 array[i] = 2; 02354 } 02355 scan = cube; 02356 while (!Cudd_IsConstant(scan)) { 02357 int index = Cudd_Regular(scan)->index; 02358 cuddGetBranches(scan,&t,&e); 02359 if (t == zero) { 02360 array[index] = 0; 02361 scan = e; 02362 } else if (e == zero) { 02363 array[index] = 1; 02364 scan = t; 02365 } else { 02366 return(0); /* cube is not a cube */ 02367 } 02368 } 02369 if (scan == zero) { 02370 return(0); 02371 } else { 02372 return(1); 02373 } 02374 02375 } /* end of Cudd_BddToCubeArray */
Function********************************************************************
Synopsis [Convert a BDD from a manager to another one.]
Description [Convert a BDD from a manager to another one. The orders of the variables in the two managers may be different. Returns a pointer to the BDD in the destination manager if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 405 of file cuddBridge.c.
00409 { 00410 DdNode *res; 00411 do { 00412 ddDestination->reordered = 0; 00413 res = cuddBddTransfer(ddSource, ddDestination, f); 00414 } while (ddDestination->reordered == 1); 00415 return(res); 00416 00417 } /* end of Cudd_bddTransfer */
int Cudd_bddUnbindVar | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Allows the sifting of a variable.]
Description [This function resets the flag that prevents the sifting of a variable. In successive variable reorderings, the variable will NOT be skipped, that is, sifted. Initially all variables can be sifted. It is necessary to call this function only to re-enable sifting after a call to Cudd_bddBindVar. Returns 1 if successful; 0 otherwise (i.e., invalid variable index).]
SideEffects [Changes the "bindVar" flag in DdSubtable.]
SeeAlso [Cudd_bddBindVar]
Function********************************************************************
Synopsis [Universally abstracts all the variables in cube from f.]
Description [Universally abstracts all the variables in cube from f. Returns the abstracted BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddExistAbstract Cudd_addUnivAbstract]
Definition at line 203 of file cuddBddAbs.c.
00207 { 00208 DdNode *res; 00209 00210 if (bddCheckPositiveCube(manager, cube) == 0) { 00211 (void) fprintf(manager->err, 00212 "Error: Can only abstract positive cubes\n"); 00213 manager->errorCode = CUDD_INVALID_ARG; 00214 return(NULL); 00215 } 00216 00217 do { 00218 manager->reordered = 0; 00219 res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube); 00220 } while (manager->reordered == 1); 00221 if (res != NULL) res = Cudd_Not(res); 00222 00223 return(res); 00224 00225 } /* end of Cudd_bddUnivAbstract */
Function********************************************************************
Synopsis [Performs two-way conjunctive decomposition of a BDD.]
Description [Conjunctively decomposes one BDD according to a variable. If f
is the function of the BDD and x
is the variable, the decomposition is (f+x)(f+x')
. The variable is chosen so as to balance the sizes of the two conjuncts and to keep them small. Returns the number of conjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise.]
SideEffects [The two factors are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the conjuncts are already referenced. If the function returns 0, the array for the conjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]
SeeAlso [Cudd_bddVarDisjDecomp Cudd_bddGenConjDecomp Cudd_bddApproxConjDecomp Cudd_bddIterConjDecomp]
Definition at line 611 of file cuddDecomp.c.
00615 { 00616 int best; 00617 int min; 00618 DdNode *support, *scan, *var, *glocal, *hlocal; 00619 00620 /* Find best cofactoring variable. */ 00621 support = Cudd_Support(dd,f); 00622 if (support == NULL) return(0); 00623 if (Cudd_IsConstant(support)) { 00624 *conjuncts = ALLOC(DdNode *,1); 00625 if (*conjuncts == NULL) { 00626 dd->errorCode = CUDD_MEMORY_OUT; 00627 return(0); 00628 } 00629 (*conjuncts)[0] = f; 00630 cuddRef((*conjuncts)[0]); 00631 return(1); 00632 } 00633 cuddRef(support); 00634 min = 1000000000; 00635 best = -1; 00636 scan = support; 00637 while (!Cudd_IsConstant(scan)) { 00638 int i = scan->index; 00639 int est1 = Cudd_EstimateCofactor(dd,f,i,1); 00640 int est0 = Cudd_EstimateCofactor(dd,f,i,0); 00641 /* Minimize the size of the larger of the two cofactors. */ 00642 int est = (est1 > est0) ? est1 : est0; 00643 if (est < min) { 00644 min = est; 00645 best = i; 00646 } 00647 scan = cuddT(scan); 00648 } 00649 #ifdef DD_DEBUG 00650 assert(best >= 0 && best < dd->size); 00651 #endif 00652 Cudd_RecursiveDeref(dd,support); 00653 00654 var = Cudd_bddIthVar(dd,best); 00655 glocal = Cudd_bddOr(dd,f,var); 00656 if (glocal == NULL) { 00657 return(0); 00658 } 00659 cuddRef(glocal); 00660 hlocal = Cudd_bddOr(dd,f,Cudd_Not(var)); 00661 if (hlocal == NULL) { 00662 Cudd_RecursiveDeref(dd,glocal); 00663 return(0); 00664 } 00665 cuddRef(hlocal); 00666 00667 if (glocal != DD_ONE(dd)) { 00668 if (hlocal != DD_ONE(dd)) { 00669 *conjuncts = ALLOC(DdNode *,2); 00670 if (*conjuncts == NULL) { 00671 Cudd_RecursiveDeref(dd,glocal); 00672 Cudd_RecursiveDeref(dd,hlocal); 00673 dd->errorCode = CUDD_MEMORY_OUT; 00674 return(0); 00675 } 00676 (*conjuncts)[0] = glocal; 00677 (*conjuncts)[1] = hlocal; 00678 return(2); 00679 } else { 00680 Cudd_RecursiveDeref(dd,hlocal); 00681 *conjuncts = ALLOC(DdNode *,1); 00682 if (*conjuncts == NULL) { 00683 Cudd_RecursiveDeref(dd,glocal); 00684 dd->errorCode = CUDD_MEMORY_OUT; 00685 return(0); 00686 } 00687 (*conjuncts)[0] = glocal; 00688 return(1); 00689 } 00690 } else { 00691 Cudd_RecursiveDeref(dd,glocal); 00692 *conjuncts = ALLOC(DdNode *,1); 00693 if (*conjuncts == NULL) { 00694 Cudd_RecursiveDeref(dd,hlocal); 00695 dd->errorCode = CUDD_MEMORY_OUT; 00696 return(0); 00697 } 00698 (*conjuncts)[0] = hlocal; 00699 return(1); 00700 } 00701 00702 } /* end of Cudd_bddVarConjDecomp */
Function********************************************************************
Synopsis [Performs two-way disjunctive decomposition of a BDD.]
Description [Performs two-way disjunctive decomposition of a BDD according to a variable. If f
is the function of the BDD and x
is the variable, the decomposition is f*x + f*x'
. The variable is chosen so as to balance the sizes of the two disjuncts and to keep them small. Returns the number of disjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise.]
SideEffects [The two disjuncts are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the disjuncts are already referenced. If the function returns 0, the array for the disjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]
SeeAlso [Cudd_bddVarConjDecomp Cudd_bddApproxDisjDecomp Cudd_bddIterDisjDecomp Cudd_bddGenDisjDecomp]
Definition at line 729 of file cuddDecomp.c.
00733 { 00734 int result, i; 00735 00736 result = Cudd_bddVarConjDecomp(dd,Cudd_Not(f),disjuncts); 00737 for (i = 0; i < result; i++) { 00738 (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); 00739 } 00740 return(result); 00741 00742 } /* end of Cudd_bddVarDisjDecomp */
int Cudd_bddVarIsBound | ( | DdManager * | dd, | |
int | index | |||
) |
Function********************************************************************
Synopsis [Tells whether a variable can be sifted.]
Description [This function returns 1 if a variable is enabled for sifting. Initially all variables can be sifted. This function returns 0 only if there has been a previous call to Cudd_bddBindVar for that variable not followed by a call to Cudd_bddUnbindVar. The function returns 0 also in the case in which the index of the variable is out of bounds.]
SideEffects [none]
SeeAlso [Cudd_bddBindVar Cudd_bddUnbindVar]
Function********************************************************************
Synopsis [Checks whether a variable is dependent on others in a function.]
Description [Checks whether a variable is dependent on others in a function. Returns 1 if the variable is dependent; 0 otherwise. No new nodes are created.]
SideEffects [None]
SeeAlso []
Definition at line 280 of file cuddBddAbs.c.
00284 { 00285 DdNode *F, *res, *zero, *ft, *fe; 00286 unsigned topf, level; 00287 DD_CTFP cacheOp; 00288 int retval; 00289 00290 zero = Cudd_Not(DD_ONE(dd)); 00291 if (Cudd_IsConstant(f)) return(f == zero); 00292 00293 /* From now on f is not constant. */ 00294 F = Cudd_Regular(f); 00295 topf = (unsigned) dd->perm[F->index]; 00296 level = (unsigned) dd->perm[var->index]; 00297 00298 /* Check terminal case. If topf > index of var, f does not depend on var. 00299 ** Therefore, var is not dependent in f. */ 00300 if (topf > level) { 00301 return(0); 00302 } 00303 00304 cacheOp = (DD_CTFP) Cudd_bddVarIsDependent; 00305 res = cuddCacheLookup2(dd,cacheOp,f,var); 00306 if (res != NULL) { 00307 return(res != zero); 00308 } 00309 00310 /* Compute cofactors. */ 00311 ft = Cudd_NotCond(cuddT(F), f != F); 00312 fe = Cudd_NotCond(cuddE(F), f != F); 00313 00314 if (topf == level) { 00315 retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe)); 00316 } else { 00317 retval = Cudd_bddVarIsDependent(dd,ft,var) && 00318 Cudd_bddVarIsDependent(dd,fe,var); 00319 } 00320 00321 cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval)); 00322 00323 return(retval); 00324 00325 } /* Cudd_bddVarIsDependent */
Function********************************************************************
Synopsis [Remaps the variables of a BDD using the default variable map.]
Description [Remaps the variables of a BDD using the default variable map. A typical use of this function is to swap two sets of variables. The variable map must be registered with Cudd_SetVarMap. Returns a pointer to the resulting BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables Cudd_SetVarMap]
Definition at line 369 of file cuddCompose.c.
00372 { 00373 DdNode *res; 00374 00375 if (manager->map == NULL) return(NULL); 00376 do { 00377 manager->reordered = 0; 00378 res = cuddBddVarMapRecur(manager, f); 00379 } while (manager->reordered == 1); 00380 00381 return(res); 00382 00383 } /* end of Cudd_bddVarMap */
Function********************************************************************
Synopsis [Composes a BDD with a vector of BDDs.]
Description [Given a vector of BDDs, creates a new BDD by substituting the BDDs for the variables of the BDD f. There should be an entry in vector for each variable in the manager. If no substitution is sought for a given variable, the corresponding projection function should be specified in the vector. This function implements simultaneous composition. Returns a pointer to the resulting BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddPermute Cudd_bddCompose Cudd_addVectorCompose]
Definition at line 787 of file cuddCompose.c.
00791 { 00792 DdHashTable *table; 00793 DdNode *res; 00794 int deepest; 00795 int i; 00796 00797 do { 00798 dd->reordered = 0; 00799 /* Initialize local cache. */ 00800 table = cuddHashTableInit(dd,1,2); 00801 if (table == NULL) return(NULL); 00802 00803 /* Find deepest real substitution. */ 00804 for (deepest = dd->size - 1; deepest >= 0; deepest--) { 00805 i = dd->invperm[deepest]; 00806 if (vector[i] != dd->vars[i]) { 00807 break; 00808 } 00809 } 00810 00811 /* Recursively solve the problem. */ 00812 res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest); 00813 if (res != NULL) cuddRef(res); 00814 00815 /* Dispose of local cache. */ 00816 cuddHashTableQuit(table); 00817 } while (dd->reordered == 1); 00818 00819 if (res != NULL) cuddDeref(res); 00820 return(res); 00821 00822 } /* end of Cudd_bddVectorCompose */
Function********************************************************************
Synopsis [Computes the exclusive NOR of two BDDs f and g.]
Description [Computes the exclusive NOR of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor]
Definition at line 503 of file cuddBddIte.c.
00507 { 00508 DdNode *res; 00509 00510 do { 00511 dd->reordered = 0; 00512 res = cuddBddXorRecur(dd,f,Cudd_Not(g)); 00513 } while (dd->reordered == 1); 00514 return(res); 00515 00516 } /* end of Cudd_bddXnor */
Function********************************************************************
Synopsis [Computes the exclusive OR of two BDDs f and g.]
Description [Computes the exclusive OR of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]
SideEffects [None]
SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXnor]
Definition at line 472 of file cuddBddIte.c.
00476 { 00477 DdNode *res; 00478 00479 do { 00480 dd->reordered = 0; 00481 res = cuddBddXorRecur(dd,f,g); 00482 } while (dd->reordered == 1); 00483 return(res); 00484 00485 } /* end of Cudd_bddXor */
Function********************************************************************
Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the variables in cube.]
Description [Takes the exclusive OR of two BDDs and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the result is successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddUnivAbstract Cudd_bddExistAbstract Cudd_bddAndAbstract]
Definition at line 165 of file cuddBddAbs.c.
00170 { 00171 DdNode *res; 00172 00173 if (bddCheckPositiveCube(manager, cube) == 0) { 00174 (void) fprintf(manager->err, 00175 "Error: Can only abstract positive cubes\n"); 00176 manager->errorCode = CUDD_INVALID_ARG; 00177 return(NULL); 00178 } 00179 00180 do { 00181 manager->reordered = 0; 00182 res = cuddBddXorExistAbstractRecur(manager, f, g, cube); 00183 } while (manager->reordered == 1); 00184 00185 return(res); 00186 00187 } /* end of Cudd_bddXorExistAbstract */
DdNode* Cudd_BiasedOverApprox | ( | DdManager * | dd, | |
DdNode * | f, | |||
DdNode * | b, | |||
int | numVars, | |||
int | threshold, | |||
double | quality1, | |||
double | quality0 | |||
) |
Function********************************************************************
Synopsis [Extracts a dense superset from a BDD with the biased underapproximation method.]
Description [Extracts a dense superset from a BDD. The procedure is identical to the underapproximation procedure except for the fact that it works on the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. Returns a pointer to the BDD of the superset if successful. NULL if intermediate result causes the procedure to run out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]
SideEffects [None]
SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_RemapOverApprox Cudd_BiasedUnderApprox Cudd_ReadSize]
Definition at line 459 of file cuddApprox.c.
00467 { 00468 DdNode *subset, *g; 00469 00470 g = Cudd_Not(f); 00471 do { 00472 dd->reordered = 0; 00473 subset = cuddBiasedUnderApprox(dd, g, b, numVars, threshold, quality1, 00474 quality0); 00475 } while (dd->reordered == 1); 00476 00477 return(Cudd_NotCond(subset, (subset != NULL))); 00478 00479 } /* end of Cudd_BiasedOverApprox */
DdNode* Cudd_BiasedUnderApprox | ( | DdManager * | dd, | |
DdNode * | f, | |||
DdNode * | b, | |||
int | numVars, | |||
int | threshold, | |||
double | quality1, | |||
double | quality0 | |||
) |
Function********************************************************************
Synopsis [Extracts a dense subset from a BDD with the biased underapproximation method.]
Description [Extracts a dense subset from a BDD. This procedure uses a biased remapping technique and density as the cost function. The bias is a function. This procedure tries to approximate where the bias is 0 and preserve the given function where the bias is 1. Returns a pointer to the BDD of the subset if successful. NULL if the procedure runs out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will cause overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]
SideEffects [None]
SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox Cudd_RemapUnderApprox Cudd_ReadSize]
Definition at line 409 of file cuddApprox.c.
00417 { 00418 DdNode *subset; 00419 00420 do { 00421 dd->reordered = 0; 00422 subset = cuddBiasedUnderApprox(dd, f, b, numVars, threshold, quality1, 00423 quality0); 00424 } while (dd->reordered == 1); 00425 00426 return(subset); 00427 00428 } /* end of Cudd_BiasedUnderApprox */
int Cudd_CheckKeys | ( | DdManager * | table | ) |
Function********************************************************************
Synopsis [Checks for several conditions that should not occur.]
Description [Checks for the following conditions:
Reports the average length of non-empty lists. Returns the number of subtables for which the number of keys is wrong.]
SideEffects [None]
SeeAlso [Cudd_DebugCheck]
Definition at line 454 of file cuddCheck.c.
00456 { 00457 int size; 00458 int i,j; 00459 DdNodePtr *nodelist; 00460 DdNode *node; 00461 DdNode *sentinel = &(table->sentinel); 00462 DdSubtable *subtable; 00463 int keys; 00464 int dead; 00465 int count = 0; 00466 int totalKeys = 0; 00467 int totalSlots = 0; 00468 int totalDead = 0; 00469 int nonEmpty = 0; 00470 unsigned int slots; 00471 int logSlots; 00472 int shift; 00473 00474 size = table->size; 00475 00476 for (i = 0; i < size; i++) { 00477 subtable = &(table->subtables[i]); 00478 nodelist = subtable->nodelist; 00479 keys = subtable->keys; 00480 dead = subtable->dead; 00481 totalKeys += keys; 00482 slots = subtable->slots; 00483 shift = subtable->shift; 00484 logSlots = sizeof(int) * 8 - shift; 00485 if (((slots >> logSlots) << logSlots) != slots) { 00486 (void) fprintf(table->err, 00487 "Unique table %d is not the right power of 2\n", i); 00488 (void) fprintf(table->err, 00489 " slots = %u shift = %d\n", slots, shift); 00490 } 00491 totalSlots += slots; 00492 totalDead += dead; 00493 for (j = 0; (unsigned) j < slots; j++) { 00494 node = nodelist[j]; 00495 if (node != sentinel) { 00496 nonEmpty++; 00497 } 00498 while (node != sentinel) { 00499 keys--; 00500 if (node->ref == 0) { 00501 dead--; 00502 } 00503 node = node->next; 00504 } 00505 } 00506 if (keys != 0) { 00507 (void) fprintf(table->err, "Wrong number of keys found \ 00508 in unique table %d (difference=%d)\n", i, keys); 00509 count++; 00510 } 00511 if (dead != 0) { 00512 (void) fprintf(table->err, "Wrong number of dead found \ 00513 in unique table no. %d (difference=%d)\n", i, dead); 00514 } 00515 } /* for each BDD/ADD subtable */ 00516 00517 /* Check the ZDD subtables. */ 00518 size = table->sizeZ; 00519 00520 for (i = 0; i < size; i++) { 00521 subtable = &(table->subtableZ[i]); 00522 nodelist = subtable->nodelist; 00523 keys = subtable->keys; 00524 dead = subtable->dead; 00525 totalKeys += keys; 00526 totalSlots += subtable->slots; 00527 totalDead += dead; 00528 for (j = 0; (unsigned) j < subtable->slots; j++) { 00529 node = nodelist[j]; 00530 if (node != NULL) { 00531 nonEmpty++; 00532 } 00533 while (node != NULL) { 00534 keys--; 00535 if (node->ref == 0) { 00536 dead--; 00537 } 00538 node = node->next; 00539 } 00540 } 00541 if (keys != 0) { 00542 (void) fprintf(table->err, "Wrong number of keys found \ 00543 in ZDD unique table no. %d (difference=%d)\n", i, keys); 00544 count++; 00545 } 00546 if (dead != 0) { 00547 (void) fprintf(table->err, "Wrong number of dead found \ 00548 in ZDD unique table no. %d (difference=%d)\n", i, dead); 00549 } 00550 } /* for each ZDD subtable */ 00551 00552 /* Check the constant table. */ 00553 subtable = &(table->constants); 00554 nodelist = subtable->nodelist; 00555 keys = subtable->keys; 00556 dead = subtable->dead; 00557 totalKeys += keys; 00558 totalSlots += subtable->slots; 00559 totalDead += dead; 00560 for (j = 0; (unsigned) j < subtable->slots; j++) { 00561 node = nodelist[j]; 00562 if (node != NULL) { 00563 nonEmpty++; 00564 } 00565 while (node != NULL) { 00566 keys--; 00567 if (node->ref == 0) { 00568 dead--; 00569 } 00570 node = node->next; 00571 } 00572 } 00573 if (keys != 0) { 00574 (void) fprintf(table->err, "Wrong number of keys found \ 00575 in the constant table (difference=%d)\n", keys); 00576 count++; 00577 } 00578 if (dead != 0) { 00579 (void) fprintf(table->err, "Wrong number of dead found \ 00580 in the constant table (difference=%d)\n", dead); 00581 } 00582 if ((unsigned) totalKeys != table->keys + table->keysZ) { 00583 (void) fprintf(table->err, "Wrong number of total keys found \ 00584 (difference=%d)\n", (int) (totalKeys-table->keys)); 00585 } 00586 if ((unsigned) totalSlots != table->slots) { 00587 (void) fprintf(table->err, "Wrong number of total slots found \ 00588 (difference=%d)\n", (int) (totalSlots-table->slots)); 00589 } 00590 if (table->minDead != (unsigned) (table->gcFrac * table->slots)) { 00591 (void) fprintf(table->err, "Wrong number of minimum dead found \ 00592 (%u vs. %u)\n", table->minDead, 00593 (unsigned) (table->gcFrac * (double) table->slots)); 00594 } 00595 if ((unsigned) totalDead != table->dead + table->deadZ) { 00596 (void) fprintf(table->err, "Wrong number of total dead found \ 00597 (difference=%d)\n", (int) (totalDead-table->dead)); 00598 } 00599 (void)printf("Average length of non-empty lists = %g\n", 00600 (double) table->keys / (double) nonEmpty); 00601 00602 return(count); 00603 00604 } /* end of Cudd_CheckKeys */
int Cudd_CheckZeroRef | ( | DdManager * | manager | ) |
Function********************************************************************
Synopsis [Checks the unique table for nodes with non-zero reference counts.]
Description [Checks the unique table for nodes with non-zero reference counts. It is normally called before Cudd_Quit to make sure that there are no memory leaks due to missing Cudd_RecursiveDeref's. Takes into account that reference counts may saturate and that the basic constants and the projection functions are referenced by the manager. Returns the number of nodes with non-zero reference count. (Except for the cases mentioned above.)]
SideEffects [None]
SeeAlso []
Definition at line 462 of file cuddRef.c.
00464 { 00465 int size; 00466 int i, j; 00467 int remain; /* the expected number of remaining references to one */ 00468 DdNodePtr *nodelist; 00469 DdNode *node; 00470 DdNode *sentinel = &(manager->sentinel); 00471 DdSubtable *subtable; 00472 int count = 0; 00473 int index; 00474 00475 #ifndef DD_NO_DEATH_ROW 00476 cuddClearDeathRow(manager); 00477 #endif 00478 00479 /* First look at the BDD/ADD subtables. */ 00480 remain = 1; /* reference from the manager */ 00481 size = manager->size; 00482 remain += 2 * size; /* reference from the BDD projection functions */ 00483 00484 for (i = 0; i < size; i++) { 00485 subtable = &(manager->subtables[i]); 00486 nodelist = subtable->nodelist; 00487 for (j = 0; (unsigned) j < subtable->slots; j++) { 00488 node = nodelist[j]; 00489 while (node != sentinel) { 00490 if (node->ref != 0 && node->ref != DD_MAXREF) { 00491 index = (int) node->index; 00492 if (node != manager->vars[index]) { 00493 count++; 00494 } else { 00495 if (node->ref != 1) { 00496 count++; 00497 } 00498 } 00499 } 00500 node = node->next; 00501 } 00502 } 00503 } 00504 00505 /* Then look at the ZDD subtables. */ 00506 size = manager->sizeZ; 00507 if (size) /* references from ZDD universe */ 00508 remain += 2; 00509 00510 for (i = 0; i < size; i++) { 00511 subtable = &(manager->subtableZ[i]); 00512 nodelist = subtable->nodelist; 00513 for (j = 0; (unsigned) j < subtable->slots; j++) { 00514 node = nodelist[j]; 00515 while (node != NULL) { 00516 if (node->ref != 0 && node->ref != DD_MAXREF) { 00517 index = (int) node->index; 00518 if (node == manager->univ[manager->permZ[index]]) { 00519 if (node->ref > 2) { 00520 count++; 00521 } 00522 } else { 00523 count++; 00524 } 00525 } 00526 node = node->next; 00527 } 00528 } 00529 } 00530 00531 /* Now examine the constant table. Plusinfinity, minusinfinity, and 00532 ** zero are referenced by the manager. One is referenced by the 00533 ** manager, by the ZDD universe, and by all projection functions. 00534 ** All other nodes should have no references. 00535 */ 00536 nodelist = manager->constants.nodelist; 00537 for (j = 0; (unsigned) j < manager->constants.slots; j++) { 00538 node = nodelist[j]; 00539 while (node != NULL) { 00540 if (node->ref != 0 && node->ref != DD_MAXREF) { 00541 if (node == manager->one) { 00542 if ((int) node->ref != remain) { 00543 count++; 00544 } 00545 } else if (node == manager->zero || 00546 node == manager->plusinfinity || 00547 node == manager->minusinfinity) { 00548 if (node->ref != 1) { 00549 count++; 00550 } 00551 } else { 00552 count++; 00553 } 00554 } 00555 node = node->next; 00556 } 00557 } 00558 return(count); 00559 00560 } /* end of Cudd_CheckZeroRef */
int Cudd_ClassifySupport | ( | DdManager * | dd, | |
DdNode * | f, | |||
DdNode * | g, | |||
DdNode ** | common, | |||
DdNode ** | onlyF, | |||
DdNode ** | onlyG | |||
) |
Function********************************************************************
Synopsis [Classifies the variables in the support of two DDs.]
Description [Classifies the variables in the support of two DDs f
and g
, depending on whther they appear in both DDs, only in f
, or only in g
. Returns 1 if successful; 0 otherwise.]
SideEffects [The cubes of the three classes of variables are returned as side effects.]
SeeAlso [Cudd_Support Cudd_VectorSupport]
Definition at line 1081 of file cuddUtil.c.
01088 { 01089 int *supportF, *supportG; 01090 DdNode *tmp, *var; 01091 int i,j; 01092 int size; 01093 01094 /* Allocate and initialize support arrays for ddSupportStep. */ 01095 size = ddMax(dd->size, dd->sizeZ); 01096 supportF = ALLOC(int,size); 01097 if (supportF == NULL) { 01098 dd->errorCode = CUDD_MEMORY_OUT; 01099 return(0); 01100 } 01101 supportG = ALLOC(int,size); 01102 if (supportG == NULL) { 01103 dd->errorCode = CUDD_MEMORY_OUT; 01104 FREE(supportF); 01105 return(0); 01106 } 01107 for (i = 0; i < size; i++) { 01108 supportF[i] = 0; 01109 supportG[i] = 0; 01110 } 01111 01112 /* Compute supports and clean up markers. */ 01113 ddSupportStep(Cudd_Regular(f),supportF); 01114 ddClearFlag(Cudd_Regular(f)); 01115 ddSupportStep(Cudd_Regular(g),supportG); 01116 ddClearFlag(Cudd_Regular(g)); 01117 01118 /* Classify variables and create cubes. */ 01119 *common = *onlyF = *onlyG = DD_ONE(dd); 01120 cuddRef(*common); cuddRef(*onlyF); cuddRef(*onlyG); 01121 for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ 01122 i = (j >= dd->size) ? j : dd->invperm[j]; 01123 if (supportF[i] == 0 && supportG[i] == 0) continue; 01124 var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); 01125 cuddRef(var); 01126 if (supportG[i] == 0) { 01127 tmp = Cudd_bddAnd(dd,*onlyF,var); 01128 if (tmp == NULL) { 01129 Cudd_RecursiveDeref(dd,*common); 01130 Cudd_RecursiveDeref(dd,*onlyF); 01131 Cudd_RecursiveDeref(dd,*onlyG); 01132 Cudd_RecursiveDeref(dd,var); 01133 FREE(supportF); FREE(supportG); 01134 return(0); 01135 } 01136 cuddRef(tmp); 01137 Cudd_RecursiveDeref(dd,*onlyF); 01138 *onlyF = tmp; 01139 } else if (supportF[i] == 0) { 01140 tmp = Cudd_bddAnd(dd,*onlyG,var); 01141 if (tmp == NULL) { 01142 Cudd_RecursiveDeref(dd,*common); 01143 Cudd_RecursiveDeref(dd,*onlyF); 01144 Cudd_RecursiveDeref(dd,*onlyG); 01145 Cudd_RecursiveDeref(dd,var); 01146 FREE(supportF); FREE(supportG); 01147 return(0); 01148 } 01149 cuddRef(tmp); 01150 Cudd_RecursiveDeref(dd,*onlyG); 01151 *onlyG = tmp; 01152 } else { 01153 tmp = Cudd_bddAnd(dd,*common,var); 01154 if (tmp == NULL) { 01155 Cudd_RecursiveDeref(dd,*common); 01156 Cudd_RecursiveDeref(dd,*onlyF); 01157 Cudd_RecursiveDeref(dd,*onlyG); 01158 Cudd_RecursiveDeref(dd,var); 01159 FREE(supportF); FREE(supportG); 01160 return(0); 01161 } 01162 cuddRef(tmp); 01163 Cudd_RecursiveDeref(dd,*common); 01164 *common = tmp; 01165 } 01166 Cudd_RecursiveDeref(dd,var); 01167 } 01168 01169 FREE(supportF); FREE(supportG); 01170 cuddDeref(*common); cuddDeref(*onlyF); cuddDeref(*onlyG); 01171 return(1); 01172 01173 } /* end of Cudd_ClassifySupport */
void Cudd_ClearErrorCode | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Clear the error code of a manager.]
Description []
SideEffects [None]
SeeAlso [Cudd_ReadErrorCode]
Definition at line 3629 of file cuddAPI.c.
03631 { 03632 dd->errorCode = CUDD_NO_ERROR; 03633 03634 } /* end of Cudd_ClearErrorCode */
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Computes the cofactor of f with respect to g.]
Description [Computes the cofactor of f with respect to g; g must be the BDD or the ADD of a cube. Returns a pointer to the cofactor if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddConstrain Cudd_bddRestrict]
Definition at line 119 of file cuddCof.c.
00123 { 00124 DdNode *res,*zero; 00125 00126 zero = Cudd_Not(DD_ONE(dd)); 00127 if (g == zero || g == DD_ZERO(dd)) { 00128 (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n"); 00129 dd->errorCode = CUDD_INVALID_ARG; 00130 return(NULL); 00131 } 00132 do { 00133 dd->reordered = 0; 00134 res = cuddCofactorRecur(dd,f,g); 00135 } while (dd->reordered == 1); 00136 return(res); 00137 00138 } /* end of Cudd_Cofactor */
AutomaticEnd Function********************************************************************
Synopsis [Computes the fraction of minterms in the on-set of all the positive cofactors of a BDD or ADD.]
Description [Computes the fraction of minterms in the on-set of all the positive cofactors of DD. Returns the pointer to an array of doubles if successful; NULL otherwise. The array has as many positions as there are BDD variables in the manager plus one. The last position of the array contains the fraction of the minterms in the ON-set of the function represented by the BDD or ADD. The other positions of the array hold the variable signatures.]
SideEffects [None]
Definition at line 127 of file cuddSign.c.
00130 { 00131 st_table *table; 00132 double *values; 00133 double *result = NULL; 00134 int i, firstLevel; 00135 00136 #ifdef DD_STATS 00137 long startTime; 00138 startTime = util_cpu_time(); 00139 num_calls = 0; 00140 table_mem = sizeof(st_table); 00141 #endif 00142 00143 table = st_init_table(st_ptrcmp, st_ptrhash); 00144 if (table == NULL) { 00145 (void) fprintf(dd->err, 00146 "out-of-memory, couldn't measure DD cofactors.\n"); 00147 dd->errorCode = CUDD_MEMORY_OUT; 00148 return(NULL); 00149 } 00150 size = dd->size; 00151 values = ddCofMintermAux(dd, node, table); 00152 if (values != NULL) { 00153 result = ALLOC(double,size + 1); 00154 if (result != NULL) { 00155 #ifdef DD_STATS 00156 table_mem += (size + 1) * sizeof(double); 00157 #endif 00158 if (Cudd_IsConstant(node)) 00159 firstLevel = 1; 00160 else 00161 firstLevel = cuddI(dd,Cudd_Regular(node)->index); 00162 for (i = 0; i < size; i++) { 00163 if (i >= cuddI(dd,Cudd_Regular(node)->index)) { 00164 result[dd->invperm[i]] = values[i - firstLevel]; 00165 } else { 00166 result[dd->invperm[i]] = values[size - firstLevel]; 00167 } 00168 } 00169 result[size] = values[size - firstLevel]; 00170 } else { 00171 dd->errorCode = CUDD_MEMORY_OUT; 00172 } 00173 } 00174 00175 #ifdef DD_STATS 00176 table_mem += table->num_bins * sizeof(st_table_entry *); 00177 #endif 00178 if (Cudd_Regular(node)->ref == 1) FREE(values); 00179 st_foreach(table, cuddStCountfree, NULL); 00180 st_free_table(table); 00181 #ifdef DD_STATS 00182 (void) fprintf(dd->out,"Number of calls: %d\tTable memory: %d bytes\n", 00183 num_calls, table_mem); 00184 (void) fprintf(dd->out,"Time to compute measures: %s\n", 00185 util_print_time(util_cpu_time() - startTime)); 00186 #endif 00187 if (result == NULL) { 00188 (void) fprintf(dd->out, 00189 "out-of-memory, couldn't measure DD cofactors.\n"); 00190 dd->errorCode = CUDD_MEMORY_OUT; 00191 } 00192 return(result); 00193 00194 } /* end of Cudd_CofMinterm */
int Cudd_CountLeaves | ( | DdNode * | node | ) |
Function********************************************************************
Synopsis [Counts the number of leaves in a DD.]
Description [Counts the number of leaves in a DD. Returns the number of leaves in the DD rooted at node if successful; CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_PrintDebug]
Definition at line 1190 of file cuddUtil.c.
01192 { 01193 int i; 01194 01195 i = ddLeavesInt(Cudd_Regular(node)); 01196 ddClearFlag(Cudd_Regular(node)); 01197 return(i); 01198 01199 } /* end of Cudd_CountLeaves */
Function********************************************************************
Synopsis [Counts the number of minterms of a DD.]
Description [Counts the number of minterms of a DD. The function is assumed to depend on nvars variables. The minterm count is represented as a double, to allow for a larger number of variables. Returns the number of minterms of the function rooted at node if successful; (double) CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_PrintDebug Cudd_CountPath]
Definition at line 574 of file cuddUtil.c.
00578 { 00579 double max; 00580 DdHashTable *table; 00581 double res; 00582 CUDD_VALUE_TYPE epsilon; 00583 00584 background = manager->background; 00585 zero = Cudd_Not(manager->one); 00586 00587 max = pow(2.0,(double)nvars); 00588 table = cuddHashTableInit(manager,1,2); 00589 if (table == NULL) { 00590 return((double)CUDD_OUT_OF_MEM); 00591 } 00592 epsilon = Cudd_ReadEpsilon(manager); 00593 Cudd_SetEpsilon(manager,(CUDD_VALUE_TYPE)0.0); 00594 res = ddCountMintermAux(node,max,table); 00595 cuddHashTableQuit(table); 00596 Cudd_SetEpsilon(manager,epsilon); 00597 00598 return(res); 00599 00600 } /* end of Cudd_CountMinterm */
double Cudd_CountPath | ( | DdNode * | node | ) |
Function********************************************************************
Synopsis [Counts the number of paths of a DD.]
Description [Counts the number of paths of a DD. Paths to all terminal nodes are counted. The path count is represented as a double, to allow for a larger number of variables. Returns the number of paths of the function rooted at node if successful; (double) CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_CountMinterm]
Definition at line 619 of file cuddUtil.c.
00621 { 00622 00623 st_table *table; 00624 double i; 00625 00626 table = st_init_table(st_ptrcmp,st_ptrhash); 00627 if (table == NULL) { 00628 return((double)CUDD_OUT_OF_MEM); 00629 } 00630 i = ddCountPathAux(Cudd_Regular(node),table); 00631 st_foreach(table, cuddStCountfree, NULL); 00632 st_free_table(table); 00633 return(i); 00634 00635 } /* end of Cudd_CountPath */
double Cudd_CountPathsToNonZero | ( | DdNode * | node | ) |
Function********************************************************************
Synopsis [Counts the number of paths to a non-zero terminal of a DD.]
Description [Counts the number of paths to a non-zero terminal of a DD. The path count is represented as a double, to allow for a larger number of variables. Returns the number of paths of the function rooted at node.]
SideEffects [None]
SeeAlso [Cudd_CountMinterm Cudd_CountPath]
Definition at line 703 of file cuddUtil.c.
00705 { 00706 00707 st_table *table; 00708 double i; 00709 00710 table = st_init_table(st_ptrcmp,st_ptrhash); 00711 if (table == NULL) { 00712 return((double)CUDD_OUT_OF_MEM); 00713 } 00714 i = ddCountPathsToNonZero(node,table); 00715 st_foreach(table, cuddStCountfree, NULL); 00716 st_free_table(table); 00717 return(i); 00718 00719 } /* end of Cudd_CountPathsToNonZero */
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 [Builds the BDD of a cube from a positional array.]
Description [Builds a cube from a positional array. The array must have one integer entry for each BDD variable. If the i-th entry is 1, the variable of index i appears in true form in the cube; If the i-th entry is 0, the variable of index i appears complemented in the cube; otherwise the variable does not appear in the cube. Returns a pointer to the BDD for the cube if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddComputeCube Cudd_IndicesToCube Cudd_BddToCubeArray]
Definition at line 2294 of file cuddUtil.c.
02297 { 02298 DdNode *cube, *var, *tmp; 02299 int i; 02300 int size = Cudd_ReadSize(dd); 02301 02302 cube = DD_ONE(dd); 02303 cuddRef(cube); 02304 for (i = size - 1; i >= 0; i--) { 02305 if ((array[i] & ~1) == 0) { 02306 var = Cudd_bddIthVar(dd,i); 02307 tmp = Cudd_bddAnd(dd,cube,Cudd_NotCond(var,array[i]==0)); 02308 if (tmp == NULL) { 02309 Cudd_RecursiveDeref(dd,cube); 02310 return(NULL); 02311 } 02312 cuddRef(tmp); 02313 Cudd_RecursiveDeref(dd,cube); 02314 cube = tmp; 02315 } 02316 } 02317 cuddDeref(cube); 02318 return(cube); 02319 02320 } /* end of Cudd_CubeArrayToBdd */
int Cudd_DagSize | ( | DdNode * | node | ) |
Function********************************************************************
Synopsis [Counts the number of nodes in a DD.]
Description [Counts the number of nodes in a DD. Returns the number of nodes in the graph rooted at node.]
SideEffects [None]
SeeAlso [Cudd_SharingSize Cudd_PrintDebug]
Definition at line 438 of file cuddUtil.c.
00440 { 00441 int i; 00442 00443 i = ddDagInt(Cudd_Regular(node)); 00444 ddClearFlag(Cudd_Regular(node)); 00445 00446 return(i); 00447 00448 } /* end of Cudd_DagSize */
int Cudd_DeadAreCounted | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Tells whether dead nodes are counted towards triggering reordering.]
Description [Tells whether dead nodes are counted towards triggering reordering. Returns 1 if dead nodes are counted; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_TurnOnCountDead Cudd_TurnOffCountDead]
Definition at line 2581 of file cuddAPI.c.
02583 { 02584 return(dd->countDead == 0 ? 1 : 0); 02585 02586 } /* end of Cudd_DeadAreCounted */
int Cudd_DebugCheck | ( | DdManager * | table | ) |
AutomaticEnd Function********************************************************************
Synopsis [Checks for inconsistencies in the DD heap.]
Description [Checks for inconsistencies in the DD heap:
Returns 0 if no inconsistencies are found; DD_OUT_OF_MEM if there is not enough memory; 1 otherwise.]
SideEffects [None]
SeeAlso [Cudd_CheckKeys]
Definition at line 138 of file cuddCheck.c.
00140 { 00141 unsigned int i; 00142 int j,count; 00143 int slots; 00144 DdNodePtr *nodelist; 00145 DdNode *f; 00146 DdNode *sentinel = &(table->sentinel); 00147 st_table *edgeTable; /* stores internal ref count for each node */ 00148 st_generator *gen; 00149 int flag = 0; 00150 int totalNode; 00151 int deadNode; 00152 int index; 00153 00154 00155 edgeTable = st_init_table(st_ptrcmp,st_ptrhash); 00156 if (edgeTable == NULL) return(CUDD_OUT_OF_MEM); 00157 00158 /* Check the BDD/ADD subtables. */ 00159 for (i = 0; i < (unsigned) table->size; i++) { 00160 index = table->invperm[i]; 00161 if (i != (unsigned) table->perm[index]) { 00162 (void) fprintf(table->err, 00163 "Permutation corrupted: invperm[%u] = %d\t perm[%d] = %d\n", 00164 i, index, index, table->perm[index]); 00165 } 00166 nodelist = table->subtables[i].nodelist; 00167 slots = table->subtables[i].slots; 00168 00169 totalNode = 0; 00170 deadNode = 0; 00171 for (j = 0; j < slots; j++) { /* for each subtable slot */ 00172 f = nodelist[j]; 00173 while (f != sentinel) { 00174 totalNode++; 00175 if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { 00176 if ((int) f->index != index) { 00177 (void) fprintf(table->err, 00178 "Error: node has illegal index\n"); 00179 cuddPrintNode(f,table->err); 00180 flag = 1; 00181 } 00182 if ((unsigned) cuddI(table,cuddT(f)->index) <= i || 00183 (unsigned) cuddI(table,Cudd_Regular(cuddE(f))->index) 00184 <= i) { 00185 (void) fprintf(table->err, 00186 "Error: node has illegal children\n"); 00187 cuddPrintNode(f,table->err); 00188 flag = 1; 00189 } 00190 if (Cudd_Regular(cuddT(f)) != cuddT(f)) { 00191 (void) fprintf(table->err, 00192 "Error: node has illegal form\n"); 00193 cuddPrintNode(f,table->err); 00194 flag = 1; 00195 } 00196 if (cuddT(f) == cuddE(f)) { 00197 (void) fprintf(table->err, 00198 "Error: node has identical children\n"); 00199 cuddPrintNode(f,table->err); 00200 flag = 1; 00201 } 00202 if (cuddT(f)->ref == 0 || Cudd_Regular(cuddE(f))->ref == 0) { 00203 (void) fprintf(table->err, 00204 "Error: live node has dead children\n"); 00205 cuddPrintNode(f,table->err); 00206 flag =1; 00207 } 00208 /* Increment the internal reference count for the 00209 ** then child of the current node. 00210 */ 00211 if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { 00212 count++; 00213 } else { 00214 count = 1; 00215 } 00216 if (st_insert(edgeTable,(char *)cuddT(f), 00217 (char *)(long)count) == ST_OUT_OF_MEM) { 00218 st_free_table(edgeTable); 00219 return(CUDD_OUT_OF_MEM); 00220 } 00221 00222 /* Increment the internal reference count for the 00223 ** else child of the current node. 00224 */ 00225 if (st_lookup_int(edgeTable,(char *)Cudd_Regular(cuddE(f)), 00226 &count)) { 00227 count++; 00228 } else { 00229 count = 1; 00230 } 00231 if (st_insert(edgeTable,(char *)Cudd_Regular(cuddE(f)), 00232 (char *)(long)count) == ST_OUT_OF_MEM) { 00233 st_free_table(edgeTable); 00234 return(CUDD_OUT_OF_MEM); 00235 } 00236 } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { 00237 deadNode++; 00238 #if 0 00239 debugCheckParent(table,f); 00240 #endif 00241 } else { 00242 fprintf(table->err, 00243 "Error: node has illegal Then or Else pointers\n"); 00244 cuddPrintNode(f,table->err); 00245 flag = 1; 00246 } 00247 00248 f = f->next; 00249 } /* for each element of the collision list */ 00250 } /* for each subtable slot */ 00251 00252 if ((unsigned) totalNode != table->subtables[i].keys) { 00253 fprintf(table->err,"Error: wrong number of total nodes\n"); 00254 flag = 1; 00255 } 00256 if ((unsigned) deadNode != table->subtables[i].dead) { 00257 fprintf(table->err,"Error: wrong number of dead nodes\n"); 00258 flag = 1; 00259 } 00260 } /* for each BDD/ADD subtable */ 00261 00262 /* Check the ZDD subtables. */ 00263 for (i = 0; i < (unsigned) table->sizeZ; i++) { 00264 index = table->invpermZ[i]; 00265 if (i != (unsigned) table->permZ[index]) { 00266 (void) fprintf(table->err, 00267 "Permutation corrupted: invpermZ[%u] = %d\t permZ[%d] = %d in ZDD\n", 00268 i, index, index, table->permZ[index]); 00269 } 00270 nodelist = table->subtableZ[i].nodelist; 00271 slots = table->subtableZ[i].slots; 00272 00273 totalNode = 0; 00274 deadNode = 0; 00275 for (j = 0; j < slots; j++) { /* for each subtable slot */ 00276 f = nodelist[j]; 00277 while (f != NULL) { 00278 totalNode++; 00279 if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { 00280 if ((int) f->index != index) { 00281 (void) fprintf(table->err, 00282 "Error: ZDD node has illegal index\n"); 00283 cuddPrintNode(f,table->err); 00284 flag = 1; 00285 } 00286 if (Cudd_IsComplement(cuddT(f)) || 00287 Cudd_IsComplement(cuddE(f))) { 00288 (void) fprintf(table->err, 00289 "Error: ZDD node has complemented children\n"); 00290 cuddPrintNode(f,table->err); 00291 flag = 1; 00292 } 00293 if ((unsigned) cuddIZ(table,cuddT(f)->index) <= i || 00294 (unsigned) cuddIZ(table,cuddE(f)->index) <= i) { 00295 (void) fprintf(table->err, 00296 "Error: ZDD node has illegal children\n"); 00297 cuddPrintNode(f,table->err); 00298 cuddPrintNode(cuddT(f),table->err); 00299 cuddPrintNode(cuddE(f),table->err); 00300 flag = 1; 00301 } 00302 if (cuddT(f) == DD_ZERO(table)) { 00303 (void) fprintf(table->err, 00304 "Error: ZDD node has zero then child\n"); 00305 cuddPrintNode(f,table->err); 00306 flag = 1; 00307 } 00308 if (cuddT(f)->ref == 0 || cuddE(f)->ref == 0) { 00309 (void) fprintf(table->err, 00310 "Error: ZDD live node has dead children\n"); 00311 cuddPrintNode(f,table->err); 00312 flag =1; 00313 } 00314 /* Increment the internal reference count for the 00315 ** then child of the current node. 00316 */ 00317 if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { 00318 count++; 00319 } else { 00320 count = 1; 00321 } 00322 if (st_insert(edgeTable,(char *)cuddT(f), 00323 (char *)(long)count) == ST_OUT_OF_MEM) { 00324 st_free_table(edgeTable); 00325 return(CUDD_OUT_OF_MEM); 00326 } 00327 00328 /* Increment the internal reference count for the 00329 ** else child of the current node. 00330 */ 00331 if (st_lookup_int(edgeTable,(char *)cuddE(f),&count)) { 00332 count++; 00333 } else { 00334 count = 1; 00335 } 00336 if (st_insert(edgeTable,(char *)cuddE(f), 00337 (char *)(long)count) == ST_OUT_OF_MEM) { 00338 st_free_table(edgeTable); 00339 table->errorCode = CUDD_MEMORY_OUT; 00340 return(CUDD_OUT_OF_MEM); 00341 } 00342 } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { 00343 deadNode++; 00344 #if 0 00345 debugCheckParent(table,f); 00346 #endif 00347 } else { 00348 fprintf(table->err, 00349 "Error: ZDD node has illegal Then or Else pointers\n"); 00350 cuddPrintNode(f,table->err); 00351 flag = 1; 00352 } 00353 00354 f = f->next; 00355 } /* for each element of the collision list */ 00356 } /* for each subtable slot */ 00357 00358 if ((unsigned) totalNode != table->subtableZ[i].keys) { 00359 fprintf(table->err, 00360 "Error: wrong number of total nodes in ZDD\n"); 00361 flag = 1; 00362 } 00363 if ((unsigned) deadNode != table->subtableZ[i].dead) { 00364 fprintf(table->err, 00365 "Error: wrong number of dead nodes in ZDD\n"); 00366 flag = 1; 00367 } 00368 } /* for each ZDD subtable */ 00369 00370 /* Check the constant table. */ 00371 nodelist = table->constants.nodelist; 00372 slots = table->constants.slots; 00373 00374 totalNode = 0; 00375 deadNode = 0; 00376 for (j = 0; j < slots; j++) { 00377 f = nodelist[j]; 00378 while (f != NULL) { 00379 totalNode++; 00380 if (f->ref != 0) { 00381 if (f->index != CUDD_CONST_INDEX) { 00382 fprintf(table->err,"Error: node has illegal index\n"); 00383 #if SIZEOF_VOID_P == 8 00384 fprintf(table->err, 00385 " node 0x%lx, id = %u, ref = %u, value = %g\n", 00386 (ptruint)f,f->index,f->ref,cuddV(f)); 00387 #else 00388 fprintf(table->err, 00389 " node 0x%x, id = %hu, ref = %hu, value = %g\n", 00390 (ptruint)f,f->index,f->ref,cuddV(f)); 00391 #endif 00392 flag = 1; 00393 } 00394 } else { 00395 deadNode++; 00396 } 00397 f = f->next; 00398 } 00399 } 00400 if ((unsigned) totalNode != table->constants.keys) { 00401 (void) fprintf(table->err, 00402 "Error: wrong number of total nodes in constants\n"); 00403 flag = 1; 00404 } 00405 if ((unsigned) deadNode != table->constants.dead) { 00406 (void) fprintf(table->err, 00407 "Error: wrong number of dead nodes in constants\n"); 00408 flag = 1; 00409 } 00410 gen = st_init_gen(edgeTable); 00411 while (st_gen(gen, &f, &count)) { 00412 if (count > (int)(f->ref) && f->ref != DD_MAXREF) { 00413 #if SIZEOF_VOID_P == 8 00414 fprintf(table->err,"ref count error at node 0x%lx, count = %d, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); 00415 #else 00416 fprintf(table->err,"ref count error at node 0x%x, count = %d, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); 00417 #endif 00418 debugFindParent(table,f); 00419 flag = 1; 00420 } 00421 } 00422 st_free_gen(gen); 00423 st_free_table(edgeTable); 00424 00425 return (flag); 00426 00427 } /* end of Cudd_DebugCheck */
Function********************************************************************
Synopsis [Determines whether a BDD is negative unate in a variable.]
Description [Determines whether the function represented by BDD f is negative unate (monotonic decreasing) in variable i. Returns the constant one is f is unate and the (logical) constant zero if it is not. This function does not generate any new nodes.]
SideEffects [None]
SeeAlso [Cudd_Increasing]
Definition at line 413 of file cuddSat.c.
00417 { 00418 unsigned int topf, level; 00419 DdNode *F, *fv, *fvn, *res; 00420 DD_CTFP cacheOp; 00421 00422 statLine(dd); 00423 #ifdef DD_DEBUG 00424 assert(0 <= i && i < dd->size); 00425 #endif 00426 00427 F = Cudd_Regular(f); 00428 topf = cuddI(dd,F->index); 00429 00430 /* Check terminal case. If topf > i, f does not depend on var. 00431 ** Therefore, f is unate in i. 00432 */ 00433 level = (unsigned) dd->perm[i]; 00434 if (topf > level) { 00435 return(DD_ONE(dd)); 00436 } 00437 00438 /* From now on, f is not constant. */ 00439 00440 /* Check cache. */ 00441 cacheOp = (DD_CTFP) Cudd_Decreasing; 00442 res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]); 00443 if (res != NULL) { 00444 return(res); 00445 } 00446 00447 /* Compute cofactors. */ 00448 fv = cuddT(F); fvn = cuddE(F); 00449 if (F != f) { 00450 fv = Cudd_Not(fv); 00451 fvn = Cudd_Not(fvn); 00452 } 00453 00454 if (topf == (unsigned) level) { 00455 /* Special case: if fv is regular, fv(1,...,1) = 1; 00456 ** If in addition fvn is complemented, fvn(1,...,1) = 0. 00457 ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not 00458 ** monotonic decreasing in i. 00459 */ 00460 if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) { 00461 return(Cudd_Not(DD_ONE(dd))); 00462 } 00463 res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd)); 00464 } else { 00465 res = Cudd_Decreasing(dd,fv,i); 00466 if (res == DD_ONE(dd)) { 00467 res = Cudd_Decreasing(dd,fvn,i); 00468 } 00469 } 00470 00471 cuddCacheInsert2(dd,cacheOp,f,dd->vars[i],res); 00472 return(res); 00473 00474 } /* end of Cudd_Decreasing */
Function********************************************************************
Synopsis [Decreases the reference count of BDD node n.]
Description [Enqueues node n for later dereferencing. If the queue is full decreases the reference count of the oldest node N to make room for n. If N dies, recursively decreases the reference counts of its children. It is used to dispose of a BDD that is currently not needed, but may be useful again in the near future. The dereferencing proper is done as in Cudd_IterDerefBdd.]
SideEffects [None]
SeeAlso [Cudd_RecursiveDeref Cudd_IterDerefBdd]
Definition at line 270 of file cuddRef.c.
00273 { 00274 DdNode *N; 00275 int ord; 00276 DdNodePtr *stack; 00277 int SP; 00278 00279 unsigned int live = table->keys - table->dead; 00280 if (live > table->peakLiveNodes) { 00281 table->peakLiveNodes = live; 00282 } 00283 00284 n = Cudd_Regular(n); 00285 #ifdef DD_DEBUG 00286 assert(n->ref != 0); 00287 #endif 00288 00289 #ifdef DD_NO_DEATH_ROW 00290 N = n; 00291 #else 00292 if (cuddIsConstant(n) || n->ref > 1) { 00293 #ifdef DD_DEBUG 00294 assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table))); 00295 #endif 00296 cuddSatDec(n->ref); 00297 return; 00298 } 00299 00300 N = table->deathRow[table->nextDead]; 00301 00302 if (N != NULL) { 00303 #endif 00304 #ifdef DD_DEBUG 00305 assert(!Cudd_IsComplement(N)); 00306 #endif 00307 stack = table->stack; 00308 SP = 1; 00309 do { 00310 #ifdef DD_DEBUG 00311 assert(N->ref != 0); 00312 #endif 00313 if (N->ref == 1) { 00314 N->ref = 0; 00315 table->dead++; 00316 #ifdef DD_STATS 00317 table->nodesDropped++; 00318 #endif 00319 ord = table->perm[N->index]; 00320 stack[SP++] = Cudd_Regular(cuddE(N)); 00321 table->subtables[ord].dead++; 00322 N = cuddT(N); 00323 } else { 00324 cuddSatDec(N->ref); 00325 N = stack[--SP]; 00326 } 00327 } while (SP != 0); 00328 #ifndef DD_NO_DEATH_ROW 00329 } 00330 table->deathRow[table->nextDead] = n; 00331 00332 /* Udate insertion point. */ 00333 table->nextDead++; 00334 table->nextDead &= table->deadMask; 00335 #if 0 00336 if (table->nextDead == table->deathRowDepth) { 00337 if (table->deathRowDepth < table->looseUpTo / 2) { 00338 extern void (*MMoutOfMemory)(long); 00339 void (*saveHandler)(long) = MMoutOfMemory; 00340 DdNodePtr *newRow; 00341 MMoutOfMemory = Cudd_OutOfMem; 00342 newRow = REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth); 00343 MMoutOfMemory = saveHandler; 00344 if (newRow == NULL) { 00345 table->nextDead = 0; 00346 } else { 00347 int i; 00348 table->memused += table->deathRowDepth; 00349 i = table->deathRowDepth; 00350 table->deathRowDepth <<= 1; 00351 for (; i < table->deathRowDepth; i++) { 00352 newRow[i] = NULL; 00353 } 00354 table->deadMask = table->deathRowDepth - 1; 00355 table->deathRow = newRow; 00356 } 00357 } else { 00358 table->nextDead = 0; 00359 } 00360 } 00361 #endif 00362 #endif 00363 00364 } /* end of Cudd_DelayedDerefBdd */
Function********************************************************************
Synopsis [Computes the density of a BDD or ADD.]
Description [Computes the density of a BDD or ADD. The density is the ratio of the number of minterms to the number of nodes. If 0 is passed as number of variables, the number of variables existing in the manager is used. Returns the density if successful; (double) CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_CountMinterm Cudd_DagSize]
Definition at line 2798 of file cuddUtil.c.
02802 { 02803 double minterms; 02804 int nodes; 02805 double density; 02806 02807 if (nvars == 0) nvars = dd->size; 02808 minterms = Cudd_CountMinterm(dd,f,nvars); 02809 if (minterms == (double) CUDD_OUT_OF_MEM) return(minterms); 02810 nodes = Cudd_DagSize(f); 02811 density = minterms / (double) nodes; 02812 return(density); 02813 02814 } /* end of Cudd_Density */
void Cudd_Deref | ( | DdNode * | node | ) |
Function********************************************************************
Synopsis [Decreases the reference count of node.]
Description [Decreases the reference count of node. It is primarily used in recursive procedures to decrease the ref count of a result node before returning it. This accomplishes the goal of removing the protection applied by a previous Cudd_Ref.]
SideEffects [None]
SeeAlso [Cudd_RecursiveDeref Cudd_RecursiveDerefZdd Cudd_Ref]
Definition at line 434 of file cuddRef.c.
00436 { 00437 node = Cudd_Regular(node); 00438 cuddSatDec(node->ref); 00439 00440 } /* end of Cudd_Deref */
void Cudd_DisableGarbageCollection | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Disables garbage collection.]
Description [Disables garbage collection. Garbage collection is initially enabled. This function may be called to disable it. However, garbage collection will still occur when a new node must be created and no memory is left, or when garbage collection is required for correctness. (E.g., before reordering.)]
SideEffects [None]
SeeAlso [Cudd_EnableGarbageCollection Cudd_GarbageCollectionEnabled]
Definition at line 2559 of file cuddAPI.c.
02561 { 02562 dd->gcEnabled = 0; 02563 02564 } /* end of Cudd_DisableGarbageCollection */
int Cudd_DisableReorderingReporting | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Disables reporting of reordering stats.]
Description [Disables reporting of reordering stats. Returns 1 if successful; 0 otherwise.]
SideEffects [Removes functions from the pre-reordering and post-reordering hooks.]
SeeAlso [Cudd_EnableReorderingReporting Cudd_ReorderingReporting]
Definition at line 3561 of file cuddAPI.c.
03563 { 03564 if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { 03565 return(0); 03566 } 03567 if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { 03568 return(0); 03569 } 03570 return(1); 03571 03572 } /* end of Cudd_DisableReorderingReporting */
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 */
int Cudd_DumpBlif | ( | DdManager * | dd, | |
int | n, | |||
DdNode ** | f, | |||
char ** | inames, | |||
char ** | onames, | |||
char * | mname, | |||
FILE * | fp, | |||
int | mv | |||
) |
AutomaticEnd Function********************************************************************
Synopsis [Writes a blif file representing the argument BDDs.]
Description [Writes a blif file representing the argument BDDs as a network of multiplexers. One multiplexer is written for each BDD node. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full, or an ADD with constants different from 0 and 1). Cudd_DumpBlif does not close the file: This is the caller responsibility. Cudd_DumpBlif uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames.]
SideEffects [None]
SeeAlso [Cudd_DumpBlifBody Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm]
Definition at line 132 of file cuddExport.c.
00140 : blif, 1: blif-MV */) 00141 { 00142 DdNode *support = NULL; 00143 DdNode *scan; 00144 int *sorted = NULL; 00145 int nvars = dd->size; 00146 int retval; 00147 int i; 00148 00149 /* Build a bit array with the support of f. */ 00150 sorted = ALLOC(int,nvars); 00151 if (sorted == NULL) { 00152 dd->errorCode = CUDD_MEMORY_OUT; 00153 goto failure; 00154 } 00155 for (i = 0; i < nvars; i++) sorted[i] = 0; 00156 00157 /* Take the union of the supports of each output function. */ 00158 support = Cudd_VectorSupport(dd,f,n); 00159 if (support == NULL) goto failure; 00160 cuddRef(support); 00161 scan = support; 00162 while (!cuddIsConstant(scan)) { 00163 sorted[scan->index] = 1; 00164 scan = cuddT(scan); 00165 } 00166 Cudd_RecursiveDeref(dd,support); 00167 support = NULL; /* so that we do not try to free it in case of failure */ 00168 00169 /* Write the header (.model .inputs .outputs). */ 00170 if (mname == NULL) { 00171 retval = fprintf(fp,".model DD\n.inputs"); 00172 } else { 00173 retval = fprintf(fp,".model %s\n.inputs",mname); 00174 } 00175 if (retval == EOF) { 00176 FREE(sorted); 00177 return(0); 00178 } 00179 00180 /* Write the input list by scanning the support array. */ 00181 for (i = 0; i < nvars; i++) { 00182 if (sorted[i]) { 00183 if (inames == NULL) { 00184 retval = fprintf(fp," %d", i); 00185 } else { 00186 retval = fprintf(fp," %s", inames[i]); 00187 } 00188 if (retval == EOF) goto failure; 00189 } 00190 } 00191 FREE(sorted); 00192 sorted = NULL; 00193 00194 /* Write the .output line. */ 00195 retval = fprintf(fp,"\n.outputs"); 00196 if (retval == EOF) goto failure; 00197 for (i = 0; i < n; i++) { 00198 if (onames == NULL) { 00199 retval = fprintf(fp," f%d", i); 00200 } else { 00201 retval = fprintf(fp," %s", onames[i]); 00202 } 00203 if (retval == EOF) goto failure; 00204 } 00205 retval = fprintf(fp,"\n"); 00206 if (retval == EOF) goto failure; 00207 00208 retval = Cudd_DumpBlifBody(dd, n, f, inames, onames, fp, mv); 00209 if (retval == 0) goto failure; 00210 00211 /* Write trailer and return. */ 00212 retval = fprintf(fp,".end\n"); 00213 if (retval == EOF) goto failure; 00214 00215 return(1); 00216 00217 failure: 00218 if (sorted != NULL) FREE(sorted); 00219 if (support != NULL) Cudd_RecursiveDeref(dd,support); 00220 return(0); 00221 00222 } /* end of Cudd_DumpBlif */
int Cudd_DumpBlifBody | ( | DdManager * | dd, | |
int | n, | |||
DdNode ** | f, | |||
char ** | inames, | |||
char ** | onames, | |||
FILE * | fp, | |||
int | mv | |||
) |
Function********************************************************************
Synopsis [Writes a blif body representing the argument BDDs.]
Description [Writes a blif body representing the argument BDDs as a network of multiplexers. No header (.model, .inputs, and .outputs) and footer (.end) are produced by this function. One multiplexer is written for each BDD node. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full, or an ADD with constants different from 0 and 1). Cudd_DumpBlifBody does not close the file: This is the caller responsibility. Cudd_DumpBlifBody uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames. This function prints out only .names part.]
SideEffects [None]
SeeAlso [Cudd_DumpBlif Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm]
Definition at line 248 of file cuddExport.c.
00255 : blif, 1: blif-MV */) 00256 { 00257 st_table *visited = NULL; 00258 int retval; 00259 int i; 00260 00261 /* Initialize symbol table for visited nodes. */ 00262 visited = st_init_table(st_ptrcmp, st_ptrhash); 00263 if (visited == NULL) goto failure; 00264 00265 /* Call the function that really gets the job done. */ 00266 for (i = 0; i < n; i++) { 00267 retval = ddDoDumpBlif(dd,Cudd_Regular(f[i]),fp,visited,inames,mv); 00268 if (retval == 0) goto failure; 00269 } 00270 00271 /* To account for the possible complement on the root, 00272 ** we put either a buffer or an inverter at the output of 00273 ** the multiplexer representing the top node. 00274 */ 00275 for (i = 0; i < n; i++) { 00276 if (onames == NULL) { 00277 retval = fprintf(fp, 00278 #if SIZEOF_VOID_P == 8 00279 ".names %lx f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); 00280 #else 00281 ".names %x f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); 00282 #endif 00283 } else { 00284 retval = fprintf(fp, 00285 #if SIZEOF_VOID_P == 8 00286 ".names %lx %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]); 00287 #else 00288 ".names %x %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]); 00289 #endif 00290 } 00291 if (retval == EOF) goto failure; 00292 if (Cudd_IsComplement(f[i])) { 00293 retval = fprintf(fp,"%s0 1\n", mv ? ".def 0\n" : ""); 00294 } else { 00295 retval = fprintf(fp,"%s1 1\n", mv ? ".def 0\n" : ""); 00296 } 00297 if (retval == EOF) goto failure; 00298 } 00299 00300 st_free_table(visited); 00301 return(1); 00302 00303 failure: 00304 if (visited != NULL) st_free_table(visited); 00305 return(0); 00306 00307 } /* end of Cudd_DumpBlifBody */
int Cudd_DumpDaVinci | ( | DdManager * | dd, | |
int | n, | |||
DdNode ** | f, | |||
char ** | inames, | |||
char ** | onames, | |||
FILE * | fp | |||
) |
Function********************************************************************
Synopsis [Writes a daVinci file representing the argument BDDs.]
Description [Writes a daVinci file representing the argument BDDs. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or file system full). Cudd_DumpDaVinci does not close the file: This is the caller responsibility. Cudd_DumpDaVinci uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames.]
SideEffects [None]
SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDDcal Cudd_DumpFactoredForm]
Definition at line 626 of file cuddExport.c.
00633 { 00634 DdNode *support = NULL; 00635 DdNode *scan; 00636 st_table *visited = NULL; 00637 int retval; 00638 int i; 00639 st_generator *gen; 00640 ptruint refAddr, diff, mask; 00641 00642 /* Initialize symbol table for visited nodes. */ 00643 visited = st_init_table(st_ptrcmp, st_ptrhash); 00644 if (visited == NULL) goto failure; 00645 00646 /* Collect all the nodes of this DD in the symbol table. */ 00647 for (i = 0; i < n; i++) { 00648 retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); 00649 if (retval == 0) goto failure; 00650 } 00651 00652 /* Find how many most significant hex digits are identical 00653 ** in the addresses of all the nodes. Build a mask based 00654 ** on this knowledge, so that digits that carry no information 00655 ** will not be printed. This is done in two steps. 00656 ** 1. We scan the symbol table to find the bits that differ 00657 ** in at least 2 addresses. 00658 ** 2. We choose one of the possible masks. There are 8 possible 00659 ** masks for 32-bit integer, and 16 possible masks for 64-bit 00660 ** integers. 00661 */ 00662 00663 /* Find the bits that are different. */ 00664 refAddr = (ptruint) Cudd_Regular(f[0]); 00665 diff = 0; 00666 gen = st_init_gen(visited); 00667 while (st_gen(gen, &scan, NULL)) { 00668 diff |= refAddr ^ (ptruint) scan; 00669 } 00670 st_free_gen(gen); 00671 00672 /* Choose the mask. */ 00673 for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) { 00674 mask = (1 << i) - 1; 00675 if (diff <= mask) break; 00676 } 00677 st_free_table(visited); 00678 00679 /* Initialize symbol table for visited nodes. */ 00680 visited = st_init_table(st_ptrcmp, st_ptrhash); 00681 if (visited == NULL) goto failure; 00682 00683 retval = fprintf(fp, "["); 00684 if (retval == EOF) goto failure; 00685 /* Call the function that really gets the job done. */ 00686 for (i = 0; i < n; i++) { 00687 if (onames == NULL) { 00688 retval = fprintf(fp, 00689 "l(\"f%d\",n(\"root\",[a(\"OBJECT\",\"f%d\")],", 00690 i,i); 00691 } else { 00692 retval = fprintf(fp, 00693 "l(\"%s\",n(\"root\",[a(\"OBJECT\",\"%s\")],", 00694 onames[i], onames[i]); 00695 } 00696 if (retval == EOF) goto failure; 00697 retval = fprintf(fp, "[e(\"edge\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", 00698 Cudd_IsComplement(f[i]) ? "red" : "blue"); 00699 if (retval == EOF) goto failure; 00700 retval = ddDoDumpDaVinci(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); 00701 if (retval == 0) goto failure; 00702 retval = fprintf(fp, ")]))%s", i == n-1 ? "" : ","); 00703 if (retval == EOF) goto failure; 00704 } 00705 00706 /* Write trailer and return. */ 00707 retval = fprintf(fp, "]\n"); 00708 if (retval == EOF) goto failure; 00709 00710 st_free_table(visited); 00711 return(1); 00712 00713 failure: 00714 if (support != NULL) Cudd_RecursiveDeref(dd,support); 00715 if (visited != NULL) st_free_table(visited); 00716 return(0); 00717 00718 } /* end of Cudd_DumpDaVinci */
int Cudd_DumpDDcal | ( | DdManager * | dd, | |
int | n, | |||
DdNode ** | f, | |||
char ** | inames, | |||
char ** | onames, | |||
FILE * | fp | |||
) |
Function********************************************************************
Synopsis [Writes a DDcal file representing the argument BDDs.]
Description [Writes a DDcal file representing the argument BDDs. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or file system full). Cudd_DumpDDcal does not close the file: This is the caller responsibility. Cudd_DumpDDcal uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames.]
SideEffects [None]
SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci Cudd_DumpFactoredForm]
Definition at line 740 of file cuddExport.c.
00747 { 00748 DdNode *support = NULL; 00749 DdNode *scan; 00750 int *sorted = NULL; 00751 int nvars = dd->size; 00752 st_table *visited = NULL; 00753 int retval; 00754 int i; 00755 st_generator *gen; 00756 ptruint refAddr, diff, mask; 00757 00758 /* Initialize symbol table for visited nodes. */ 00759 visited = st_init_table(st_ptrcmp, st_ptrhash); 00760 if (visited == NULL) goto failure; 00761 00762 /* Collect all the nodes of this DD in the symbol table. */ 00763 for (i = 0; i < n; i++) { 00764 retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); 00765 if (retval == 0) goto failure; 00766 } 00767 00768 /* Find how many most significant hex digits are identical 00769 ** in the addresses of all the nodes. Build a mask based 00770 ** on this knowledge, so that digits that carry no information 00771 ** will not be printed. This is done in two steps. 00772 ** 1. We scan the symbol table to find the bits that differ 00773 ** in at least 2 addresses. 00774 ** 2. We choose one of the possible masks. There are 8 possible 00775 ** masks for 32-bit integer, and 16 possible masks for 64-bit 00776 ** integers. 00777 */ 00778 00779 /* Find the bits that are different. */ 00780 refAddr = (ptruint) Cudd_Regular(f[0]); 00781 diff = 0; 00782 gen = st_init_gen(visited); 00783 while (st_gen(gen, &scan, NULL)) { 00784 diff |= refAddr ^ (ptruint) scan; 00785 } 00786 st_free_gen(gen); 00787 00788 /* Choose the mask. */ 00789 for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) { 00790 mask = (1 << i) - 1; 00791 if (diff <= mask) break; 00792 } 00793 st_free_table(visited); 00794 00795 /* Build a bit array with the support of f. */ 00796 sorted = ALLOC(int,nvars); 00797 if (sorted == NULL) { 00798 dd->errorCode = CUDD_MEMORY_OUT; 00799 goto failure; 00800 } 00801 for (i = 0; i < nvars; i++) sorted[i] = 0; 00802 00803 /* Take the union of the supports of each output function. */ 00804 support = Cudd_VectorSupport(dd,f,n); 00805 if (support == NULL) goto failure; 00806 cuddRef(support); 00807 scan = support; 00808 while (!cuddIsConstant(scan)) { 00809 sorted[scan->index] = 1; 00810 scan = cuddT(scan); 00811 } 00812 Cudd_RecursiveDeref(dd,support); 00813 support = NULL; /* so that we do not try to free it in case of failure */ 00814 for (i = 0; i < nvars; i++) { 00815 if (sorted[dd->invperm[i]]) { 00816 if (inames == NULL || inames[dd->invperm[i]] == NULL) { 00817 retval = fprintf(fp,"v%d", dd->invperm[i]); 00818 } else { 00819 retval = fprintf(fp,"%s", inames[dd->invperm[i]]); 00820 } 00821 if (retval == EOF) goto failure; 00822 } 00823 retval = fprintf(fp,"%s", i == nvars - 1 ? "\n" : " * "); 00824 if (retval == EOF) goto failure; 00825 } 00826 FREE(sorted); 00827 sorted = NULL; 00828 00829 /* Initialize symbol table for visited nodes. */ 00830 visited = st_init_table(st_ptrcmp, st_ptrhash); 00831 if (visited == NULL) goto failure; 00832 00833 /* Call the function that really gets the job done. */ 00834 for (i = 0; i < n; i++) { 00835 retval = ddDoDumpDDcal(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); 00836 if (retval == 0) goto failure; 00837 if (onames == NULL) { 00838 retval = fprintf(fp, "f%d = ", i); 00839 } else { 00840 retval = fprintf(fp, "%s = ", onames[i]); 00841 } 00842 if (retval == EOF) goto failure; 00843 retval = fprintf(fp, "n%p%s\n", 00844 (void *) (((ptruint) f[i] & mask) / 00845 (ptruint) sizeof(DdNode)), 00846 Cudd_IsComplement(f[i]) ? "'" : ""); 00847 if (retval == EOF) goto failure; 00848 } 00849 00850 /* Write trailer and return. */ 00851 retval = fprintf(fp, "["); 00852 if (retval == EOF) goto failure; 00853 for (i = 0; i < n; i++) { 00854 if (onames == NULL) { 00855 retval = fprintf(fp, "f%d", i); 00856 } else { 00857 retval = fprintf(fp, "%s", onames[i]); 00858 } 00859 retval = fprintf(fp, "%s", i == n-1 ? "" : " "); 00860 if (retval == EOF) goto failure; 00861 } 00862 retval = fprintf(fp, "]\n"); 00863 if (retval == EOF) goto failure; 00864 00865 st_free_table(visited); 00866 return(1); 00867 00868 failure: 00869 if (sorted != NULL) FREE(sorted); 00870 if (support != NULL) Cudd_RecursiveDeref(dd,support); 00871 if (visited != NULL) st_free_table(visited); 00872 return(0); 00873 00874 } /* end of Cudd_DumpDDcal */
Function********************************************************************
Synopsis [Writes a dot file representing the argument DDs.]
Description [Writes a file representing the argument DDs in a format suitable for the graph drawing program dot. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full). Cudd_DumpDot does not close the file: This is the caller responsibility. Cudd_DumpDot uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames. Cudd_DumpDot uses the following convention to draw arcs:
The dot options are chosen so that the drawing fits on a letter-size sheet. ]
SideEffects [None]
SeeAlso [Cudd_DumpBlif Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm]
Definition at line 340 of file cuddExport.c.
00347 { 00348 DdNode *support = NULL; 00349 DdNode *scan; 00350 int *sorted = NULL; 00351 int nvars = dd->size; 00352 st_table *visited = NULL; 00353 st_generator *gen = NULL; 00354 int retval; 00355 int i, j; 00356 int slots; 00357 DdNodePtr *nodelist; 00358 long refAddr, diff, mask; 00359 00360 /* Build a bit array with the support of f. */ 00361 sorted = ALLOC(int,nvars); 00362 if (sorted == NULL) { 00363 dd->errorCode = CUDD_MEMORY_OUT; 00364 goto failure; 00365 } 00366 for (i = 0; i < nvars; i++) sorted[i] = 0; 00367 00368 /* Take the union of the supports of each output function. */ 00369 support = Cudd_VectorSupport(dd,f,n); 00370 if (support == NULL) goto failure; 00371 cuddRef(support); 00372 scan = support; 00373 while (!cuddIsConstant(scan)) { 00374 sorted[scan->index] = 1; 00375 scan = cuddT(scan); 00376 } 00377 Cudd_RecursiveDeref(dd,support); 00378 support = NULL; /* so that we do not try to free it in case of failure */ 00379 00380 /* Initialize symbol table for visited nodes. */ 00381 visited = st_init_table(st_ptrcmp, st_ptrhash); 00382 if (visited == NULL) goto failure; 00383 00384 /* Collect all the nodes of this DD in the symbol table. */ 00385 for (i = 0; i < n; i++) { 00386 retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); 00387 if (retval == 0) goto failure; 00388 } 00389 00390 /* Find how many most significant hex digits are identical 00391 ** in the addresses of all the nodes. Build a mask based 00392 ** on this knowledge, so that digits that carry no information 00393 ** will not be printed. This is done in two steps. 00394 ** 1. We scan the symbol table to find the bits that differ 00395 ** in at least 2 addresses. 00396 ** 2. We choose one of the possible masks. There are 8 possible 00397 ** masks for 32-bit integer, and 16 possible masks for 64-bit 00398 ** integers. 00399 */ 00400 00401 /* Find the bits that are different. */ 00402 refAddr = (long) Cudd_Regular(f[0]); 00403 diff = 0; 00404 gen = st_init_gen(visited); 00405 if (gen == NULL) goto failure; 00406 while (st_gen(gen, &scan, NULL)) { 00407 diff |= refAddr ^ (long) scan; 00408 } 00409 st_free_gen(gen); gen = NULL; 00410 00411 /* Choose the mask. */ 00412 for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { 00413 mask = (1 << i) - 1; 00414 if (diff <= mask) break; 00415 } 00416 00417 /* Write the header and the global attributes. */ 00418 retval = fprintf(fp,"digraph \"DD\" {\n"); 00419 if (retval == EOF) return(0); 00420 retval = fprintf(fp, 00421 "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); 00422 if (retval == EOF) return(0); 00423 00424 /* Write the input name subgraph by scanning the support array. */ 00425 retval = fprintf(fp,"{ node [shape = plaintext];\n"); 00426 if (retval == EOF) goto failure; 00427 retval = fprintf(fp," edge [style = invis];\n"); 00428 if (retval == EOF) goto failure; 00429 /* We use a name ("CONST NODES") with an embedded blank, because 00430 ** it is unlikely to appear as an input name. 00431 */ 00432 retval = fprintf(fp," \"CONST NODES\" [style = invis];\n"); 00433 if (retval == EOF) goto failure; 00434 for (i = 0; i < nvars; i++) { 00435 if (sorted[dd->invperm[i]]) { 00436 if (inames == NULL || inames[dd->invperm[i]] == NULL) { 00437 retval = fprintf(fp,"\" %d \" -> ", dd->invperm[i]); 00438 } else { 00439 retval = fprintf(fp,"\" %s \" -> ", inames[dd->invperm[i]]); 00440 } 00441 if (retval == EOF) goto failure; 00442 } 00443 } 00444 retval = fprintf(fp,"\"CONST NODES\"; \n}\n"); 00445 if (retval == EOF) goto failure; 00446 00447 /* Write the output node subgraph. */ 00448 retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); 00449 if (retval == EOF) goto failure; 00450 for (i = 0; i < n; i++) { 00451 if (onames == NULL) { 00452 retval = fprintf(fp,"\"F%d\"", i); 00453 } else { 00454 retval = fprintf(fp,"\" %s \"", onames[i]); 00455 } 00456 if (retval == EOF) goto failure; 00457 if (i == n - 1) { 00458 retval = fprintf(fp,"; }\n"); 00459 } else { 00460 retval = fprintf(fp," -> "); 00461 } 00462 if (retval == EOF) goto failure; 00463 } 00464 00465 /* Write rank info: All nodes with the same index have the same rank. */ 00466 for (i = 0; i < nvars; i++) { 00467 if (sorted[dd->invperm[i]]) { 00468 retval = fprintf(fp,"{ rank = same; "); 00469 if (retval == EOF) goto failure; 00470 if (inames == NULL || inames[dd->invperm[i]] == NULL) { 00471 retval = fprintf(fp,"\" %d \";\n", dd->invperm[i]); 00472 } else { 00473 retval = fprintf(fp,"\" %s \";\n", inames[dd->invperm[i]]); 00474 } 00475 if (retval == EOF) goto failure; 00476 nodelist = dd->subtables[i].nodelist; 00477 slots = dd->subtables[i].slots; 00478 for (j = 0; j < slots; j++) { 00479 scan = nodelist[j]; 00480 while (scan != NULL) { 00481 if (st_is_member(visited,(char *) scan)) { 00482 retval = fprintf(fp,"\"%p\";\n", 00483 (void *) ((mask & (ptrint) scan) / 00484 sizeof(DdNode))); 00485 if (retval == EOF) goto failure; 00486 } 00487 scan = scan->next; 00488 } 00489 } 00490 retval = fprintf(fp,"}\n"); 00491 if (retval == EOF) goto failure; 00492 } 00493 } 00494 00495 /* All constants have the same rank. */ 00496 retval = fprintf(fp, 00497 "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); 00498 if (retval == EOF) goto failure; 00499 nodelist = dd->constants.nodelist; 00500 slots = dd->constants.slots; 00501 for (j = 0; j < slots; j++) { 00502 scan = nodelist[j]; 00503 while (scan != NULL) { 00504 if (st_is_member(visited,(char *) scan)) { 00505 retval = fprintf(fp,"\"%p\";\n", 00506 (void *) ((mask & (ptrint) scan) / sizeof(DdNode))); 00507 if (retval == EOF) goto failure; 00508 } 00509 scan = scan->next; 00510 } 00511 } 00512 retval = fprintf(fp,"}\n}\n"); 00513 if (retval == EOF) goto failure; 00514 00515 /* Write edge info. */ 00516 /* Edges from the output nodes. */ 00517 for (i = 0; i < n; i++) { 00518 if (onames == NULL) { 00519 retval = fprintf(fp,"\"F%d\"", i); 00520 } else { 00521 retval = fprintf(fp,"\" %s \"", onames[i]); 00522 } 00523 if (retval == EOF) goto failure; 00524 /* Account for the possible complement on the root. */ 00525 if (Cudd_IsComplement(f[i])) { 00526 retval = fprintf(fp," -> \"%p\" [style = dotted];\n", 00527 (void *) ((mask & (ptrint) f[i]) / sizeof(DdNode))); 00528 } else { 00529 retval = fprintf(fp," -> \"%p\" [style = solid];\n", 00530 (void *) ((mask & (ptrint) f[i]) / sizeof(DdNode))); 00531 } 00532 if (retval == EOF) goto failure; 00533 } 00534 00535 /* Edges from internal nodes. */ 00536 for (i = 0; i < nvars; i++) { 00537 if (sorted[dd->invperm[i]]) { 00538 nodelist = dd->subtables[i].nodelist; 00539 slots = dd->subtables[i].slots; 00540 for (j = 0; j < slots; j++) { 00541 scan = nodelist[j]; 00542 while (scan != NULL) { 00543 if (st_is_member(visited,(char *) scan)) { 00544 retval = fprintf(fp, 00545 "\"%p\" -> \"%p\";\n", 00546 (void *) ((mask & (ptrint) scan) / 00547 sizeof(DdNode)), 00548 (void *) ((mask & (ptrint) cuddT(scan)) / 00549 sizeof(DdNode))); 00550 if (retval == EOF) goto failure; 00551 if (Cudd_IsComplement(cuddE(scan))) { 00552 retval = fprintf(fp, 00553 "\"%p\" -> \"%p\" [style = dotted];\n", 00554 (void *) ((mask & (ptrint) scan) / 00555 sizeof(DdNode)), 00556 (void *) ((mask & (ptrint) cuddE(scan)) / 00557 sizeof(DdNode))); 00558 } else { 00559 retval = fprintf(fp, 00560 "\"%p\" -> \"%p\" [style = dashed];\n", 00561 (void *) ((mask & (ptrint) scan) / 00562 sizeof(DdNode)), 00563 (void *) ((mask & (ptrint) cuddE(scan)) / 00564 sizeof(DdNode))); 00565 } 00566 if (retval == EOF) goto failure; 00567 } 00568 scan = scan->next; 00569 } 00570 } 00571 } 00572 } 00573 00574 /* Write constant labels. */ 00575 nodelist = dd->constants.nodelist; 00576 slots = dd->constants.slots; 00577 for (j = 0; j < slots; j++) { 00578 scan = nodelist[j]; 00579 while (scan != NULL) { 00580 if (st_is_member(visited,(char *) scan)) { 00581 retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n", 00582 (void *) ((mask & (ptrint) scan) / sizeof(DdNode)), 00583 cuddV(scan)); 00584 if (retval == EOF) goto failure; 00585 } 00586 scan = scan->next; 00587 } 00588 } 00589 00590 /* Write trailer and return. */ 00591 retval = fprintf(fp,"}\n"); 00592 if (retval == EOF) goto failure; 00593 00594 st_free_table(visited); 00595 FREE(sorted); 00596 return(1); 00597 00598 failure: 00599 if (sorted != NULL) FREE(sorted); 00600 if (support != NULL) Cudd_RecursiveDeref(dd,support); 00601 if (visited != NULL) st_free_table(visited); 00602 return(0); 00603 00604 } /* end of Cudd_DumpDot */
int Cudd_DumpFactoredForm | ( | DdManager * | dd, | |
int | n, | |||
DdNode ** | f, | |||
char ** | inames, | |||
char ** | onames, | |||
FILE * | fp | |||
) |
Function********************************************************************
Synopsis [Writes factored forms representing the argument BDDs.]
Description [Writes factored forms representing the argument BDDs. The format of the factored form is the one used in the genlib files for technology mapping in sis. It returns 1 in case of success; 0 otherwise (e.g., file system full). Cudd_DumpFactoredForm does not close the file: This is the caller responsibility. Caution must be exercised because a factored form may be exponentially larger than the argument BDD. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames.]
SideEffects [None]
SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci Cudd_DumpDDcal]
Definition at line 898 of file cuddExport.c.
00905 { 00906 int retval; 00907 int i; 00908 00909 /* Call the function that really gets the job done. */ 00910 for (i = 0; i < n; i++) { 00911 if (onames == NULL) { 00912 retval = fprintf(fp, "f%d = ", i); 00913 } else { 00914 retval = fprintf(fp, "%s = ", onames[i]); 00915 } 00916 if (retval == EOF) return(0); 00917 if (f[i] == DD_ONE(dd)) { 00918 retval = fprintf(fp, "CONST1"); 00919 if (retval == EOF) return(0); 00920 } else if (f[i] == Cudd_Not(DD_ONE(dd)) || f[i] == DD_ZERO(dd)) { 00921 retval = fprintf(fp, "CONST0"); 00922 if (retval == EOF) return(0); 00923 } else { 00924 retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? "!(" : ""); 00925 if (retval == EOF) return(0); 00926 retval = ddDoDumpFactoredForm(dd,Cudd_Regular(f[i]),fp,inames); 00927 if (retval == 0) return(0); 00928 retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? ")" : ""); 00929 if (retval == EOF) return(0); 00930 } 00931 retval = fprintf(fp, "%s", i == n-1 ? "" : "\n"); 00932 if (retval == EOF) return(0); 00933 } 00934 00935 return(1); 00936 00937 } /* end of Cudd_DumpFactoredForm */
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 */
void Cudd_EnableGarbageCollection | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Enables garbage collection.]
Description [Enables garbage collection. Garbage collection is initially enabled. Therefore it is necessary to call this function only if garbage collection has been explicitly disabled.]
SideEffects [None]
SeeAlso [Cudd_DisableGarbageCollection Cudd_GarbageCollectionEnabled]
Definition at line 2535 of file cuddAPI.c.
02537 { 02538 dd->gcEnabled = 1; 02539 02540 } /* end of Cudd_EnableGarbageCollection */
int Cudd_EnableReorderingReporting | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Enables reporting of reordering stats.]
Description [Enables reporting of reordering stats. Returns 1 if successful; 0 otherwise.]
SideEffects [Installs functions in the pre-reordering and post-reordering hooks.]
SeeAlso [Cudd_DisableReorderingReporting Cudd_ReorderingReporting]
Definition at line 3533 of file cuddAPI.c.
03535 { 03536 if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { 03537 return(0); 03538 } 03539 if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { 03540 return(0); 03541 } 03542 return(1); 03543 03544 } /* end of Cudd_EnableReorderingReporting */
Function********************************************************************
Synopsis [Counts the number of minterms of a DD with extended precision.]
Description [Counts the number of minterms of a DD with extended precision. The function is assumed to depend on nvars variables. The minterm count is represented as an EpDouble, to allow any number of variables. Returns 0 if successful; CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_PrintDebug Cudd_CountPath]
Definition at line 653 of file cuddUtil.c.
00658 { 00659 EpDouble max, tmp; 00660 st_table *table; 00661 int status; 00662 00663 background = manager->background; 00664 zero = Cudd_Not(manager->one); 00665 00666 EpdPow2(nvars, &max); 00667 table = st_init_table(EpdCmp, st_ptrhash); 00668 if (table == NULL) { 00669 EpdMakeZero(epd, 0); 00670 return(CUDD_OUT_OF_MEM); 00671 } 00672 status = ddEpdCountMintermAux(Cudd_Regular(node),&max,epd,table); 00673 st_foreach(table, ddEpdFree, NULL); 00674 st_free_table(table); 00675 if (status == CUDD_OUT_OF_MEM) { 00676 EpdMakeZero(epd, 0); 00677 return(CUDD_OUT_OF_MEM); 00678 } 00679 if (Cudd_IsComplement(node)) { 00680 EpdSubtract3(&max, epd, &tmp); 00681 EpdCopy(&tmp, epd); 00682 } 00683 return(0); 00684 00685 } /* end of Cudd_EpdCountMinterm */
Function********************************************************************
Synopsis [Compares two ADDs for equality within tolerance.]
Description [Compares two ADDs for equality within tolerance. Two ADDs are reported to be equal if the maximum difference between them (the sup norm of their difference) is less than or equal to the tolerance parameter. Returns 1 if the two ADDs are equal (within tolerance); 0 otherwise. If parameter pr
is positive the first failure is reported to the standard output.]
SideEffects [None]
SeeAlso []
Definition at line 792 of file cuddSat.c.
00798 { 00799 DdNode *fv, *fvn, *gv, *gvn, *r; 00800 unsigned int topf, topg; 00801 00802 statLine(dd); 00803 /* Check terminal cases. */ 00804 if (f == g) return(1); 00805 if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) { 00806 if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) { 00807 return(1); 00808 } else { 00809 if (pr>0) { 00810 (void) fprintf(dd->out,"Offending nodes:\n"); 00811 (void) fprintf(dd->out, 00812 "f: address = %p\t value = %40.30f\n", 00813 (void *) f, cuddV(f)); 00814 (void) fprintf(dd->out, 00815 "g: address = %p\t value = %40.30f\n", 00816 (void *) g, cuddV(g)); 00817 } 00818 return(0); 00819 } 00820 } 00821 00822 /* We only insert the result in the cache if the comparison is 00823 ** successful. Therefore, if we hit we return 1. */ 00824 r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g); 00825 if (r != NULL) { 00826 return(1); 00827 } 00828 00829 /* Compute the cofactors and solve the recursive subproblems. */ 00830 topf = cuddI(dd,f->index); 00831 topg = cuddI(dd,g->index); 00832 00833 if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;} 00834 if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;} 00835 00836 if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0); 00837 if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0); 00838 00839 cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g,DD_ONE(dd)); 00840 00841 return(1); 00842 00843 } /* end of Cudd_EqualSupNorm */
Function********************************************************************
Synopsis [Tells whether F and G are identical wherever D is 0.]
Description [Tells whether F and G are identical wherever D is 0. F and G are either two ADDs or two BDDs. D is either a 0-1 ADD or a BDD. The function returns 1 if F and G are equivalent, and 0 otherwise. No new nodes are created.]
SideEffects [None]
SeeAlso [Cudd_bddLeqUnless]
Definition at line 518 of file cuddSat.c.
00523 { 00524 DdNode *tmp, *One, *Gr, *Dr; 00525 DdNode *Fv, *Fvn, *Gv, *Gvn, *Dv, *Dvn; 00526 int res; 00527 unsigned int flevel, glevel, dlevel, top; 00528 00529 One = DD_ONE(dd); 00530 00531 statLine(dd); 00532 /* Check terminal cases. */ 00533 if (D == One || F == G) return(1); 00534 if (D == Cudd_Not(One) || D == DD_ZERO(dd) || F == Cudd_Not(G)) return(0); 00535 00536 /* From now on, D is non-constant. */ 00537 00538 /* Normalize call to increase cache efficiency. */ 00539 if (F > G) { 00540 tmp = F; 00541 F = G; 00542 G = tmp; 00543 } 00544 if (Cudd_IsComplement(F)) { 00545 F = Cudd_Not(F); 00546 G = Cudd_Not(G); 00547 } 00548 00549 /* From now on, F is regular. */ 00550 00551 /* Check cache. */ 00552 tmp = cuddCacheLookup(dd,DD_EQUIV_DC_TAG,F,G,D); 00553 if (tmp != NULL) return(tmp == One); 00554 00555 /* Find splitting variable. */ 00556 flevel = cuddI(dd,F->index); 00557 Gr = Cudd_Regular(G); 00558 glevel = cuddI(dd,Gr->index); 00559 top = ddMin(flevel,glevel); 00560 Dr = Cudd_Regular(D); 00561 dlevel = dd->perm[Dr->index]; 00562 top = ddMin(top,dlevel); 00563 00564 /* Compute cofactors. */ 00565 if (top == flevel) { 00566 Fv = cuddT(F); 00567 Fvn = cuddE(F); 00568 } else { 00569 Fv = Fvn = F; 00570 } 00571 if (top == glevel) { 00572 Gv = cuddT(Gr); 00573 Gvn = cuddE(Gr); 00574 if (G != Gr) { 00575 Gv = Cudd_Not(Gv); 00576 Gvn = Cudd_Not(Gvn); 00577 } 00578 } else { 00579 Gv = Gvn = G; 00580 } 00581 if (top == dlevel) { 00582 Dv = cuddT(Dr); 00583 Dvn = cuddE(Dr); 00584 if (D != Dr) { 00585 Dv = Cudd_Not(Dv); 00586 Dvn = Cudd_Not(Dvn); 00587 } 00588 } else { 00589 Dv = Dvn = D; 00590 } 00591 00592 /* Solve recursively. */ 00593 res = Cudd_EquivDC(dd,Fv,Gv,Dv); 00594 if (res != 0) { 00595 res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn); 00596 } 00597 cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One)); 00598 00599 return(res); 00600 00601 } /* end of Cudd_EquivDC */
Function********************************************************************
Synopsis [Estimates the number of nodes in a cofactor of a DD.]
Description [Estimates the number of nodes in a cofactor of a DD. Returns an estimate of the number of nodes in a cofactor of the graph rooted at node with respect to the variable whose index is i. In case of failure, returns CUDD_OUT_OF_MEM. This function uses a refinement of the algorithm of Cabodi et al. (ICCAD96). The refinement allows the procedure to account for part of the recombination that may occur in the part of the cofactor above the cofactoring variable. This procedure does no create any new node. It does keep a small table of results; therefore it may run out of memory. If this is a concern, one should use Cudd_EstimateCofactorSimple, which is faster, does not allocate any memory, but is less accurate.]
SideEffects [None]
SeeAlso [Cudd_DagSize Cudd_EstimateCofactorSimple]
Definition at line 473 of file cuddUtil.c.
00477 : positive; 0: negative */ 00478 ) 00479 { 00480 int val; 00481 DdNode *ptr; 00482 st_table *table; 00483 00484 table = st_init_table(st_ptrcmp,st_ptrhash); 00485 if (table == NULL) return(CUDD_OUT_OF_MEM); 00486 val = cuddEstimateCofactor(dd,table,Cudd_Regular(f),i,phase,&ptr); 00487 ddClearFlag(Cudd_Regular(f)); 00488 st_free_table(table); 00489 00490 return(val); 00491 00492 } /* end of Cudd_EstimateCofactor */
int Cudd_EstimateCofactorSimple | ( | DdNode * | node, | |
int | i | |||
) |
Function********************************************************************
Synopsis [Estimates the number of nodes in a cofactor of a DD.]
Description [Estimates the number of nodes in a cofactor of a DD. Returns an estimate of the number of nodes in the positive cofactor of the graph rooted at node with respect to the variable whose index is i. This procedure implements with minor changes the algorithm of Cabodi et al. (ICCAD96). It does not allocate any memory, it does not change the state of the manager, and it is fast. However, it has been observed to overestimate the size of the cofactor by as much as a factor of 2.]
SideEffects [None]
SeeAlso [Cudd_DagSize]
Definition at line 513 of file cuddUtil.c.
00516 { 00517 int val; 00518 00519 val = cuddEstimateCofactorSimple(Cudd_Regular(node),i); 00520 ddClearFlag(Cudd_Regular(node)); 00521 00522 return(val); 00523 00524 } /* end of Cudd_EstimateCofactorSimple */
AutomaticEnd Function********************************************************************
Synopsis [Returns the value of a DD for a given variable assignment.]
Description [Finds the value of a DD for a given variable assignment. The variable assignment is passed in an array of int's, that should specify a zero or a one for each variable in the support of the function. Returns a pointer to a constant node. No new nodes are produced.]
SideEffects [None]
SeeAlso [Cudd_bddLeq Cudd_addEvalConst]
Definition at line 153 of file cuddSat.c.
00157 { 00158 int comple; 00159 DdNode *ptr; 00160 00161 comple = Cudd_IsComplement(f); 00162 ptr = Cudd_Regular(f); 00163 00164 while (!cuddIsConstant(ptr)) { 00165 if (inputs[ptr->index] == 1) { 00166 ptr = cuddT(ptr); 00167 } else { 00168 comple ^= Cudd_IsComplement(cuddE(ptr)); 00169 ptr = Cudd_Regular(cuddE(ptr)); 00170 } 00171 } 00172 return(Cudd_NotCond(ptr,comple)); 00173 00174 } /* end of Cudd_Eval */
double Cudd_ExpectedUsedSlots | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Computes the expected fraction of used slots in the unique table.]
Description [Computes the fraction of slots in the unique table that should be in use. This expected value is based on the assumption that the hash function distributes the keys randomly; it can be compared with the result of Cudd_ReadUsedSlots to monitor the performance of the unique table hash function.]
SideEffects [None]
SeeAlso [Cudd_ReadSlots Cudd_ReadUsedSlots]
Definition at line 1568 of file cuddAPI.c.
01570 { 01571 int i; 01572 int size = dd->size; 01573 DdSubtable *subtable; 01574 double empty = 0.0; 01575 01576 /* To each subtable we apply the corollary to Theorem 8.5 (occupancy 01577 ** distribution) from Sedgewick and Flajolet's Analysis of Algorithms. 01578 ** The corollary says that for a table with M buckets and a load ratio 01579 ** of r, the expected number of empty buckets is asymptotically given 01580 ** by M * exp(-r). 01581 */ 01582 01583 /* Scan each BDD/ADD subtable. */ 01584 for (i = 0; i < size; i++) { 01585 subtable = &(dd->subtables[i]); 01586 empty += (double) subtable->slots * 01587 exp(-(double) subtable->keys / (double) subtable->slots); 01588 } 01589 01590 /* Scan the ZDD subtables. */ 01591 size = dd->sizeZ; 01592 01593 for (i = 0; i < size; i++) { 01594 subtable = &(dd->subtableZ[i]); 01595 empty += (double) subtable->slots * 01596 exp(-(double) subtable->keys / (double) subtable->slots); 01597 } 01598 01599 /* Constant table. */ 01600 subtable = &(dd->constants); 01601 empty += (double) subtable->slots * 01602 exp(-(double) subtable->keys / (double) subtable->slots); 01603 01604 return(1.0 - empty / (double) dd->slots); 01605 01606 } /* end of Cudd_ExpectedUsedSlots */
AutomaticEnd Function********************************************************************
Synopsis [Finds the essential variables of a DD.]
Description [Returns the cube of the essential variables. A positive literal means that the variable must be set to 1 for the function to be 1. A negative literal means that the variable must be set to 0 for the function to be 1. Returns a pointer to the cube BDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddIsVarEssential]
Definition at line 205 of file cuddEssent.c.
00208 { 00209 DdNode *res; 00210 00211 do { 00212 dd->reordered = 0; 00213 res = ddFindEssentialRecur(dd,f); 00214 } while (dd->reordered == 1); 00215 return(res); 00216 00217 } /* end of Cudd_FindEssential */
Function********************************************************************
Synopsis [Finds the two literal clauses of a DD.]
Description [Returns the one- and two-literal clauses of a DD. Returns a pointer to the structure holding the clauses if successful; NULL otherwise. For a constant DD, the empty set of clauses is returned. This is obviously correct for a non-zero constant. For the constant zero, it is based on the assumption that only those clauses containing variables in the support of the function are considered. Since the support of a constant function is empty, no clauses are returned.]
SideEffects [None]
SeeAlso [Cudd_FindEssential]
Definition at line 273 of file cuddEssent.c.
00276 { 00277 DdTlcInfo *res; 00278 st_table *table; 00279 st_generator *gen; 00280 DdTlcInfo *tlc; 00281 DdNode *node; 00282 int size = dd->size; 00283 00284 if (Cudd_IsConstant(f)) { 00285 res = emptyClauseSet(); 00286 return(res); 00287 } 00288 table = st_init_table(st_ptrcmp,st_ptrhash); 00289 if (table == NULL) return(NULL); 00290 Tolv = bitVectorAlloc(size); 00291 if (Tolv == NULL) { 00292 st_free_table(table); 00293 return(NULL); 00294 } 00295 Tolp = bitVectorAlloc(size); 00296 if (Tolp == NULL) { 00297 st_free_table(table); 00298 bitVectorFree(Tolv); 00299 return(NULL); 00300 } 00301 Eolv = bitVectorAlloc(size); 00302 if (Eolv == NULL) { 00303 st_free_table(table); 00304 bitVectorFree(Tolv); 00305 bitVectorFree(Tolp); 00306 return(NULL); 00307 } 00308 Eolp = bitVectorAlloc(size); 00309 if (Eolp == NULL) { 00310 st_free_table(table); 00311 bitVectorFree(Tolv); 00312 bitVectorFree(Tolp); 00313 bitVectorFree(Eolv); 00314 return(NULL); 00315 } 00316 00317 res = ddFindTwoLiteralClausesRecur(dd,f,table); 00318 /* Dispose of table contents and free table. */ 00319 st_foreach_item(table, gen, &node, &tlc) { 00320 if (node != f) { 00321 Cudd_tlcInfoFree(tlc); 00322 } 00323 } 00324 st_free_table(table); 00325 bitVectorFree(Tolv); 00326 bitVectorFree(Tolp); 00327 bitVectorFree(Eolv); 00328 bitVectorFree(Eolp); 00329 00330 if (res != NULL) { 00331 int i; 00332 for (i = 0; !sentinelp(res->vars[i], res->vars[i+1]); i += 2); 00333 res->cnt = i >> 1; 00334 } 00335 00336 return(res); 00337 00338 } /* end of Cudd_FindTwoLiteralClauses */
Function********************************************************************
Synopsis [Finds the first cube of a decision diagram.]
Description [Defines an iterator on the onset of a decision diagram and finds its first cube. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise.
A cube is represented as an array of literals, which are integers in {0, 1, 2}; 0 represents a complemented literal, 1 represents an uncomplemented literal, and 2 stands for don't care. The enumeration produces a disjoint cover of the function associated with the diagram. The size of the array equals the number of variables in the manager at the time Cudd_FirstCube is called.
For each cube, a value is also returned. This value is always 1 for a BDD, while it may be different from 1 for an ADD. For BDDs, the offset is the set of cubes whose value is the logical zero. For ADDs, the offset is the set of cubes whose value is the background value. The cubes of the offset are not enumerated.]
SideEffects [The first cube and its value are returned as side effects.]
SeeAlso [Cudd_ForeachCube Cudd_NextCube Cudd_GenFree Cudd_IsGenEmpty Cudd_FirstNode]
Definition at line 1794 of file cuddUtil.c.
01799 { 01800 DdGen *gen; 01801 DdNode *top, *treg, *next, *nreg, *prev, *preg; 01802 int i; 01803 int nvars; 01804 01805 /* Sanity Check. */ 01806 if (dd == NULL || f == NULL) return(NULL); 01807 01808 /* Allocate generator an initialize it. */ 01809 gen = ALLOC(DdGen,1); 01810 if (gen == NULL) { 01811 dd->errorCode = CUDD_MEMORY_OUT; 01812 return(NULL); 01813 } 01814 01815 gen->manager = dd; 01816 gen->type = CUDD_GEN_CUBES; 01817 gen->status = CUDD_GEN_EMPTY; 01818 gen->gen.cubes.cube = NULL; 01819 gen->gen.cubes.value = DD_ZERO_VAL; 01820 gen->stack.sp = 0; 01821 gen->stack.stack = NULL; 01822 gen->node = NULL; 01823 01824 nvars = dd->size; 01825 gen->gen.cubes.cube = ALLOC(int,nvars); 01826 if (gen->gen.cubes.cube == NULL) { 01827 dd->errorCode = CUDD_MEMORY_OUT; 01828 FREE(gen); 01829 return(NULL); 01830 } 01831 for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; 01832 01833 /* The maximum stack depth is one plus the number of variables. 01834 ** because a path may have nodes at all levels, including the 01835 ** constant level. 01836 */ 01837 gen->stack.stack = ALLOC(DdNodePtr, nvars+1); 01838 if (gen->stack.stack == NULL) { 01839 dd->errorCode = CUDD_MEMORY_OUT; 01840 FREE(gen->gen.cubes.cube); 01841 FREE(gen); 01842 return(NULL); 01843 } 01844 for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; 01845 01846 /* Find the first cube of the onset. */ 01847 gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; 01848 01849 while (1) { 01850 top = gen->stack.stack[gen->stack.sp-1]; 01851 treg = Cudd_Regular(top); 01852 if (!cuddIsConstant(treg)) { 01853 /* Take the else branch first. */ 01854 gen->gen.cubes.cube[treg->index] = 0; 01855 next = cuddE(treg); 01856 if (top != treg) next = Cudd_Not(next); 01857 gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; 01858 } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { 01859 /* Backtrack */ 01860 while (1) { 01861 if (gen->stack.sp == 1) { 01862 /* The current node has no predecessor. */ 01863 gen->status = CUDD_GEN_EMPTY; 01864 gen->stack.sp--; 01865 goto done; 01866 } 01867 prev = gen->stack.stack[gen->stack.sp-2]; 01868 preg = Cudd_Regular(prev); 01869 nreg = cuddT(preg); 01870 if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} 01871 if (next != top) { /* follow the then branch next */ 01872 gen->gen.cubes.cube[preg->index] = 1; 01873 gen->stack.stack[gen->stack.sp-1] = next; 01874 break; 01875 } 01876 /* Pop the stack and try again. */ 01877 gen->gen.cubes.cube[preg->index] = 2; 01878 gen->stack.sp--; 01879 top = gen->stack.stack[gen->stack.sp-1]; 01880 treg = Cudd_Regular(top); 01881 } 01882 } else { 01883 gen->status = CUDD_GEN_NONEMPTY; 01884 gen->gen.cubes.value = cuddV(top); 01885 goto done; 01886 } 01887 } 01888 01889 done: 01890 *cube = gen->gen.cubes.cube; 01891 *value = gen->gen.cubes.value; 01892 return(gen); 01893 01894 } /* end of Cudd_FirstCube */
Function********************************************************************
Synopsis [Finds the first node of a decision diagram.]
Description [Defines an iterator on the nodes of a decision diagram and finds its first node. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise. The nodes are enumerated in a reverse topological order, so that a node is always preceded in the enumeration by its descendants.]
SideEffects [The first node is returned as a side effect.]
SeeAlso [Cudd_ForeachNode Cudd_NextNode Cudd_GenFree Cudd_IsGenEmpty Cudd_FirstCube]
Definition at line 2396 of file cuddUtil.c.
02400 { 02401 DdGen *gen; 02402 int size; 02403 02404 /* Sanity Check. */ 02405 if (dd == NULL || f == NULL) return(NULL); 02406 02407 /* Allocate generator an initialize it. */ 02408 gen = ALLOC(DdGen,1); 02409 if (gen == NULL) { 02410 dd->errorCode = CUDD_MEMORY_OUT; 02411 return(NULL); 02412 } 02413 02414 gen->manager = dd; 02415 gen->type = CUDD_GEN_NODES; 02416 gen->status = CUDD_GEN_EMPTY; 02417 gen->stack.sp = 0; 02418 gen->node = NULL; 02419 02420 /* Collect all the nodes on the generator stack for later perusal. */ 02421 gen->stack.stack = cuddNodeArray(Cudd_Regular(f), &size); 02422 if (gen->stack.stack == NULL) { 02423 FREE(gen); 02424 dd->errorCode = CUDD_MEMORY_OUT; 02425 return(NULL); 02426 } 02427 gen->gen.nodes.size = size; 02428 02429 /* Find the first node. */ 02430 if (gen->stack.sp < gen->gen.nodes.size) { 02431 gen->status = CUDD_GEN_NONEMPTY; 02432 gen->node = gen->stack.stack[gen->stack.sp]; 02433 *node = gen->node; 02434 } 02435 02436 return(gen); 02437 02438 } /* end of Cudd_FirstNode */
Function********************************************************************
Synopsis [Finds the first prime of a Boolean function.]
Description [Defines an iterator on a pair of BDDs describing a (possibly incompletely specified) Boolean functions and finds the first cube of a cover of the function. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise.
The two argument BDDs are the lower and upper bounds of an interval. It is a mistake to call this function with a lower bound that is not less than or equal to the upper bound.
A cube is represented as an array of literals, which are integers in {0, 1, 2}; 0 represents a complemented literal, 1 represents an uncomplemented literal, and 2 stands for don't care. The enumeration produces a prime and irredundant cover of the function associated with the two BDDs. The size of the array equals the number of variables in the manager at the time Cudd_FirstCube is called.
This iterator can only be used on BDDs.]
SideEffects [The first cube is returned as side effect.]
SeeAlso [Cudd_ForeachPrime Cudd_NextPrime Cudd_GenFree Cudd_IsGenEmpty Cudd_FirstCube Cudd_FirstNode]
Definition at line 2024 of file cuddUtil.c.
02029 { 02030 DdGen *gen; 02031 DdNode *implicant, *prime, *tmp; 02032 int length, result; 02033 02034 /* Sanity Check. */ 02035 if (dd == NULL || l == NULL || u == NULL) return(NULL); 02036 02037 /* Allocate generator an initialize it. */ 02038 gen = ALLOC(DdGen,1); 02039 if (gen == NULL) { 02040 dd->errorCode = CUDD_MEMORY_OUT; 02041 return(NULL); 02042 } 02043 02044 gen->manager = dd; 02045 gen->type = CUDD_GEN_PRIMES; 02046 gen->status = CUDD_GEN_EMPTY; 02047 gen->gen.primes.cube = NULL; 02048 gen->gen.primes.ub = u; 02049 gen->stack.sp = 0; 02050 gen->stack.stack = NULL; 02051 gen->node = l; 02052 cuddRef(l); 02053 02054 gen->gen.primes.cube = ALLOC(int,dd->size); 02055 if (gen->gen.primes.cube == NULL) { 02056 dd->errorCode = CUDD_MEMORY_OUT; 02057 FREE(gen); 02058 return(NULL); 02059 } 02060 02061 if (gen->node == Cudd_ReadLogicZero(dd)) { 02062 gen->status = CUDD_GEN_EMPTY; 02063 } else { 02064 implicant = Cudd_LargestCube(dd,gen->node,&length); 02065 if (implicant == NULL) { 02066 Cudd_RecursiveDeref(dd,gen->node); 02067 FREE(gen->gen.primes.cube); 02068 FREE(gen); 02069 return(NULL); 02070 } 02071 cuddRef(implicant); 02072 prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); 02073 if (prime == NULL) { 02074 Cudd_RecursiveDeref(dd,gen->node); 02075 Cudd_RecursiveDeref(dd,implicant); 02076 FREE(gen->gen.primes.cube); 02077 FREE(gen); 02078 return(NULL); 02079 } 02080 cuddRef(prime); 02081 Cudd_RecursiveDeref(dd,implicant); 02082 tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); 02083 if (tmp == NULL) { 02084 Cudd_RecursiveDeref(dd,gen->node); 02085 Cudd_RecursiveDeref(dd,prime); 02086 FREE(gen->gen.primes.cube); 02087 FREE(gen); 02088 return(NULL); 02089 } 02090 cuddRef(tmp); 02091 Cudd_RecursiveDeref(dd,gen->node); 02092 gen->node = tmp; 02093 result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); 02094 if (result == 0) { 02095 Cudd_RecursiveDeref(dd,gen->node); 02096 Cudd_RecursiveDeref(dd,prime); 02097 FREE(gen->gen.primes.cube); 02098 FREE(gen); 02099 return(NULL); 02100 } 02101 Cudd_RecursiveDeref(dd,prime); 02102 gen->status = CUDD_GEN_NONEMPTY; 02103 } 02104 *cube = gen->gen.primes.cube; 02105 return(gen); 02106 02107 } /* end of Cudd_FirstPrime */
void Cudd_FreeTree | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Frees the variable group tree of the manager.]
Description []
SideEffects [None]
SeeAlso [Cudd_SetTree Cudd_ReadTree Cudd_FreeZddTree]
Definition at line 2176 of file cuddAPI.c.
02178 { 02179 if (dd->tree != NULL) { 02180 Mtr_FreeTree(dd->tree); 02181 dd->tree = NULL; 02182 } 02183 return; 02184 02185 } /* end of Cudd_FreeTree */
void Cudd_FreeZddTree | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Frees the variable group tree of the manager.]
Description []
SideEffects [None]
SeeAlso [Cudd_SetZddTree Cudd_ReadZddTree Cudd_FreeTree]
Definition at line 2248 of file cuddAPI.c.
02250 { 02251 if (dd->treeZ != NULL) { 02252 Mtr_FreeTree(dd->treeZ); 02253 dd->treeZ = NULL; 02254 } 02255 return; 02256 02257 } /* end of Cudd_FreeZddTree */
int Cudd_GarbageCollectionEnabled | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Tells whether garbage collection is enabled.]
Description [Returns 1 if garbage collection is enabled; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_EnableGarbageCollection Cudd_DisableGarbageCollection]
Definition at line 2513 of file cuddAPI.c.
02515 { 02516 return(dd->gcEnabled); 02517 02518 } /* end of Cudd_GarbageCollectionEnabled */
int Cudd_GenFree | ( | DdGen * | gen | ) |
Function********************************************************************
Synopsis [Frees a CUDD generator.]
Description [Frees a CUDD generator. Always returns 0, so that it can be used in mis-like foreach constructs.]
SideEffects [None]
SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_FirstNode Cudd_NextNode Cudd_IsGenEmpty]
Definition at line 2487 of file cuddUtil.c.
02489 { 02490 if (gen == NULL) return(0); 02491 switch (gen->type) { 02492 case CUDD_GEN_CUBES: 02493 case CUDD_GEN_ZDD_PATHS: 02494 FREE(gen->gen.cubes.cube); 02495 FREE(gen->stack.stack); 02496 break; 02497 case CUDD_GEN_PRIMES: 02498 FREE(gen->gen.primes.cube); 02499 Cudd_RecursiveDeref(gen->manager,gen->node); 02500 break; 02501 case CUDD_GEN_NODES: 02502 FREE(gen->stack.stack); 02503 break; 02504 default: 02505 return(0); 02506 } 02507 FREE(gen); 02508 return(0); 02509 02510 } /* end of Cudd_GenFree */
Function********************************************************************
Synopsis [Determines whether a BDD is positive unate in a variable.]
Description [Determines whether the function represented by BDD f is positive unate (monotonic increasing) in variable i. It is based on Cudd_Decreasing and the fact that f is monotonic increasing in i if and only if its complement is monotonic decreasing in i.]
SideEffects [None]
SeeAlso [Cudd_Decreasing]
Definition at line 493 of file cuddSat.c.
00497 { 00498 return(Cudd_Decreasing(dd,Cudd_Not(f),i)); 00499 00500 } /* end of Cudd_Increasing */
Function********************************************************************
Synopsis [Builds a cube of BDD variables from an array of indices.]
Description [Builds a cube of BDD variables from an array of indices. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddComputeCube Cudd_CubeArrayToBdd]
Definition at line 2549 of file cuddUtil.c.
02553 { 02554 DdNode *cube, *tmp; 02555 int i; 02556 02557 cube = DD_ONE(dd); 02558 cuddRef(cube); 02559 for (i = n - 1; i >= 0; i--) { 02560 tmp = Cudd_bddAnd(dd,Cudd_bddIthVar(dd,array[i]),cube); 02561 if (tmp == NULL) { 02562 Cudd_RecursiveDeref(dd,cube); 02563 return(NULL); 02564 } 02565 cuddRef(tmp); 02566 Cudd_RecursiveDeref(dd,cube); 02567 cube = tmp; 02568 } 02569 02570 cuddDeref(cube); 02571 return(cube); 02572 02573 } /* end of Cudd_IndicesToCube */
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 */
DdManager* Cudd_Init | ( | unsigned int | numVars, | |
unsigned int | numVarsZ, | |||
unsigned int | numSlots, | |||
unsigned int | cacheSize, | |||
unsigned long | maxMemory | |||
) |
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Creates a new DD manager.]
Description [Creates a new DD manager, initializes the table, the basic constants and the projection functions. If maxMemory is 0, Cudd_Init decides suitable values for the maximum size of the cache and for the limit for fast unique table growth based on the available memory. Returns a pointer to the manager if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_Quit]
Definition at line 121 of file cuddInit.c.
00127 { 00128 DdManager *unique; 00129 int i,result; 00130 DdNode *one, *zero; 00131 unsigned int maxCacheSize; 00132 unsigned int looseUpTo; 00133 extern DD_OOMFP MMoutOfMemory; 00134 DD_OOMFP saveHandler; 00135 00136 if (maxMemory == 0) { 00137 maxMemory = getSoftDataLimit(); 00138 } 00139 looseUpTo = (unsigned int) ((maxMemory / sizeof(DdNode)) / 00140 DD_MAX_LOOSE_FRACTION); 00141 unique = cuddInitTable(numVars,numVarsZ,numSlots,looseUpTo); 00142 if (unique == NULL) return(NULL); 00143 unique->maxmem = (unsigned long) maxMemory / 10 * 9; 00144 maxCacheSize = (unsigned int) ((maxMemory / sizeof(DdCache)) / 00145 DD_MAX_CACHE_FRACTION); 00146 result = cuddInitCache(unique,cacheSize,maxCacheSize); 00147 if (result == 0) return(NULL); 00148 00149 saveHandler = MMoutOfMemory; 00150 MMoutOfMemory = Cudd_OutOfMem; 00151 unique->stash = ALLOC(char,(maxMemory / DD_STASH_FRACTION) + 4); 00152 MMoutOfMemory = saveHandler; 00153 if (unique->stash == NULL) { 00154 (void) fprintf(unique->err,"Unable to set aside memory\n"); 00155 } 00156 00157 /* Initialize constants. */ 00158 unique->one = cuddUniqueConst(unique,1.0); 00159 if (unique->one == NULL) return(0); 00160 cuddRef(unique->one); 00161 unique->zero = cuddUniqueConst(unique,0.0); 00162 if (unique->zero == NULL) return(0); 00163 cuddRef(unique->zero); 00164 #ifdef HAVE_IEEE_754 00165 if (DD_PLUS_INF_VAL != DD_PLUS_INF_VAL * 3 || 00166 DD_PLUS_INF_VAL != DD_PLUS_INF_VAL / 3) { 00167 (void) fprintf(unique->err,"Warning: Crippled infinite values\n"); 00168 (void) fprintf(unique->err,"Recompile without -DHAVE_IEEE_754\n"); 00169 } 00170 #endif 00171 unique->plusinfinity = cuddUniqueConst(unique,DD_PLUS_INF_VAL); 00172 if (unique->plusinfinity == NULL) return(0); 00173 cuddRef(unique->plusinfinity); 00174 unique->minusinfinity = cuddUniqueConst(unique,DD_MINUS_INF_VAL); 00175 if (unique->minusinfinity == NULL) return(0); 00176 cuddRef(unique->minusinfinity); 00177 unique->background = unique->zero; 00178 00179 /* The logical zero is different from the CUDD_VALUE_TYPE zero! */ 00180 one = unique->one; 00181 zero = Cudd_Not(one); 00182 /* Create the projection functions. */ 00183 unique->vars = ALLOC(DdNodePtr,unique->maxSize); 00184 if (unique->vars == NULL) { 00185 unique->errorCode = CUDD_MEMORY_OUT; 00186 return(NULL); 00187 } 00188 for (i = 0; i < unique->size; i++) { 00189 unique->vars[i] = cuddUniqueInter(unique,i,one,zero); 00190 if (unique->vars[i] == NULL) return(0); 00191 cuddRef(unique->vars[i]); 00192 } 00193 00194 if (unique->sizeZ) 00195 cuddZddInitUniv(unique); 00196 00197 unique->memused += sizeof(DdNode *) * unique->maxSize; 00198 00199 return(unique); 00200 00201 } /* end of Cudd_Init */
int Cudd_IsGenEmpty | ( | DdGen * | gen | ) |
Function********************************************************************
Synopsis [Queries the status of a generator.]
Description [Queries the status of a generator. Returns 1 if the generator is empty or NULL; 0 otherswise.]
SideEffects [None]
SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_FirstNode Cudd_NextNode Cudd_GenFree]
Definition at line 2527 of file cuddUtil.c.
02529 { 02530 if (gen == NULL) return(1); 02531 return(gen->status == CUDD_GEN_EMPTY); 02532 02533 } /* end of Cudd_IsGenEmpty */
int Cudd_IsInHook | ( | DdManager * | dd, | |
DD_HFP | f, | |||
Cudd_HookType | where | |||
) |
Function********************************************************************
Synopsis [Checks whether a function is in a hook.]
Description [Checks whether a function is in a hook. A hook is a list of application-provided functions called on certain occasions by the package. Returns 1 if the function is found; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_AddHook Cudd_RemoveHook]
Definition at line 3356 of file cuddAPI.c.
03360 { 03361 DdHook *hook; 03362 03363 switch (where) { 03364 case CUDD_PRE_GC_HOOK: 03365 hook = dd->preGCHook; 03366 break; 03367 case CUDD_POST_GC_HOOK: 03368 hook = dd->postGCHook; 03369 break; 03370 case CUDD_PRE_REORDERING_HOOK: 03371 hook = dd->preReorderingHook; 03372 break; 03373 case CUDD_POST_REORDERING_HOOK: 03374 hook = dd->postReorderingHook; 03375 break; 03376 default: 03377 return(0); 03378 } 03379 /* Scan the list and find whether the function is already there. */ 03380 while (hook != NULL) { 03381 if (hook->f == f) { 03382 return(1); 03383 } 03384 hook = hook->next; 03385 } 03386 return(0); 03387 03388 } /* end of Cudd_IsInHook */
int Cudd_IsNonConstant | ( | DdNode * | f | ) |
Function********************************************************************
Synopsis [Returns 1 if a DD node is not constant.]
Description [Returns 1 if a DD node is not constant. This function is useful to test the results of Cudd_bddIteConstant, Cudd_addIteConstant, Cudd_addEvalConst. These results may be a special value signifying non-constant. In the other cases the macro Cudd_IsConstant can be used.]
SideEffects [None]
SeeAlso [Cudd_IsConstant Cudd_bddIteConstant Cudd_addIteConstant Cudd_addEvalConst]
Definition at line 641 of file cuddAPI.c.
00643 { 00644 return(f == DD_NON_CONSTANT || !Cudd_IsConstant(f)); 00645 00646 } /* end of Cudd_IsNonConstant */
Function********************************************************************
Synopsis [Decreases the reference count of BDD node n.]
Description [Decreases the reference count of node n. If n dies, recursively decreases the reference counts of its children. It is used to dispose of a BDD that is no longer needed. It is more efficient than Cudd_RecursiveDeref, but it cannot be used on ADDs. The greater efficiency comes from being able to assume that no constant node will ever die as a result of a call to this procedure.]
SideEffects [None]
SeeAlso [Cudd_RecursiveDeref Cudd_DelayedDerefBdd]
Definition at line 213 of file cuddRef.c.
00216 { 00217 DdNode *N; 00218 int ord; 00219 DdNodePtr *stack = table->stack; 00220 int SP = 1; 00221 00222 unsigned int live = table->keys - table->dead; 00223 if (live > table->peakLiveNodes) { 00224 table->peakLiveNodes = live; 00225 } 00226 00227 N = Cudd_Regular(n); 00228 00229 do { 00230 #ifdef DD_DEBUG 00231 assert(N->ref != 0); 00232 #endif 00233 00234 if (N->ref == 1) { 00235 N->ref = 0; 00236 table->dead++; 00237 #ifdef DD_STATS 00238 table->nodesDropped++; 00239 #endif 00240 ord = table->perm[N->index]; 00241 stack[SP++] = Cudd_Regular(cuddE(N)); 00242 table->subtables[ord].dead++; 00243 N = cuddT(N); 00244 } else { 00245 cuddSatDec(N->ref); 00246 N = stack[--SP]; 00247 } 00248 } while (SP != 0); 00249 00250 } /* end of Cudd_IterDerefBdd */
Function********************************************************************
Synopsis [Finds a largest cube in a DD.]
Description [Finds a largest cube in a DD. f is the DD we want to get the largest cube for. The problem is translated into the one of finding a shortest path in f, when both THEN and ELSE arcs are assumed to have unit length. This yields a largest cube in the disjoint cover corresponding to the DD. Therefore, it is not necessarily the largest implicant of f. Returns the largest cube as a BDD.]
SideEffects [The number of literals of the cube is returned in length.]
SeeAlso [Cudd_ShortestPath]
Definition at line 281 of file cuddSat.c.
00285 { 00286 register DdNode *F; 00287 st_table *visited; 00288 DdNode *sol; 00289 cuddPathPair *rootPair; 00290 int complement, cost; 00291 00292 one = DD_ONE(manager); 00293 zero = DD_ZERO(manager); 00294 00295 if (f == Cudd_Not(one) || f == zero) { 00296 *length = DD_BIGGY; 00297 return(Cudd_Not(one)); 00298 } 00299 /* From this point on, a path exists. */ 00300 00301 do { 00302 manager->reordered = 0; 00303 00304 /* Initialize visited table. */ 00305 visited = st_init_table(st_ptrcmp, st_ptrhash); 00306 00307 /* Now get the length of the shortest path(s) from f to 1. */ 00308 (void) getLargest(f, visited); 00309 00310 complement = Cudd_IsComplement(f); 00311 00312 F = Cudd_Regular(f); 00313 00314 if (!st_lookup(visited, F, &rootPair)) return(NULL); 00315 00316 if (complement) { 00317 cost = rootPair->neg; 00318 } else { 00319 cost = rootPair->pos; 00320 } 00321 00322 /* Recover an actual shortest path. */ 00323 sol = getCube(manager,visited,f,cost); 00324 00325 st_foreach(visited, freePathPair, NULL); 00326 st_free_table(visited); 00327 00328 } while (manager->reordered == 1); 00329 00330 *length = cost; 00331 return(sol); 00332 00333 } /* end of Cudd_LargestCube */
Function********************************************************************
Synopsis [Converts a ZDD cover to a BDD graph.]
Description [Converts a ZDD cover to a BDD graph. If successful, it returns a BDD node, otherwise it returns NULL.]
SideEffects []
SeeAlso [cuddMakeBddFromZddCover]
Definition at line 199 of file cuddZddIsop.c.
00202 { 00203 DdNode *res; 00204 00205 do { 00206 dd->reordered = 0; 00207 res = cuddMakeBddFromZddCover(dd, node); 00208 } while (dd->reordered == 1); 00209 return(res); 00210 } /* end of Cudd_MakeBddFromZddCover */
MtrNode* Cudd_MakeTreeNode | ( | DdManager * | dd, | |
unsigned int | low, | |||
unsigned int | size, | |||
unsigned int | type | |||
) |
AutomaticEnd Function********************************************************************
Synopsis [Creates a new variable group.]
Description [Creates a new variable group. The group starts at variable and contains size variables. The parameter low is the index of the first variable. If the variable already exists, its current position in the order is known to the manager. If the variable does not exist yet, the position is assumed to be the same as the index. The group tree is created if it does not exist yet. Returns a pointer to the group if successful; NULL otherwise.]
SideEffects [The variable tree is changed.]
SeeAlso [Cudd_MakeZddTreeNode]
Definition at line 202 of file cuddGroup.c.
00207 { 00208 MtrNode *group; 00209 MtrNode *tree; 00210 unsigned int level; 00211 00212 /* If the variable does not exist yet, the position is assumed to be 00213 ** the same as the index. Therefore, applications that rely on 00214 ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new 00215 ** variables have to create the variables before they group them. 00216 */ 00217 level = (low < (unsigned int) dd->size) ? dd->perm[low] : low; 00218 00219 if (level + size - 1> (int) MTR_MAXHIGH) 00220 return(NULL); 00221 00222 /* If the tree does not exist yet, create it. */ 00223 tree = dd->tree; 00224 if (tree == NULL) { 00225 dd->tree = tree = Mtr_InitGroupTree(0, dd->size); 00226 if (tree == NULL) 00227 return(NULL); 00228 tree->index = dd->invperm[0]; 00229 } 00230 00231 /* Extend the upper bound of the tree if necessary. This allows the 00232 ** application to create groups even before the variables are created. 00233 */ 00234 tree->size = ddMax(tree->size, ddMax(level + size, (unsigned) dd->size)); 00235 00236 /* Create the group. */ 00237 group = Mtr_MakeGroup(tree, level, size, type); 00238 if (group == NULL) 00239 return(NULL); 00240 00241 /* Initialize the index field to the index of the variable currently 00242 ** in position low. This field will be updated by the reordering 00243 ** procedure to provide a handle to the group once it has been moved. 00244 */ 00245 group->index = (MtrHalfWord) low; 00246 00247 return(group); 00248 00249 } /* end of Cudd_MakeTreeNode */
MtrNode* Cudd_MakeZddTreeNode | ( | DdManager * | dd, | |
unsigned int | low, | |||
unsigned int | size, | |||
unsigned int | type | |||
) |
AutomaticEnd Function********************************************************************
Synopsis [Creates a new ZDD variable group.]
Description [Creates a new ZDD variable group. The group starts at variable and contains size variables. The parameter low is the index of the first variable. If the variable already exists, its current position in the order is known to the manager. If the variable does not exist yet, the position is assumed to be the same as the index. The group tree is created if it does not exist yet. Returns a pointer to the group if successful; NULL otherwise.]
SideEffects [The ZDD variable tree is changed.]
SeeAlso [Cudd_MakeTreeNode]
Definition at line 159 of file cuddZddGroup.c.
00164 { 00165 MtrNode *group; 00166 MtrNode *tree; 00167 unsigned int level; 00168 00169 /* If the variable does not exist yet, the position is assumed to be 00170 ** the same as the index. Therefore, applications that rely on 00171 ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new 00172 ** variables have to create the variables before they group them. 00173 */ 00174 level = (low < (unsigned int) dd->sizeZ) ? dd->permZ[low] : low; 00175 00176 if (level + size - 1> (int) MTR_MAXHIGH) 00177 return(NULL); 00178 00179 /* If the tree does not exist yet, create it. */ 00180 tree = dd->treeZ; 00181 if (tree == NULL) { 00182 dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ); 00183 if (tree == NULL) 00184 return(NULL); 00185 tree->index = dd->invpermZ[0]; 00186 } 00187 00188 /* Extend the upper bound of the tree if necessary. This allows the 00189 ** application to create groups even before the variables are created. 00190 */ 00191 tree->size = ddMax(tree->size, level + size); 00192 00193 /* Create the group. */ 00194 group = Mtr_MakeGroup(tree, level, size, type); 00195 if (group == NULL) 00196 return(NULL); 00197 00198 /* Initialize the index field to the index of the variable currently 00199 ** in position low. This field will be updated by the reordering 00200 ** procedure to provide a handle to the group once it has been moved. 00201 */ 00202 group->index = (MtrHalfWord) low; 00203 00204 return(group); 00205 00206 } /* end of Cudd_MakeZddTreeNode */
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 */
DdApaNumber Cudd_NewApaNumber | ( | int | digits | ) |
Function********************************************************************
Synopsis [Allocates memory for an arbitrary precision integer.]
Description [Allocates memory for an arbitrary precision integer. Returns a pointer to the allocated memory if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 170 of file cuddApa.c.
00172 { 00173 return(ALLOC(DdApaDigit, digits)); 00174 00175 } /* end of Cudd_NewApaNumber */
int Cudd_NextCube | ( | DdGen * | gen, | |
int ** | cube, | |||
CUDD_VALUE_TYPE * | value | |||
) |
Function********************************************************************
Synopsis [Generates the next cube of a decision diagram onset.]
Description [Generates the next cube of a decision diagram onset, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]
SideEffects [The cube and its value are returned as side effects. The generator is modified.]
SeeAlso [Cudd_ForeachCube Cudd_FirstCube Cudd_GenFree Cudd_IsGenEmpty Cudd_NextNode]
Definition at line 1913 of file cuddUtil.c.
01917 { 01918 DdNode *top, *treg, *next, *nreg, *prev, *preg; 01919 DdManager *dd = gen->manager; 01920 01921 /* Backtrack from previously reached terminal node. */ 01922 while (1) { 01923 if (gen->stack.sp == 1) { 01924 /* The current node has no predecessor. */ 01925 gen->status = CUDD_GEN_EMPTY; 01926 gen->stack.sp--; 01927 goto done; 01928 } 01929 top = gen->stack.stack[gen->stack.sp-1]; 01930 treg = Cudd_Regular(top); 01931 prev = gen->stack.stack[gen->stack.sp-2]; 01932 preg = Cudd_Regular(prev); 01933 nreg = cuddT(preg); 01934 if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} 01935 if (next != top) { /* follow the then branch next */ 01936 gen->gen.cubes.cube[preg->index] = 1; 01937 gen->stack.stack[gen->stack.sp-1] = next; 01938 break; 01939 } 01940 /* Pop the stack and try again. */ 01941 gen->gen.cubes.cube[preg->index] = 2; 01942 gen->stack.sp--; 01943 } 01944 01945 while (1) { 01946 top = gen->stack.stack[gen->stack.sp-1]; 01947 treg = Cudd_Regular(top); 01948 if (!cuddIsConstant(treg)) { 01949 /* Take the else branch first. */ 01950 gen->gen.cubes.cube[treg->index] = 0; 01951 next = cuddE(treg); 01952 if (top != treg) next = Cudd_Not(next); 01953 gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; 01954 } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { 01955 /* Backtrack */ 01956 while (1) { 01957 if (gen->stack.sp == 1) { 01958 /* The current node has no predecessor. */ 01959 gen->status = CUDD_GEN_EMPTY; 01960 gen->stack.sp--; 01961 goto done; 01962 } 01963 prev = gen->stack.stack[gen->stack.sp-2]; 01964 preg = Cudd_Regular(prev); 01965 nreg = cuddT(preg); 01966 if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} 01967 if (next != top) { /* follow the then branch next */ 01968 gen->gen.cubes.cube[preg->index] = 1; 01969 gen->stack.stack[gen->stack.sp-1] = next; 01970 break; 01971 } 01972 /* Pop the stack and try again. */ 01973 gen->gen.cubes.cube[preg->index] = 2; 01974 gen->stack.sp--; 01975 top = gen->stack.stack[gen->stack.sp-1]; 01976 treg = Cudd_Regular(top); 01977 } 01978 } else { 01979 gen->status = CUDD_GEN_NONEMPTY; 01980 gen->gen.cubes.value = cuddV(top); 01981 goto done; 01982 } 01983 } 01984 01985 done: 01986 if (gen->status == CUDD_GEN_EMPTY) return(0); 01987 *cube = gen->gen.cubes.cube; 01988 *value = gen->gen.cubes.value; 01989 return(1); 01990 01991 } /* end of Cudd_NextCube */
Function********************************************************************
Synopsis [Finds the next node of a decision diagram.]
Description [Finds the node of a decision diagram, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]
SideEffects [The next node is returned as a side effect.]
SeeAlso [Cudd_ForeachNode Cudd_FirstNode Cudd_GenFree Cudd_IsGenEmpty Cudd_NextCube]
Definition at line 2455 of file cuddUtil.c.
02458 { 02459 /* Find the next node. */ 02460 gen->stack.sp++; 02461 if (gen->stack.sp < gen->gen.nodes.size) { 02462 gen->node = gen->stack.stack[gen->stack.sp]; 02463 *node = gen->node; 02464 return(1); 02465 } else { 02466 gen->status = CUDD_GEN_EMPTY; 02467 return(0); 02468 } 02469 02470 } /* end of Cudd_NextNode */
int Cudd_NextPrime | ( | DdGen * | gen, | |
int ** | cube | |||
) |
Function********************************************************************
Synopsis [Generates the next prime of a Boolean function.]
Description [Generates the next cube of a Boolean function, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]
SideEffects [The cube and is returned as side effects. The generator is modified.]
SeeAlso [Cudd_ForeachPrime Cudd_FirstPrime Cudd_GenFree Cudd_IsGenEmpty Cudd_NextCube Cudd_NextNode]
Definition at line 2126 of file cuddUtil.c.
02129 { 02130 DdNode *implicant, *prime, *tmp; 02131 DdManager *dd = gen->manager; 02132 int length, result; 02133 02134 if (gen->node == Cudd_ReadLogicZero(dd)) { 02135 gen->status = CUDD_GEN_EMPTY; 02136 } else { 02137 implicant = Cudd_LargestCube(dd,gen->node,&length); 02138 if (implicant == NULL) { 02139 gen->status = CUDD_GEN_EMPTY; 02140 return(0); 02141 } 02142 cuddRef(implicant); 02143 prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); 02144 if (prime == NULL) { 02145 Cudd_RecursiveDeref(dd,implicant); 02146 gen->status = CUDD_GEN_EMPTY; 02147 return(0); 02148 } 02149 cuddRef(prime); 02150 Cudd_RecursiveDeref(dd,implicant); 02151 tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); 02152 if (tmp == NULL) { 02153 Cudd_RecursiveDeref(dd,prime); 02154 gen->status = CUDD_GEN_EMPTY; 02155 return(0); 02156 } 02157 cuddRef(tmp); 02158 Cudd_RecursiveDeref(dd,gen->node); 02159 gen->node = tmp; 02160 result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); 02161 if (result == 0) { 02162 Cudd_RecursiveDeref(dd,prime); 02163 gen->status = CUDD_GEN_EMPTY; 02164 return(0); 02165 } 02166 Cudd_RecursiveDeref(dd,prime); 02167 gen->status = CUDD_GEN_NONEMPTY; 02168 } 02169 if (gen->status == CUDD_GEN_EMPTY) return(0); 02170 *cube = gen->gen.primes.cube; 02171 return(1); 02172 02173 } /* end of Cudd_NextPrime */
unsigned int Cudd_NodeReadIndex | ( | DdNode * | node | ) |
Function********************************************************************
Synopsis [Returns the index of the node.]
Description [Returns the index of the node. The node pointer can be either regular or complemented.]
SideEffects [None]
SeeAlso [Cudd_ReadIndex]
Definition at line 2273 of file cuddAPI.c.
02275 { 02276 return((unsigned int) Cudd_Regular(node)->index); 02277 02278 } /* end of Cudd_NodeReadIndex */
void Cudd_OutOfMem | ( | long | size | ) |
Function********************************************************************
Synopsis [Warns that a memory allocation failed.]
Description [Warns that a memory allocation failed. This function can be used as replacement of MMout_of_memory to prevent the safe_mem functions of the util package from exiting when malloc returns NULL. One possible use is in case of discretionary allocations; for instance, the allocation of memory to enlarge the computed table.]
SideEffects [None]
SeeAlso []
Definition at line 2833 of file cuddUtil.c.
02835 { 02836 (void) fflush(stdout); 02837 (void) fprintf(stderr, "\nunable to allocate %ld bytes\n", size); 02838 return; 02839 02840 } /* end of Cudd_OutOfMem */
DdNode* Cudd_OverApprox | ( | DdManager * | dd, | |
DdNode * | f, | |||
int | numVars, | |||
int | threshold, | |||
int | safe, | |||
double | quality | |||
) |
Function********************************************************************
Synopsis [Extracts a dense superset from a BDD with Shiple's underapproximation method.]
Description [Extracts a dense superset from a BDD. The procedure is identical to the underapproximation procedure except for the fact that it works on the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. Returns a pointer to the BDD of the superset if successful. NULL if intermediate result causes the procedure to run out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]
SideEffects [None]
SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize]
Definition at line 271 of file cuddApprox.c.
00278 { 00279 DdNode *subset, *g; 00280 00281 g = Cudd_Not(f); 00282 do { 00283 dd->reordered = 0; 00284 subset = cuddUnderApprox(dd, g, numVars, threshold, safe, quality); 00285 } while (dd->reordered == 1); 00286 00287 return(Cudd_NotCond(subset, (subset != NULL))); 00288 00289 } /* end of Cudd_OverApprox */
unsigned int Cudd_Prime | ( | unsigned int | p | ) |
AutomaticEnd Function********************************************************************
Synopsis [Returns the next prime >= p.]
Description []
SideEffects [None]
Definition at line 184 of file cuddTable.c.
00186 { 00187 int i,pn; 00188 00189 p--; 00190 do { 00191 p++; 00192 if (p&1) { 00193 pn = 1; 00194 i = 3; 00195 while ((unsigned) (i * i) <= p) { 00196 if (p % i == 0) { 00197 pn = 0; 00198 break; 00199 } 00200 i += 2; 00201 } 00202 } else { 00203 pn = 0; 00204 } 00205 } while (!pn); 00206 return(p); 00207 00208 } /* end of Cudd_Prime */
Function********************************************************************
Synopsis [Prints to the standard output a DD and its statistics.]
Description [Prints to the standard output a DD and its statistics. The statistics include the number of nodes, the number of leaves, and the number of minterms. (The number of minterms is the number of assignments to the variables that cause the function to be different from the logical zero (for BDDs) and from the background value (for ADDs.) The statistics are printed if pr > 0. Specifically:
For the purpose of counting the number of minterms, the function is supposed to depend on n variables. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_DagSize Cudd_CountLeaves Cudd_CountMinterm Cudd_PrintMinterm]
Definition at line 378 of file cuddUtil.c.
00383 { 00384 DdNode *azero, *bzero; 00385 int nodes; 00386 int leaves; 00387 double minterms; 00388 int retval = 1; 00389 00390 if (f == NULL) { 00391 (void) fprintf(dd->out,": is the NULL DD\n"); 00392 (void) fflush(dd->out); 00393 return(0); 00394 } 00395 azero = DD_ZERO(dd); 00396 bzero = Cudd_Not(DD_ONE(dd)); 00397 if ((f == azero || f == bzero) && pr > 0){ 00398 (void) fprintf(dd->out,": is the zero DD\n"); 00399 (void) fflush(dd->out); 00400 return(1); 00401 } 00402 if (pr > 0) { 00403 nodes = Cudd_DagSize(f); 00404 if (nodes == CUDD_OUT_OF_MEM) retval = 0; 00405 leaves = Cudd_CountLeaves(f); 00406 if (leaves == CUDD_OUT_OF_MEM) retval = 0; 00407 minterms = Cudd_CountMinterm(dd, f, n); 00408 if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; 00409 (void) fprintf(dd->out,": %d nodes %d leaves %g minterms\n", 00410 nodes, leaves, minterms); 00411 if (pr > 2) { 00412 if (!cuddP(dd, f)) retval = 0; 00413 } 00414 if (pr == 2 || pr > 3) { 00415 if (!Cudd_PrintMinterm(dd,f)) retval = 0; 00416 (void) fprintf(dd->out,"\n"); 00417 } 00418 (void) fflush(dd->out); 00419 } 00420 return(retval); 00421 00422 } /* end of Cudd_PrintDebug */
int Cudd_PrintInfo | ( | DdManager * | dd, | |
FILE * | fp | |||
) |
Function********************************************************************
Synopsis [Prints out statistics and settings for a CUDD manager.]
Description [Prints out statistics and settings for a CUDD manager. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 2933 of file cuddAPI.c.
02936 { 02937 int retval; 02938 Cudd_ReorderingType autoMethod, autoMethodZ; 02939 02940 /* Modifiable parameters. */ 02941 retval = fprintf(fp,"**** CUDD modifiable parameters ****\n"); 02942 if (retval == EOF) return(0); 02943 retval = fprintf(fp,"Hard limit for cache size: %u\n", 02944 Cudd_ReadMaxCacheHard(dd)); 02945 if (retval == EOF) return(0); 02946 retval = fprintf(fp,"Cache hit threshold for resizing: %u%%\n", 02947 Cudd_ReadMinHit(dd)); 02948 if (retval == EOF) return(0); 02949 retval = fprintf(fp,"Garbage collection enabled: %s\n", 02950 Cudd_GarbageCollectionEnabled(dd) ? "yes" : "no"); 02951 if (retval == EOF) return(0); 02952 retval = fprintf(fp,"Limit for fast unique table growth: %u\n", 02953 Cudd_ReadLooseUpTo(dd)); 02954 if (retval == EOF) return(0); 02955 retval = fprintf(fp, 02956 "Maximum number of variables sifted per reordering: %d\n", 02957 Cudd_ReadSiftMaxVar(dd)); 02958 if (retval == EOF) return(0); 02959 retval = fprintf(fp, 02960 "Maximum number of variable swaps per reordering: %d\n", 02961 Cudd_ReadSiftMaxSwap(dd)); 02962 if (retval == EOF) return(0); 02963 retval = fprintf(fp,"Maximum growth while sifting a variable: %g\n", 02964 Cudd_ReadMaxGrowth(dd)); 02965 if (retval == EOF) return(0); 02966 retval = fprintf(fp,"Dynamic reordering of BDDs enabled: %s\n", 02967 Cudd_ReorderingStatus(dd,&autoMethod) ? "yes" : "no"); 02968 if (retval == EOF) return(0); 02969 retval = fprintf(fp,"Default BDD reordering method: %d\n", 02970 (int) autoMethod); 02971 if (retval == EOF) return(0); 02972 retval = fprintf(fp,"Dynamic reordering of ZDDs enabled: %s\n", 02973 Cudd_ReorderingStatusZdd(dd,&autoMethodZ) ? "yes" : "no"); 02974 if (retval == EOF) return(0); 02975 retval = fprintf(fp,"Default ZDD reordering method: %d\n", 02976 (int) autoMethodZ); 02977 if (retval == EOF) return(0); 02978 retval = fprintf(fp,"Realignment of ZDDs to BDDs enabled: %s\n", 02979 Cudd_zddRealignmentEnabled(dd) ? "yes" : "no"); 02980 if (retval == EOF) return(0); 02981 retval = fprintf(fp,"Realignment of BDDs to ZDDs enabled: %s\n", 02982 Cudd_bddRealignmentEnabled(dd) ? "yes" : "no"); 02983 if (retval == EOF) return(0); 02984 retval = fprintf(fp,"Dead nodes counted in triggering reordering: %s\n", 02985 Cudd_DeadAreCounted(dd) ? "yes" : "no"); 02986 if (retval == EOF) return(0); 02987 retval = fprintf(fp,"Group checking criterion: %d\n", 02988 (int) Cudd_ReadGroupcheck(dd)); 02989 if (retval == EOF) return(0); 02990 retval = fprintf(fp,"Recombination threshold: %d\n", Cudd_ReadRecomb(dd)); 02991 if (retval == EOF) return(0); 02992 retval = fprintf(fp,"Symmetry violation threshold: %d\n", 02993 Cudd_ReadSymmviolation(dd)); 02994 if (retval == EOF) return(0); 02995 retval = fprintf(fp,"Arc violation threshold: %d\n", 02996 Cudd_ReadArcviolation(dd)); 02997 if (retval == EOF) return(0); 02998 retval = fprintf(fp,"GA population size: %d\n", 02999 Cudd_ReadPopulationSize(dd)); 03000 if (retval == EOF) return(0); 03001 retval = fprintf(fp,"Number of crossovers for GA: %d\n", 03002 Cudd_ReadNumberXovers(dd)); 03003 if (retval == EOF) return(0); 03004 retval = fprintf(fp,"Next reordering threshold: %u\n", 03005 Cudd_ReadNextReordering(dd)); 03006 if (retval == EOF) return(0); 03007 03008 /* Non-modifiable parameters. */ 03009 retval = fprintf(fp,"**** CUDD non-modifiable parameters ****\n"); 03010 if (retval == EOF) return(0); 03011 retval = fprintf(fp,"Memory in use: %lu\n", Cudd_ReadMemoryInUse(dd)); 03012 if (retval == EOF) return(0); 03013 retval = fprintf(fp,"Peak number of nodes: %ld\n", 03014 Cudd_ReadPeakNodeCount(dd)); 03015 if (retval == EOF) return(0); 03016 retval = fprintf(fp,"Peak number of live nodes: %d\n", 03017 Cudd_ReadPeakLiveNodeCount(dd)); 03018 if (retval == EOF) return(0); 03019 retval = fprintf(fp,"Number of BDD variables: %d\n", dd->size); 03020 if (retval == EOF) return(0); 03021 retval = fprintf(fp,"Number of ZDD variables: %d\n", dd->sizeZ); 03022 if (retval == EOF) return(0); 03023 retval = fprintf(fp,"Number of cache entries: %u\n", dd->cacheSlots); 03024 if (retval == EOF) return(0); 03025 retval = fprintf(fp,"Number of cache look-ups: %.0f\n", 03026 Cudd_ReadCacheLookUps(dd)); 03027 if (retval == EOF) return(0); 03028 retval = fprintf(fp,"Number of cache hits: %.0f\n", 03029 Cudd_ReadCacheHits(dd)); 03030 if (retval == EOF) return(0); 03031 retval = fprintf(fp,"Number of cache insertions: %.0f\n", 03032 dd->cacheinserts); 03033 if (retval == EOF) return(0); 03034 retval = fprintf(fp,"Number of cache collisions: %.0f\n", 03035 dd->cachecollisions); 03036 if (retval == EOF) return(0); 03037 retval = fprintf(fp,"Number of cache deletions: %.0f\n", 03038 dd->cachedeletions); 03039 if (retval == EOF) return(0); 03040 retval = cuddCacheProfile(dd,fp); 03041 if (retval == 0) return(0); 03042 retval = fprintf(fp,"Soft limit for cache size: %u\n", 03043 Cudd_ReadMaxCache(dd)); 03044 if (retval == EOF) return(0); 03045 retval = fprintf(fp,"Number of buckets in unique table: %u\n", dd->slots); 03046 if (retval == EOF) return(0); 03047 retval = fprintf(fp,"Used buckets in unique table: %.2f%% (expected %.2f%%)\n", 03048 100.0 * Cudd_ReadUsedSlots(dd), 03049 100.0 * Cudd_ExpectedUsedSlots(dd)); 03050 if (retval == EOF) return(0); 03051 #ifdef DD_UNIQUE_PROFILE 03052 retval = fprintf(fp,"Unique lookups: %.0f\n", dd->uniqueLookUps); 03053 if (retval == EOF) return(0); 03054 retval = fprintf(fp,"Unique links: %.0f (%g per lookup)\n", 03055 dd->uniqueLinks, dd->uniqueLinks / dd->uniqueLookUps); 03056 if (retval == EOF) return(0); 03057 #endif 03058 retval = fprintf(fp,"Number of BDD and ADD nodes: %u\n", dd->keys); 03059 if (retval == EOF) return(0); 03060 retval = fprintf(fp,"Number of ZDD nodes: %u\n", dd->keysZ); 03061 if (retval == EOF) return(0); 03062 retval = fprintf(fp,"Number of dead BDD and ADD nodes: %u\n", dd->dead); 03063 if (retval == EOF) return(0); 03064 retval = fprintf(fp,"Number of dead ZDD nodes: %u\n", dd->deadZ); 03065 if (retval == EOF) return(0); 03066 retval = fprintf(fp,"Total number of nodes allocated: %.0f\n", 03067 dd->allocated); 03068 if (retval == EOF) return(0); 03069 retval = fprintf(fp,"Total number of nodes reclaimed: %.0f\n", 03070 dd->reclaimed); 03071 if (retval == EOF) return(0); 03072 #ifdef DD_STATS 03073 retval = fprintf(fp,"Nodes freed: %.0f\n", dd->nodesFreed); 03074 if (retval == EOF) return(0); 03075 retval = fprintf(fp,"Nodes dropped: %.0f\n", dd->nodesDropped); 03076 if (retval == EOF) return(0); 03077 #endif 03078 #ifdef DD_COUNT 03079 retval = fprintf(fp,"Number of recursive calls: %.0f\n", 03080 Cudd_ReadRecursiveCalls(dd)); 03081 if (retval == EOF) return(0); 03082 #endif 03083 retval = fprintf(fp,"Garbage collections so far: %d\n", 03084 Cudd_ReadGarbageCollections(dd)); 03085 if (retval == EOF) return(0); 03086 retval = fprintf(fp,"Time for garbage collection: %.2f sec\n", 03087 ((double)Cudd_ReadGarbageCollectionTime(dd)/1000.0)); 03088 if (retval == EOF) return(0); 03089 retval = fprintf(fp,"Reorderings so far: %d\n", dd->reorderings); 03090 if (retval == EOF) return(0); 03091 retval = fprintf(fp,"Time for reordering: %.2f sec\n", 03092 ((double)Cudd_ReadReorderingTime(dd)/1000.0)); 03093 if (retval == EOF) return(0); 03094 #ifdef DD_COUNT 03095 retval = fprintf(fp,"Node swaps in reordering: %.0f\n", 03096 Cudd_ReadSwapSteps(dd)); 03097 if (retval == EOF) return(0); 03098 #endif 03099 03100 return(1); 03101 03102 } /* end of Cudd_PrintInfo */
int Cudd_PrintLinear | ( | DdManager * | table | ) |
AutomaticEnd Function********************************************************************
Synopsis [Prints the linear transform matrix.]
Description [Prints the linear transform matrix. Returns 1 in case of success; 0 otherwise.]
SideEffects [none]
SeeAlso []
Definition at line 149 of file cuddLinear.c.
00151 { 00152 int i,j,k; 00153 int retval; 00154 int nvars = table->linearSize; 00155 int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; 00156 long word; 00157 00158 for (i = 0; i < nvars; i++) { 00159 for (j = 0; j < wordsPerRow; j++) { 00160 word = table->linear[i*wordsPerRow + j]; 00161 for (k = 0; k < BPL; k++) { 00162 retval = fprintf(table->out,"%ld",word & 1); 00163 if (retval == 0) return(0); 00164 word >>= 1; 00165 } 00166 } 00167 retval = fprintf(table->out,"\n"); 00168 if (retval == 0) return(0); 00169 } 00170 return(1); 00171 00172 } /* end of Cudd_PrintLinear */
AutomaticEnd Function********************************************************************
Synopsis [Prints a disjoint sum of products.]
Description [Prints a disjoint sum of product cover for the function rooted at node. Each product corresponds to a path from node to a leaf node different from the logical zero, and different from the background value. Uses the package default output file. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_PrintDebug Cudd_bddPrintCover]
Definition at line 212 of file cuddUtil.c.
00215 { 00216 int i, *list; 00217 00218 background = manager->background; 00219 zero = Cudd_Not(manager->one); 00220 list = ALLOC(int,manager->size); 00221 if (list == NULL) { 00222 manager->errorCode = CUDD_MEMORY_OUT; 00223 return(0); 00224 } 00225 for (i = 0; i < manager->size; i++) list[i] = 2; 00226 ddPrintMintermAux(manager,node,list); 00227 FREE(list); 00228 return(1); 00229 00230 } /* end of Cudd_PrintMinterm */
Function********************************************************************
Synopsis [Prints the two literal clauses of a DD.]
Description [Prints the one- and two-literal clauses. Returns 1 if successful; 0 otherwise. The argument "names" can be NULL, in which case the variable indices are printed.]
SideEffects [None]
SeeAlso [Cudd_FindTwoLiteralClauses]
Definition at line 389 of file cuddEssent.c.
00394 { 00395 DdHalfWord *vars; 00396 BitVector *phases; 00397 int i; 00398 DdTlcInfo *res = Cudd_FindTwoLiteralClauses(dd, f); 00399 FILE *ifp = fp == NULL ? dd->out : fp; 00400 00401 if (res == NULL) return(0); 00402 vars = res->vars; 00403 phases = res->phases; 00404 for (i = 0; !sentinelp(vars[i], vars[i+1]); i += 2) { 00405 if (names != NULL) { 00406 if (vars[i+1] == CUDD_MAXINDEX) { 00407 (void) fprintf(ifp, "%s%s\n", 00408 bitVectorRead(phases, i) ? "~" : " ", 00409 names[vars[i]]); 00410 } else { 00411 (void) fprintf(ifp, "%s%s | %s%s\n", 00412 bitVectorRead(phases, i) ? "~" : " ", 00413 names[vars[i]], 00414 bitVectorRead(phases, i+1) ? "~" : " ", 00415 names[vars[i+1]]); 00416 } 00417 } else { 00418 if (vars[i+1] == CUDD_MAXINDEX) { 00419 (void) fprintf(ifp, "%s%d\n", 00420 bitVectorRead(phases, i) ? "~" : " ", 00421 (int) vars[i]); 00422 } else { 00423 (void) fprintf(ifp, "%s%d | %s%d\n", 00424 bitVectorRead(phases, i) ? "~" : " ", 00425 (int) vars[i], 00426 bitVectorRead(phases, i+1) ? "~" : " ", 00427 (int) vars[i+1]); 00428 } 00429 } 00430 } 00431 Cudd_tlcInfoFree(res); 00432 00433 return(1); 00434 00435 } /* end of Cudd_PrintTwoLiteralClauses */
void Cudd_PrintVersion | ( | FILE * | fp | ) |
Function********************************************************************
Synopsis [Prints the package version number.]
Description []
SideEffects [None]
SeeAlso []
Definition at line 2588 of file cuddUtil.c.
02590 { 02591 (void) fprintf(fp, "%s\n", CUDD_VERSION); 02592 02593 } /* end of Cudd_PrintVersion */
DdNode* Cudd_PrioritySelect | ( | DdManager * | dd, | |
DdNode * | R, | |||
DdNode ** | x, | |||
DdNode ** | y, | |||
DdNode ** | z, | |||
DdNode * | Pi, | |||
int | n, | |||
DdNode * | *)(DdManager *, int, DdNode **, DdNode **, DdNode ** | |||
) |
void Cudd_Quit | ( | DdManager * | unique | ) |
Function********************************************************************
Synopsis [Deletes resources associated with a DD manager.]
Description [Deletes resources associated with a DD manager and resets the global statistical counters. (Otherwise, another manaqger subsequently created would inherit the stats of this one.)]
SideEffects [None]
SeeAlso [Cudd_Init]
Definition at line 218 of file cuddInit.c.
00220 { 00221 if (unique->stash != NULL) FREE(unique->stash); 00222 cuddFreeTable(unique); 00223 00224 } /* end of Cudd_Quit */
long Cudd_Random | ( | void | ) |
Function********************************************************************
Synopsis [Portable random number generator.]
Description [Portable number generator based on ran2 from "Numerical Recipes in C." It is a long period (> 2 * 10^18) random number generator of L'Ecuyer with Bays-Durham shuffle. Returns a long integer uniformly distributed between 0 and 2147483561 (inclusive of the endpoint values). The random generator can be explicitly initialized by calling Cudd_Srandom. If no explicit initialization is performed, then the seed 1 is assumed.]
SideEffects [None]
SeeAlso [Cudd_Srandom]
Definition at line 2698 of file cuddUtil.c.
02699 { 02700 int i; /* index in the shuffle table */ 02701 long int w; /* work variable */ 02702 02703 /* cuddRand == 0 if the geneartor has not been initialized yet. */ 02704 if (cuddRand == 0) Cudd_Srandom(1); 02705 02706 /* Compute cuddRand = (cuddRand * LEQA1) % MODULUS1 avoiding 02707 ** overflows by Schrage's method. 02708 */ 02709 w = cuddRand / LEQQ1; 02710 cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; 02711 cuddRand += (cuddRand < 0) * MODULUS1; 02712 02713 /* Compute cuddRand2 = (cuddRand2 * LEQA2) % MODULUS2 avoiding 02714 ** overflows by Schrage's method. 02715 */ 02716 w = cuddRand2 / LEQQ2; 02717 cuddRand2 = LEQA2 * (cuddRand2 - w * LEQQ2) - w * LEQR2; 02718 cuddRand2 += (cuddRand2 < 0) * MODULUS2; 02719 02720 /* cuddRand is shuffled with the Bays-Durham algorithm. 02721 ** shuffleSelect and cuddRand2 are combined to generate the output. 02722 */ 02723 02724 /* Pick one element from the shuffle table; "i" will be in the range 02725 ** from 0 to STAB_SIZE-1. 02726 */ 02727 i = (int) (shuffleSelect / STAB_DIV); 02728 /* Mix the element of the shuffle table with the current iterate of 02729 ** the second sub-generator, and replace the chosen element of the 02730 ** shuffle table with the current iterate of the first sub-generator. 02731 */ 02732 shuffleSelect = shuffleTable[i] - cuddRand2; 02733 shuffleTable[i] = cuddRand; 02734 shuffleSelect += (shuffleSelect < 1) * (MODULUS1 - 1); 02735 /* Since shuffleSelect != 0, and we want to be able to return 0, 02736 ** here we subtract 1 before returning. 02737 */ 02738 return(shuffleSelect - 1); 02739 02740 } /* end of Cudd_Random */
int Cudd_ReadArcviolation | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the current value of the arcviolation parameter used in group sifting.]
Description [Returns the current value of the arcviolation parameter. This parameter is used in group sifting to decide how many arcs into y
not coming from x
are tolerable when checking for aggregation due to extended symmetry. The value should be between 0 and 100. A small value causes fewer variables to be aggregated. The default value is 0.]
SideEffects [None]
SeeAlso [Cudd_SetArcviolation]
Definition at line 2760 of file cuddAPI.c.
02762 { 02763 return(dd->arcviolation); 02764 02765 } /* end of Cudd_ReadArcviolation */
Function********************************************************************
Synopsis [Reads the background constant of the manager.]
Description []
SideEffects [None]
Definition at line 1108 of file cuddAPI.c.
01110 { 01111 return(dd->background); 01112 01113 } /* end of Cudd_ReadBackground */
double Cudd_ReadCacheHits | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of cache hits.]
Description []
SideEffects [None]
SeeAlso [Cudd_ReadCacheLookUps]
Definition at line 1221 of file cuddAPI.c.
01223 { 01224 return(dd->cacheHits + dd->totCachehits); 01225 01226 } /* end of Cudd_ReadCacheHits */
double Cudd_ReadCacheLookUps | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of cache look-ups.]
Description [Returns the number of cache look-ups.]
SideEffects [None]
SeeAlso [Cudd_ReadCacheHits]
Definition at line 1200 of file cuddAPI.c.
01202 { 01203 return(dd->cacheHits + dd->cacheMisses + 01204 dd->totCachehits + dd->totCacheMisses); 01205 01206 } /* end of Cudd_ReadCacheLookUps */
unsigned int Cudd_ReadCacheSlots | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the number of slots in the cache.]
Description []
SideEffects [None]
SeeAlso [Cudd_ReadCacheUsedSlots]
Definition at line 1148 of file cuddAPI.c.
01150 { 01151 return(dd->cacheSlots); 01152 01153 } /* end of Cudd_ReadCacheSlots */
double Cudd_ReadCacheUsedSlots | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the fraction of used slots in the cache.]
Description [Reads the fraction of used slots in the cache. The unused slots are those in which no valid data is stored. Garbage collection, variable reordering, and cache resizing may cause used slots to become unused.]
SideEffects [None]
SeeAlso [Cudd_ReadCacheSlots]
Definition at line 1171 of file cuddAPI.c.
01173 { 01174 unsigned long used = 0; 01175 int slots = dd->cacheSlots; 01176 DdCache *cache = dd->cache; 01177 int i; 01178 01179 for (i = 0; i < slots; i++) { 01180 used += cache[i].h != 0; 01181 } 01182 01183 return((double)used / (double) dd->cacheSlots); 01184 01185 } /* end of Cudd_ReadCacheUsedSlots */
unsigned int Cudd_ReadDead | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of dead nodes in the unique table.]
Description []
SideEffects [None]
SeeAlso [Cudd_ReadKeys]
Definition at line 1642 of file cuddAPI.c.
01644 { 01645 return(dd->dead); 01646 01647 } /* end of Cudd_ReadDead */
CUDD_VALUE_TYPE Cudd_ReadEpsilon | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the epsilon parameter of the manager.]
Description [Reads the epsilon parameter of the manager. The epsilon parameter control the comparison between floating point numbers.]
SideEffects [None]
SeeAlso [Cudd_SetEpsilon]
Definition at line 2426 of file cuddAPI.c.
02428 { 02429 return(dd->epsilon); 02430 02431 } /* end of Cudd_ReadEpsilon */
Cudd_ErrorType Cudd_ReadErrorCode | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the code of the last error.]
Description [Returns the code of the last error. The error codes are defined in cudd.h.]
SideEffects [None]
SeeAlso [Cudd_ClearErrorCode]
Definition at line 3609 of file cuddAPI.c.
03611 { 03612 return(dd->errorCode); 03613 03614 } /* end of Cudd_ReadErrorCode */
int Cudd_ReadGarbageCollections | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of times garbage collection has occurred.]
Description [Returns the number of times garbage collection has occurred in the manager. The number includes both the calls from reordering procedures and those caused by requests to create new nodes.]
SideEffects [None]
SeeAlso [Cudd_ReadGarbageCollectionTime]
Definition at line 1737 of file cuddAPI.c.
01739 { 01740 return(dd->garbageCollections); 01741 01742 } /* end of Cudd_ReadGarbageCollections */
long Cudd_ReadGarbageCollectionTime | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the time spent in garbage collection.]
Description [Returns the number of milliseconds spent doing garbage collection since the manager was initialized.]
SideEffects [None]
SeeAlso [Cudd_ReadGarbageCollections]
Definition at line 1758 of file cuddAPI.c.
01760 { 01761 return(dd->GCTime); 01762 01763 } /* end of Cudd_ReadGarbageCollectionTime */
Cudd_AggregationType Cudd_ReadGroupcheck | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the groupcheck parameter of the manager.]
Description [Reads the groupcheck parameter of the manager. The groupcheck parameter determines the aggregation criterion in group sifting.]
SideEffects [None]
SeeAlso [Cudd_SetGroupcheck]
Definition at line 2470 of file cuddAPI.c.
02472 { 02473 return(dd->groupcheck); 02474 02475 } /* end of Cudd_ReadGroupCheck */
int Cudd_ReadInvPerm | ( | DdManager * | dd, | |
int | i | |||
) |
Function********************************************************************
Synopsis [Returns the index of the variable currently in the i-th position of the order.]
Description [Returns the index of the variable currently in the i-th position of the order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]
SideEffects [None]
SeeAlso [Cudd_ReadPerm Cudd_ReadInvPermZdd]
Definition at line 2350 of file cuddAPI.c.
02353 { 02354 if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); 02355 if (i < 0 || i >= dd->size) return(-1); 02356 return(dd->invperm[i]); 02357 02358 } /* end of Cudd_ReadInvPerm */
int Cudd_ReadInvPermZdd | ( | DdManager * | dd, | |
int | i | |||
) |
Function********************************************************************
Synopsis [Returns the index of the ZDD variable currently in the i-th position of the order.]
Description [Returns the index of the ZDD variable currently in the i-th position of the order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]
SideEffects [None]
SeeAlso [Cudd_ReadPerm Cudd_ReadInvPermZdd]
Definition at line 2376 of file cuddAPI.c.
02379 { 02380 if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); 02381 if (i < 0 || i >= dd->sizeZ) return(-1); 02382 return(dd->invpermZ[i]); 02383 02384 } /* end of Cudd_ReadInvPermZdd */
int Cudd_ReadIthClause | ( | DdTlcInfo * | tlc, | |
int | i, | |||
DdHalfWord * | var1, | |||
DdHalfWord * | var2, | |||
int * | phase1, | |||
int * | phase2 | |||
) |
Function********************************************************************
Synopsis [Accesses the i-th clause of a DD.]
Description [Accesses the i-th clause of a DD given the clause set which must be already computed. Returns 1 if successful; 0 if i is out of range, or in case of error.]
SideEffects [the four components of a clause are returned as side effects.]
SeeAlso [Cudd_FindTwoLiteralClauses]
Definition at line 355 of file cuddEssent.c.
00362 { 00363 if (tlc == NULL) return(0); 00364 if (tlc->vars == NULL || tlc->phases == NULL) return(0); 00365 if (i < 0 || (unsigned) i >= tlc->cnt) return(0); 00366 *var1 = tlc->vars[2*i]; 00367 *var2 = tlc->vars[2*i+1]; 00368 *phase1 = (int) bitVectorRead(tlc->phases, 2*i); 00369 *phase2 = (int) bitVectorRead(tlc->phases, 2*i+1); 00370 return(1); 00371 00372 } /* end of Cudd_ReadIthClause */
unsigned int Cudd_ReadKeys | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of nodes in the unique table.]
Description [Returns the total number of nodes currently in the unique table, including the dead nodes.]
SideEffects [None]
SeeAlso [Cudd_ReadDead]
Definition at line 1622 of file cuddAPI.c.
01624 { 01625 return(dd->keys); 01626 01627 } /* end of Cudd_ReadKeys */
int Cudd_ReadLinear | ( | DdManager * | table, | |
int | x, | |||
int | y | |||
) |
Function********************************************************************
Synopsis [Reads an entry of the linear transform matrix.]
Description [Reads an entry of the linear transform matrix.]
SideEffects [none]
SeeAlso []
Definition at line 187 of file cuddLinear.c.
00191 { 00192 int nvars = table->size; 00193 int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; 00194 long word; 00195 int bit; 00196 int result; 00197 00198 assert(table->size == table->linearSize); 00199 00200 word = wordsPerRow * x + (y >> LOGBPL); 00201 bit = y & (BPL-1); 00202 result = (int) ((table->linear[word] >> bit) & 1); 00203 return(result); 00204 00205 } /* end of Cudd_ReadLinear */
Function********************************************************************
Synopsis [Returns the logic zero constant of the manager.]
Description [Returns the zero constant of the manager. The logic zero constant is the complement of the one constant, and is distinct from the arithmetic zero.]
SideEffects [None]
SeeAlso [Cudd_ReadOne Cudd_ReadZero]
unsigned int Cudd_ReadLooseUpTo | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the looseUpTo parameter of the manager.]
Description []
SideEffects [None]
SeeAlso [Cudd_SetLooseUpTo Cudd_ReadMinHit Cudd_ReadMinDead]
Definition at line 1317 of file cuddAPI.c.
01319 { 01320 return(dd->looseUpTo); 01321 01322 } /* end of Cudd_ReadLooseUpTo */
unsigned int Cudd_ReadMaxCache | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the soft limit for the cache size.]
Description [Returns the soft limit for the cache size. The soft limit]
SideEffects [None]
SeeAlso [Cudd_ReadMaxCache]
Definition at line 1367 of file cuddAPI.c.
01369 { 01370 return(2 * dd->cacheSlots + dd->cacheSlack); 01371 01372 } /* end of Cudd_ReadMaxCache */
unsigned int Cudd_ReadMaxCacheHard | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the maxCacheHard parameter of the manager.]
Description []
SideEffects [None]
SeeAlso [Cudd_SetMaxCacheHard Cudd_ReadMaxCache]
Definition at line 1387 of file cuddAPI.c.
01389 { 01390 return(dd->maxCacheHard); 01391 01392 } /* end of Cudd_ReadMaxCache */
double Cudd_ReadMaxGrowth | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the maxGrowth parameter of the manager.]
Description [Reads the maxGrowth parameter of the manager. This parameter determines how much the number of nodes can grow during sifting of a variable. Overall, sifting never increases the size of the decision diagrams. This parameter only refers to intermediate results. A lower value will speed up sifting, possibly at the expense of quality.]
SideEffects [None]
SeeAlso [Cudd_SetMaxGrowth Cudd_ReadMaxGrowthAlternate]
Definition at line 1984 of file cuddAPI.c.
01986 { 01987 return(dd->maxGrowth); 01988 01989 } /* end of Cudd_ReadMaxGrowth */
double Cudd_ReadMaxGrowthAlternate | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the maxGrowthAlt parameter of the manager.]
Description [Reads the maxGrowthAlt parameter of the manager. This parameter is analogous to the maxGrowth paramter, and is used every given number of reorderings instead of maxGrowth. The number of reorderings is set with Cudd_SetReorderingCycle. If the number of reorderings is 0 (default) maxGrowthAlt is never used.]
SideEffects [None]
SeeAlso [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate Cudd_SetReorderingCycle Cudd_ReadReorderingCycle]
Definition at line 2035 of file cuddAPI.c.
02037 { 02038 return(dd->maxGrowthAlt); 02039 02040 } /* end of Cudd_ReadMaxGrowthAlternate */
unsigned int Cudd_ReadMaxLive | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the maximum allowed number of live nodes.]
Description [Reads the maximum allowed number of live nodes. When this number is exceeded, the package returns NULL.]
SideEffects [none]
SeeAlso [Cudd_SetMaxLive]
Definition at line 3809 of file cuddAPI.c.
03811 { 03812 return(dd->maxLive); 03813 03814 } /* end of Cudd_ReadMaxLive */
unsigned long Cudd_ReadMaxMemory | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the maximum allowed memory.]
Description [Reads the maximum allowed memory. When this number is exceeded, the package returns NULL.]
SideEffects [none]
SeeAlso [Cudd_SetMaxMemory]
Definition at line 3852 of file cuddAPI.c.
03854 { 03855 return(dd->maxmemhard); 03856 03857 } /* end of Cudd_ReadMaxMemory */
unsigned long Cudd_ReadMemoryInUse | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the memory in use by the manager measured in bytes.]
Description []
SideEffects [None]
SeeAlso []
Definition at line 2912 of file cuddAPI.c.
02914 { 02915 return(dd->memused); 02916 02917 } /* end of Cudd_ReadMemoryInUse */
unsigned int Cudd_ReadMinDead | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the minDead parameter of the manager.]
Description [Reads the minDead parameter of the manager. The minDead parameter is used by the package to decide whether to collect garbage or resize a subtable of the unique table when the subtable becomes too full. The application can indirectly control the value of minDead by setting the looseUpTo parameter.]
SideEffects [None]
SeeAlso [Cudd_ReadDead Cudd_ReadLooseUpTo Cudd_SetLooseUpTo]
Definition at line 1666 of file cuddAPI.c.
01668 { 01669 return(dd->minDead); 01670 01671 } /* end of Cudd_ReadMinDead */
unsigned int Cudd_ReadMinHit | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the hit rate that causes resizinig of the computed table.]
Description []
SideEffects [None]
SeeAlso [Cudd_SetMinHit]
Function********************************************************************
Synopsis [Reads the minus-infinity constant from the manager.]
Description []
SideEffects [None]
Definition at line 1090 of file cuddAPI.c.
01092 { 01093 return(dd->minusinfinity); 01094 01095 } /* end of Cudd_ReadMinusInfinity */
unsigned int Cudd_ReadNextReordering | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the threshold for the next dynamic reordering.]
Description [Returns the threshold for the next dynamic reordering. The threshold is in terms of number of nodes and is in effect only if reordering is enabled. The count does not include the dead nodes, unless the countDead parameter of the manager has been changed from its default setting.]
SideEffects [None]
SeeAlso [Cudd_SetNextReordering]
Definition at line 3739 of file cuddAPI.c.
03741 { 03742 return(dd->nextDyn); 03743 03744 } /* end of Cudd_ReadNextReordering */
long Cudd_ReadNodeCount | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reports the number of nodes in BDDs and ADDs.]
Description [Reports the number of live nodes in BDDs and ADDs. This number does not include the isolated projection functions and the unused constants. These nodes that are not counted are not part of the DDs manipulated by the application.]
SideEffects [None]
SeeAlso [Cudd_ReadPeakNodeCount Cudd_zddReadNodeCount]
Definition at line 3176 of file cuddAPI.c.
03178 { 03179 long count; 03180 int i; 03181 03182 #ifndef DD_NO_DEATH_ROW 03183 cuddClearDeathRow(dd); 03184 #endif 03185 03186 count = (long) (dd->keys - dd->dead); 03187 03188 /* Count isolated projection functions. Their number is subtracted 03189 ** from the node count because they are not part of the BDDs. 03190 */ 03191 for (i=0; i < dd->size; i++) { 03192 if (dd->vars[i]->ref == 1) count--; 03193 } 03194 /* Subtract from the count the unused constants. */ 03195 if (DD_ZERO(dd)->ref == 1) count--; 03196 if (DD_PLUS_INFINITY(dd)->ref == 1) count--; 03197 if (DD_MINUS_INFINITY(dd)->ref == 1) count--; 03198 03199 return(count); 03200 03201 } /* end of Cudd_ReadNodeCount */
double Cudd_ReadNodesDropped | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of nodes dropped.]
Description [Returns the number of nodes killed by dereferencing if the keeping of this statistic is enabled; -1 otherwise. This statistic is enabled only if the package is compiled with DD_STATS defined.]
SideEffects [None]
SeeAlso [Cudd_ReadNodesFreed]
double Cudd_ReadNodesFreed | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of nodes freed.]
Description [Returns the number of nodes returned to the free list if the keeping of this statistic is enabled; -1 otherwise. This statistic is enabled only if the package is compiled with DD_STATS defined.]
SideEffects [None]
SeeAlso [Cudd_ReadNodesDropped]
int Cudd_ReadNumberXovers | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the current number of crossovers used by the genetic algorithm for reordering.]
Description [Reads the current number of crossovers used by the genetic algorithm for variable reordering. A larger number of crossovers will cause the genetic algorithm to take more time, but will generally produce better results. The default value is 0, in which case the package uses three times the number of variables as number of crossovers, with a maximum of 60.]
SideEffects [None]
SeeAlso [Cudd_SetNumberXovers]
Definition at line 2866 of file cuddAPI.c.
02868 { 02869 return(dd->numberXovers); 02870 02871 } /* end of Cudd_ReadNumberXovers */
Function********************************************************************
Synopsis [Returns the one constant of the manager.]
Description [Returns the one constant of the manager. The one constant is common to ADDs and BDDs.]
SideEffects [None]
SeeAlso [Cudd_ReadZero Cudd_ReadLogicZero Cudd_ReadZddOne]
Definition at line 983 of file cuddAPI.c.
00985 { 00986 return(dd->one); 00987 00988 } /* end of Cudd_ReadOne */
int Cudd_ReadPeakLiveNodeCount | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reports the peak number of live nodes.]
Description [Reports the peak number of live nodes. This count is kept only if CUDD is compiled with DD_STATS defined. If DD_STATS is not defined, this function returns -1.]
SideEffects [None]
SeeAlso [Cudd_ReadNodeCount Cudd_PrintInfo Cudd_ReadPeakNodeCount]
Definition at line 3148 of file cuddAPI.c.
03150 { 03151 unsigned int live = dd->keys - dd->dead; 03152 03153 if (live > dd->peakLiveNodes) { 03154 dd->peakLiveNodes = live; 03155 } 03156 return((int)dd->peakLiveNodes); 03157 03158 } /* end of Cudd_ReadPeakLiveNodeCount */
long Cudd_ReadPeakNodeCount | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reports the peak number of nodes.]
Description [Reports the peak number of nodes. This number includes node on the free list. At the peak, the number of nodes on the free list is guaranteed to be less than DD_MEM_CHUNK.]
SideEffects [None]
SeeAlso [Cudd_ReadNodeCount Cudd_PrintInfo]
Definition at line 3119 of file cuddAPI.c.
03121 { 03122 long count = 0; 03123 DdNodePtr *scan = dd->memoryList; 03124 03125 while (scan != NULL) { 03126 count += DD_MEM_CHUNK; 03127 scan = (DdNodePtr *) *scan; 03128 } 03129 return(count); 03130 03131 } /* end of Cudd_ReadPeakNodeCount */
int Cudd_ReadPerm | ( | DdManager * | dd, | |
int | i | |||
) |
Function********************************************************************
Synopsis [Returns the current position of the i-th variable in the order.]
Description [Returns the current position of the i-th variable in the order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]
SideEffects [None]
SeeAlso [Cudd_ReadInvPerm Cudd_ReadPermZdd]
Definition at line 2297 of file cuddAPI.c.
02300 { 02301 if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); 02302 if (i < 0 || i >= dd->size) return(-1); 02303 return(dd->perm[i]); 02304 02305 } /* end of Cudd_ReadPerm */
int Cudd_ReadPermZdd | ( | DdManager * | dd, | |
int | i | |||
) |
Function********************************************************************
Synopsis [Returns the current position of the i-th ZDD variable in the order.]
Description [Returns the current position of the i-th ZDD variable in the order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]
SideEffects [None]
SeeAlso [Cudd_ReadInvPermZdd Cudd_ReadPerm]
Definition at line 2324 of file cuddAPI.c.
02327 { 02328 if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX); 02329 if (i < 0 || i >= dd->sizeZ) return(-1); 02330 return(dd->permZ[i]); 02331 02332 } /* end of Cudd_ReadPermZdd */
Function********************************************************************
Synopsis [Reads the plus-infinity constant from the manager.]
Description []
SideEffects [None]
Definition at line 1072 of file cuddAPI.c.
01074 { 01075 return(dd->plusinfinity); 01076 01077 } /* end of Cudd_ReadPlusInfinity */
int Cudd_ReadPopulationSize | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the current size of the population used by the genetic algorithm for reordering.]
Description [Reads the current size of the population used by the genetic algorithm for variable reordering. A larger population size will cause the genetic algorithm to take more time, but will generally produce better results. The default value is 0, in which case the package uses three times the number of variables as population size, with a maximum of 120.]
SideEffects [None]
SeeAlso [Cudd_SetPopulationSize]
Definition at line 2813 of file cuddAPI.c.
02815 { 02816 return(dd->populationSize); 02817 02818 } /* end of Cudd_ReadPopulationSize */
int Cudd_ReadRecomb | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the current value of the recombination parameter used in group sifting.]
Description [Returns the current value of the recombination parameter used in group sifting. A larger (positive) value makes the aggregation of variables due to the second difference criterion more likely. A smaller (negative) value makes aggregation less likely.]
SideEffects [None]
SeeAlso [Cudd_SetRecomb]
Definition at line 2653 of file cuddAPI.c.
02655 { 02656 return(dd->recomb); 02657 02658 } /* end of Cudd_ReadRecomb */
double Cudd_ReadRecursiveCalls | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of recursive calls.]
Description [Returns the number of recursive calls if the package is compiled with DD_COUNT defined.]
SideEffects [None]
SeeAlso []
int Cudd_ReadReorderingCycle | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the reordCycle parameter of the manager.]
Description [Reads the reordCycle parameter of the manager. This parameter determines how often the alternate threshold on maximum growth is used in reordering.]
SideEffects [None]
SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate Cudd_SetReorderingCycle]
Definition at line 2084 of file cuddAPI.c.
02086 { 02087 return(dd->reordCycle); 02088 02089 } /* end of Cudd_ReadReorderingCycle */
int Cudd_ReadReorderings | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of times reordering has occurred.]
Description [Returns the number of times reordering has occurred in the manager. The number includes both the calls to Cudd_ReduceHeap from the application program and those automatically performed by the package. However, calls that do not even initiate reordering are not counted. A call may not initiate reordering if there are fewer than minsize live nodes in the manager, or if CUDD_REORDER_NONE is specified as reordering method. The calls to Cudd_ShuffleHeap are not counted.]
SideEffects [None]
SeeAlso [Cudd_ReduceHeap Cudd_ReadReorderingTime]
Definition at line 1692 of file cuddAPI.c.
01694 { 01695 return(dd->reorderings); 01696 01697 } /* end of Cudd_ReadReorderings */
long Cudd_ReadReorderingTime | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the time spent in reordering.]
Description [Returns the number of milliseconds spent reordering variables since the manager was initialized. The time spent in collecting garbage before reordering is included.]
SideEffects [None]
SeeAlso [Cudd_ReadReorderings]
Definition at line 1714 of file cuddAPI.c.
01716 { 01717 return(dd->reordTime); 01718 01719 } /* end of Cudd_ReadReorderingTime */
int Cudd_ReadSiftMaxSwap | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the siftMaxSwap parameter of the manager.]
Description [Reads the siftMaxSwap parameter of the manager. This parameter gives the maximum number of swaps that will be attempted for each invocation of sifting. The real number of swaps may exceed the set limit because the package will always complete the sifting of the variable that causes the limit to be reached.]
SideEffects [None]
SeeAlso [Cudd_ReadSiftMaxVar Cudd_SetSiftMaxSwap]
Definition at line 1934 of file cuddAPI.c.
01936 { 01937 return(dd->siftMaxSwap); 01938 01939 } /* end of Cudd_ReadSiftMaxSwap */
int Cudd_ReadSiftMaxVar | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the siftMaxVar parameter of the manager.]
Description [Reads the siftMaxVar parameter of the manager. This parameter gives the maximum number of variables that will be sifted for each invocation of sifting.]
SideEffects [None]
SeeAlso [Cudd_ReadSiftMaxSwap Cudd_SetSiftMaxVar]
Definition at line 1887 of file cuddAPI.c.
01889 { 01890 return(dd->siftMaxVar); 01891 01892 } /* end of Cudd_ReadSiftMaxVar */
int Cudd_ReadSize | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of BDD variables in existance.]
Description []
SideEffects [None]
SeeAlso [Cudd_ReadZddSize]
Definition at line 1437 of file cuddAPI.c.
01439 { 01440 return(dd->size); 01441 01442 } /* end of Cudd_ReadSize */
unsigned int Cudd_ReadSlots | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the total number of slots of the unique table.]
Description [Returns the total number of slots of the unique table. This number ismainly for diagnostic purposes.]
SideEffects [None]
Definition at line 1476 of file cuddAPI.c.
01478 { 01479 return(dd->slots); 01480 01481 } /* end of Cudd_ReadSlots */
FILE* Cudd_ReadStderr | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the stderr of a manager.]
Description [Reads the stderr of a manager. This is the file pointer to which messages normally going to stderr are written. It is initialized to stderr. Cudd_SetStderr allows the application to redirect it.]
SideEffects [None]
SeeAlso [Cudd_SetStderr Cudd_ReadStdout]
Definition at line 3694 of file cuddAPI.c.
03696 { 03697 return(dd->err); 03698 03699 } /* end of Cudd_ReadStderr */
FILE* Cudd_ReadStdout | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the stdout of a manager.]
Description [Reads the stdout of a manager. This is the file pointer to which messages normally going to stdout are written. It is initialized to stdout. Cudd_SetStdout allows the application to redirect it.]
SideEffects [None]
SeeAlso [Cudd_SetStdout Cudd_ReadStderr]
Definition at line 3651 of file cuddAPI.c.
03653 { 03654 return(dd->out); 03655 03656 } /* end of Cudd_ReadStdout */
double Cudd_ReadSwapSteps | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the number of elementary reordering steps.]
Description []
SideEffects [none]
SeeAlso []
int Cudd_ReadSymmviolation | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the current value of the symmviolation parameter used in group sifting.]
Description [Returns the current value of the symmviolation parameter. This parameter is used in group sifting to decide how many violations to the symmetry conditions f10 = f01
or f11 = f00
are tolerable when checking for aggregation due to extended symmetry. The value should be between 0 and 100. A small value causes fewer variables to be aggregated. The default value is 0.]
SideEffects [None]
SeeAlso [Cudd_SetSymmviolation]
Definition at line 2706 of file cuddAPI.c.
02708 { 02709 return(dd->symmviolation); 02710 02711 } /* end of Cudd_ReadSymmviolation */
Function********************************************************************
Synopsis [Returns the variable group tree of the manager.]
Description []
SideEffects [None]
SeeAlso [Cudd_SetTree Cudd_FreeTree Cudd_ReadZddTree]
Definition at line 2128 of file cuddAPI.c.
02130 { 02131 return(dd->tree); 02132 02133 } /* end of Cudd_ReadTree */
double Cudd_ReadUniqueLinks | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of links followed in the unique table.]
Description [Returns the number of links followed during look-ups in the unique table if the keeping of this statistic is enabled; -1 otherwise. If an item is found in the first position of its collision list, the number of links followed is taken to be 0. If it is in second position, the number of links is 1, and so on. This statistic is enabled only if the package is compiled with DD_UNIQUE_PROFILE defined.]
SideEffects [None]
SeeAlso [Cudd_ReadUniqueLookUps]
double Cudd_ReadUniqueLookUps | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of look-ups in the unique table.]
Description [Returns the number of look-ups in the unique table if the keeping of this statistic is enabled; -1 otherwise. This statistic is enabled only if the package is compiled with DD_UNIQUE_PROFILE defined.]
SideEffects [None]
SeeAlso [Cudd_ReadUniqueLinks]
double Cudd_ReadUsedSlots | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reads the fraction of used slots in the unique table.]
Description [Reads the fraction of used slots in the unique table. The unused slots are those in which no valid data is stored. Garbage collection, variable reordering, and subtable resizing may cause used slots to become unused.]
SideEffects [None]
SeeAlso [Cudd_ReadSlots]
Definition at line 1499 of file cuddAPI.c.
01501 { 01502 unsigned long used = 0; 01503 int i, j; 01504 int size = dd->size; 01505 DdNodePtr *nodelist; 01506 DdSubtable *subtable; 01507 DdNode *node; 01508 DdNode *sentinel = &(dd->sentinel); 01509 01510 /* Scan each BDD/ADD subtable. */ 01511 for (i = 0; i < size; i++) { 01512 subtable = &(dd->subtables[i]); 01513 nodelist = subtable->nodelist; 01514 for (j = 0; (unsigned) j < subtable->slots; j++) { 01515 node = nodelist[j]; 01516 if (node != sentinel) { 01517 used++; 01518 } 01519 } 01520 } 01521 01522 /* Scan the ZDD subtables. */ 01523 size = dd->sizeZ; 01524 01525 for (i = 0; i < size; i++) { 01526 subtable = &(dd->subtableZ[i]); 01527 nodelist = subtable->nodelist; 01528 for (j = 0; (unsigned) j < subtable->slots; j++) { 01529 node = nodelist[j]; 01530 if (node != NULL) { 01531 used++; 01532 } 01533 } 01534 } 01535 01536 /* Constant table. */ 01537 subtable = &(dd->constants); 01538 nodelist = subtable->nodelist; 01539 for (j = 0; (unsigned) j < subtable->slots; j++) { 01540 node = nodelist[j]; 01541 if (node != NULL) { 01542 used++; 01543 } 01544 } 01545 01546 return((double)used / (double) dd->slots); 01547 01548 } /* end of Cudd_ReadUsedSlots */
Function********************************************************************
Synopsis [Returns the i-th element of the vars array.]
Description [Returns the i-th element of the vars array if it falls within the array bounds; NULL otherwise. If i is the index of an existing variable, this function produces the same result as Cudd_bddIthVar. However, if the i-th var does not exist yet, Cudd_bddIthVar will create it, whereas Cudd_ReadVars will not.]
SideEffects [None]
SeeAlso [Cudd_bddIthVar]
Function********************************************************************
Synopsis [Returns the ZDD for the constant 1 function.]
Description [Returns the ZDD for the constant 1 function. The representation of the constant 1 function as a ZDD depends on how many variables it (nominally) depends on. The index of the topmost variable in the support is given as argument i
.]
SideEffects [None]
SeeAlso [Cudd_ReadOne]
int Cudd_ReadZddSize | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns the number of ZDD variables in existance.]
Description []
SideEffects [None]
SeeAlso [Cudd_ReadSize]
Definition at line 1457 of file cuddAPI.c.
01459 { 01460 return(dd->sizeZ); 01461 01462 } /* end of Cudd_ReadZddSize */
Function********************************************************************
Synopsis [Returns the variable group tree of the manager.]
Description []
SideEffects [None]
SeeAlso [Cudd_SetZddTree Cudd_FreeZddTree Cudd_ReadTree]
Definition at line 2200 of file cuddAPI.c.
02202 { 02203 return(dd->treeZ); 02204 02205 } /* end of Cudd_ReadZddTree */
Function********************************************************************
Synopsis [Returns the zero constant of the manager.]
Description [Returns the zero constant of the manager. The zero constant is the arithmetic zero, rather than the logic zero. The latter is the complement of the one constant.]
SideEffects [None]
SeeAlso [Cudd_ReadOne Cudd_ReadLogicZero]
Definition at line 1032 of file cuddAPI.c.
01034 { 01035 return(DD_ZERO(dd)); 01036 01037 } /* end of Cudd_ReadZero */
Function********************************************************************
Synopsis [Decreases the reference count of node n.]
Description [Decreases the reference count of node n. If n dies, recursively decreases the reference counts of its children. It is used to dispose of a DD that is no longer needed.]
SideEffects [None]
SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDerefZdd]
Definition at line 150 of file cuddRef.c.
00153 { 00154 DdNode *N; 00155 int ord; 00156 DdNodePtr *stack = table->stack; 00157 int SP = 1; 00158 00159 unsigned int live = table->keys - table->dead; 00160 if (live > table->peakLiveNodes) { 00161 table->peakLiveNodes = live; 00162 } 00163 00164 N = Cudd_Regular(n); 00165 00166 do { 00167 #ifdef DD_DEBUG 00168 assert(N->ref != 0); 00169 #endif 00170 00171 if (N->ref == 1) { 00172 N->ref = 0; 00173 table->dead++; 00174 #ifdef DD_STATS 00175 table->nodesDropped++; 00176 #endif 00177 if (cuddIsConstant(N)) { 00178 table->constants.dead++; 00179 N = stack[--SP]; 00180 } else { 00181 ord = table->perm[N->index]; 00182 stack[SP++] = Cudd_Regular(cuddE(N)); 00183 table->subtables[ord].dead++; 00184 N = cuddT(N); 00185 } 00186 } else { 00187 cuddSatDec(N->ref); 00188 N = stack[--SP]; 00189 } 00190 } while (SP != 0); 00191 00192 } /* end of Cudd_RecursiveDeref */
Function********************************************************************
Synopsis [Decreases the reference count of ZDD node n.]
Description [Decreases the reference count of ZDD node n. If n dies, recursively decreases the reference counts of its children. It is used to dispose of a ZDD that is no longer needed.]
SideEffects [None]
SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDeref]
Definition at line 381 of file cuddRef.c.
00384 { 00385 DdNode *N; 00386 int ord; 00387 DdNodePtr *stack = table->stack; 00388 int SP = 1; 00389 00390 N = n; 00391 00392 do { 00393 #ifdef DD_DEBUG 00394 assert(N->ref != 0); 00395 #endif 00396 00397 cuddSatDec(N->ref); 00398 00399 if (N->ref == 0) { 00400 table->deadZ++; 00401 #ifdef DD_STATS 00402 table->nodesDropped++; 00403 #endif 00404 #ifdef DD_DEBUG 00405 assert(!cuddIsConstant(N)); 00406 #endif 00407 ord = table->permZ[N->index]; 00408 stack[SP++] = cuddE(N); 00409 table->subtableZ[ord].dead++; 00410 N = cuddT(N); 00411 } else { 00412 N = stack[--SP]; 00413 } 00414 } while (SP != 0); 00415 00416 } /* end of Cudd_RecursiveDerefZdd */
int Cudd_ReduceHeap | ( | DdManager * | table, | |
Cudd_ReorderingType | heuristic, | |||
int | minsize | |||
) |
AutomaticEnd Function********************************************************************
Synopsis [Main dynamic reordering routine.]
Description [Main dynamic reordering routine. Calls one of the possible reordering procedures:
For sifting, symmetric sifting, group sifting, and window permutation it is possible to request reordering to convergence.
The core of all methods is the reordering procedure cuddSwapInPlace() which swaps two adjacent variables and is based on Rudell's paper. Returns 1 in case of success; 0 otherwise. In the case of symmetric sifting (with and without convergence) returns 1 plus the number of symmetric variables, in case of success.]
SideEffects [Changes the variable order for all diagrams and clears the cache.]
Definition at line 172 of file cuddReorder.c.
00176 { 00177 DdHook *hook; 00178 int result; 00179 unsigned int nextDyn; 00180 #ifdef DD_STATS 00181 unsigned int initialSize; 00182 unsigned int finalSize; 00183 #endif 00184 long localTime; 00185 00186 /* Don't reorder if there are too many dead nodes. */ 00187 if (table->keys - table->dead < (unsigned) minsize) 00188 return(1); 00189 00190 if (heuristic == CUDD_REORDER_SAME) { 00191 heuristic = table->autoMethod; 00192 } 00193 if (heuristic == CUDD_REORDER_NONE) { 00194 return(1); 00195 } 00196 00197 /* This call to Cudd_ReduceHeap does initiate reordering. Therefore 00198 ** we count it. 00199 */ 00200 table->reorderings++; 00201 00202 localTime = util_cpu_time(); 00203 00204 /* Run the hook functions. */ 00205 hook = table->preReorderingHook; 00206 while (hook != NULL) { 00207 int res = (hook->f)(table, "BDD", (void *)heuristic); 00208 if (res == 0) return(0); 00209 hook = hook->next; 00210 } 00211 00212 if (!ddReorderPreprocess(table)) return(0); 00213 ddTotalNumberSwapping = 0; 00214 00215 if (table->keys > table->peakLiveNodes) { 00216 table->peakLiveNodes = table->keys; 00217 } 00218 #ifdef DD_STATS 00219 initialSize = table->keys - table->isolated; 00220 ddTotalNISwaps = 0; 00221 00222 switch(heuristic) { 00223 case CUDD_REORDER_RANDOM: 00224 case CUDD_REORDER_RANDOM_PIVOT: 00225 (void) fprintf(table->out,"#:I_RANDOM "); 00226 break; 00227 case CUDD_REORDER_SIFT: 00228 case CUDD_REORDER_SIFT_CONVERGE: 00229 case CUDD_REORDER_SYMM_SIFT: 00230 case CUDD_REORDER_SYMM_SIFT_CONV: 00231 case CUDD_REORDER_GROUP_SIFT: 00232 case CUDD_REORDER_GROUP_SIFT_CONV: 00233 (void) fprintf(table->out,"#:I_SIFTING "); 00234 break; 00235 case CUDD_REORDER_WINDOW2: 00236 case CUDD_REORDER_WINDOW3: 00237 case CUDD_REORDER_WINDOW4: 00238 case CUDD_REORDER_WINDOW2_CONV: 00239 case CUDD_REORDER_WINDOW3_CONV: 00240 case CUDD_REORDER_WINDOW4_CONV: 00241 (void) fprintf(table->out,"#:I_WINDOW "); 00242 break; 00243 case CUDD_REORDER_ANNEALING: 00244 (void) fprintf(table->out,"#:I_ANNEAL "); 00245 break; 00246 case CUDD_REORDER_GENETIC: 00247 (void) fprintf(table->out,"#:I_GENETIC "); 00248 break; 00249 case CUDD_REORDER_LINEAR: 00250 case CUDD_REORDER_LINEAR_CONVERGE: 00251 (void) fprintf(table->out,"#:I_LINSIFT "); 00252 break; 00253 case CUDD_REORDER_EXACT: 00254 (void) fprintf(table->out,"#:I_EXACT "); 00255 break; 00256 default: 00257 return(0); 00258 } 00259 (void) fprintf(table->out,"%8d: initial size",initialSize); 00260 #endif 00261 00262 /* See if we should use alternate threshold for maximum growth. */ 00263 if (table->reordCycle && table->reorderings % table->reordCycle == 0) { 00264 double saveGrowth = table->maxGrowth; 00265 table->maxGrowth = table->maxGrowthAlt; 00266 result = cuddTreeSifting(table,heuristic); 00267 table->maxGrowth = saveGrowth; 00268 } else { 00269 result = cuddTreeSifting(table,heuristic); 00270 } 00271 00272 #ifdef DD_STATS 00273 (void) fprintf(table->out,"\n"); 00274 finalSize = table->keys - table->isolated; 00275 (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); 00276 (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n", 00277 ((double)(util_cpu_time() - localTime)/1000.0)); 00278 (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n", 00279 ddTotalNumberSwapping); 00280 (void) fprintf(table->out,"#:M_REORDER %8d: NI swaps\n",ddTotalNISwaps); 00281 #endif 00282 00283 if (result == 0) 00284 return(0); 00285 00286 if (!ddReorderPostprocess(table)) 00287 return(0); 00288 00289 if (table->realign) { 00290 if (!cuddZddAlignToBdd(table)) 00291 return(0); 00292 } 00293 00294 nextDyn = (table->keys - table->constants.keys + 1) * 00295 DD_DYN_RATIO + table->constants.keys; 00296 if (table->reorderings < 20 || nextDyn > table->nextDyn) 00297 table->nextDyn = nextDyn; 00298 else 00299 table->nextDyn += 20; 00300 table->reordered = 1; 00301 00302 /* Run hook functions. */ 00303 hook = table->postReorderingHook; 00304 while (hook != NULL) { 00305 int res = (hook->f)(table, "BDD", (void *)localTime); 00306 if (res == 0) return(0); 00307 hook = hook->next; 00308 } 00309 /* Update cumulative reordering time. */ 00310 table->reordTime += util_cpu_time() - localTime; 00311 00312 return(result); 00313 00314 } /* end of Cudd_ReduceHeap */
void Cudd_Ref | ( | DdNode * | n | ) |
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Increases the reference count of a node, if it is not saturated.]
Description []
SideEffects [None]
SeeAlso [Cudd_RecursiveDeref Cudd_Deref]
Definition at line 125 of file cuddRef.c.
00127 { 00128 00129 n = Cudd_Regular(n); 00130 00131 cuddSatInc(n->ref); 00132 00133 } /* end of Cudd_Ref */
DdNode* Cudd_RemapOverApprox | ( | DdManager * | dd, | |
DdNode * | f, | |||
int | numVars, | |||
int | threshold, | |||
double | quality | |||
) |
Function********************************************************************
Synopsis [Extracts a dense superset from a BDD with the remapping underapproximation method.]
Description [Extracts a dense superset from a BDD. The procedure is identical to the underapproximation procedure except for the fact that it works on the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. Returns a pointer to the BDD of the superset if successful. NULL if intermediate result causes the procedure to run out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]
SideEffects [None]
SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize]
Definition at line 362 of file cuddApprox.c.
00368 { 00369 DdNode *subset, *g; 00370 00371 g = Cudd_Not(f); 00372 do { 00373 dd->reordered = 0; 00374 subset = cuddRemapUnderApprox(dd, g, numVars, threshold, quality); 00375 } while (dd->reordered == 1); 00376 00377 return(Cudd_NotCond(subset, (subset != NULL))); 00378 00379 } /* end of Cudd_RemapOverApprox */
DdNode* Cudd_RemapUnderApprox | ( | DdManager * | dd, | |
DdNode * | f, | |||
int | numVars, | |||
int | threshold, | |||
double | quality | |||
) |
Function********************************************************************
Synopsis [Extracts a dense subset from a BDD with the remapping underapproximation method.]
Description [Extracts a dense subset from a BDD. This procedure uses a remapping technique and density as the cost function. Returns a pointer to the BDD of the subset if successful. NULL if the procedure runs out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will cause overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]
SideEffects [None]
SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox Cudd_ReadSize]
Definition at line 316 of file cuddApprox.c.
00322 { 00323 DdNode *subset; 00324 00325 do { 00326 dd->reordered = 0; 00327 subset = cuddRemapUnderApprox(dd, f, numVars, threshold, quality); 00328 } while (dd->reordered == 1); 00329 00330 return(subset); 00331 00332 } /* end of Cudd_RemapUnderApprox */
int Cudd_RemoveHook | ( | DdManager * | dd, | |
DD_HFP | f, | |||
Cudd_HookType | where | |||
) |
Function********************************************************************
Synopsis [Removes a function from a hook.]
Description [Removes a function from a hook. A hook is a list of application-provided functions called on certain occasions by the package. Returns 1 if successful; 0 the function was not in the list.]
SideEffects [None]
SeeAlso [Cudd_AddHook]
Definition at line 3303 of file cuddAPI.c.
03307 { 03308 DdHook **hook, *nextHook; 03309 03310 switch (where) { 03311 case CUDD_PRE_GC_HOOK: 03312 hook = &(dd->preGCHook); 03313 break; 03314 case CUDD_POST_GC_HOOK: 03315 hook = &(dd->postGCHook); 03316 break; 03317 case CUDD_PRE_REORDERING_HOOK: 03318 hook = &(dd->preReorderingHook); 03319 break; 03320 case CUDD_POST_REORDERING_HOOK: 03321 hook = &(dd->postReorderingHook); 03322 break; 03323 default: 03324 return(0); 03325 } 03326 nextHook = *hook; 03327 while (nextHook != NULL) { 03328 if (nextHook->f == f) { 03329 *hook = nextHook->next; 03330 FREE(nextHook); 03331 return(1); 03332 } 03333 hook = &(nextHook->next); 03334 nextHook = nextHook->next; 03335 } 03336 03337 return(0); 03338 03339 } /* end of Cudd_RemoveHook */
int Cudd_ReorderingReporting | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Returns 1 if reporting of reordering stats is enabled.]
Description [Returns 1 if reporting of reordering stats is enabled; 0 otherwise.]
SideEffects [none]
SeeAlso [Cudd_EnableReorderingReporting Cudd_DisableReorderingReporting]
Definition at line 3588 of file cuddAPI.c.
03590 { 03591 return(Cudd_IsInHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)); 03592 03593 } /* end of Cudd_ReorderingReporting */
int Cudd_ReorderingStatus | ( | DdManager * | unique, | |
Cudd_ReorderingType * | method | |||
) |
Function********************************************************************
Synopsis [Reports the status of automatic dynamic reordering of BDDs and ADDs.]
Description [Reports the status of automatic dynamic reordering of BDDs and ADDs. Parameter method is set to the reordering method currently selected. Returns 1 if automatic reordering is enabled; 0 otherwise.]
SideEffects [Parameter method is set to the reordering method currently selected.]
SeeAlso [Cudd_AutodynEnable Cudd_AutodynDisable Cudd_ReorderingStatusZdd]
Definition at line 731 of file cuddAPI.c.
00734 { 00735 *method = unique->autoMethod; 00736 return(unique->autoDyn); 00737 00738 } /* end of Cudd_ReorderingStatus */
int Cudd_ReorderingStatusZdd | ( | DdManager * | unique, | |
Cudd_ReorderingType * | method | |||
) |
Function********************************************************************
Synopsis [Reports the status of automatic dynamic reordering of ZDDs.]
Description [Reports the status of automatic dynamic reordering of ZDDs. Parameter method is set to the ZDD reordering method currently selected. Returns 1 if automatic reordering is enabled; 0 otherwise.]
SideEffects [Parameter method is set to the ZDD reordering method currently selected.]
SeeAlso [Cudd_AutodynEnableZdd Cudd_AutodynDisableZdd Cudd_ReorderingStatus]
Definition at line 808 of file cuddAPI.c.
00811 { 00812 *method = unique->autoMethodZ; 00813 return(unique->autoDynZ); 00814 00815 } /* end of Cudd_ReorderingStatusZdd */
void Cudd_SetArcviolation | ( | DdManager * | dd, | |
int | arcviolation | |||
) |
Function********************************************************************
Synopsis [Sets the value of the arcviolation parameter used in group sifting.]
Description [Sets the value of the arcviolation parameter. This parameter is used in group sifting to decide how many arcs into y
not coming from x
are tolerable when checking for aggregation due to extended symmetry. The value should be between 0 and 100. A small value causes fewer variables to be aggregated. The default value is 0.]
SideEffects [None]
SeeAlso [Cudd_ReadArcviolation]
Definition at line 2786 of file cuddAPI.c.
02789 { 02790 dd->arcviolation = arcviolation; 02791 02792 } /* end of Cudd_SetArcviolation */
Function********************************************************************
Synopsis [Sets the background constant of the manager.]
Description [Sets the background constant of the manager. It assumes that the DdNode pointer bck is already referenced.]
SideEffects [None]
Definition at line 1127 of file cuddAPI.c.
01130 { 01131 dd->background = bck; 01132 01133 } /* end of Cudd_SetBackground */
void Cudd_SetEpsilon | ( | DdManager * | dd, | |
CUDD_VALUE_TYPE | ep | |||
) |
Function********************************************************************
Synopsis [Sets the epsilon parameter of the manager to ep.]
Description [Sets the epsilon parameter of the manager to ep. The epsilon parameter control the comparison between floating point numbers.]
SideEffects [None]
SeeAlso [Cudd_ReadEpsilon]
Definition at line 2447 of file cuddAPI.c.
02450 { 02451 dd->epsilon = ep; 02452 02453 } /* end of Cudd_SetEpsilon */
void Cudd_SetGroupcheck | ( | DdManager * | dd, | |
Cudd_AggregationType | gc | |||
) |
Function********************************************************************
Synopsis [Sets the parameter groupcheck of the manager to gc.]
Description [Sets the parameter groupcheck of the manager to gc. The groupcheck parameter determines the aggregation criterion in group sifting.]
SideEffects [None]
SeeAlso [Cudd_ReadGroupCheck]
Definition at line 2492 of file cuddAPI.c.
02495 { 02496 dd->groupcheck = gc; 02497 02498 } /* end of Cudd_SetGroupcheck */
void Cudd_SetLooseUpTo | ( | DdManager * | dd, | |
unsigned int | lut | |||
) |
Function********************************************************************
Synopsis [Sets the looseUpTo parameter of the manager.]
Description [Sets the looseUpTo parameter of the manager. This parameter of the manager controls the threshold beyond which no fast growth of the unique table is allowed. The threshold is given as a number of slots. If the value passed to this function is 0, the function determines a suitable value based on the available memory.]
SideEffects [None]
SeeAlso [Cudd_ReadLooseUpTo Cudd_SetMinHit]
Definition at line 1341 of file cuddAPI.c.
01344 { 01345 if (lut == 0) { 01346 unsigned long datalimit = getSoftDataLimit(); 01347 lut = (unsigned int) (datalimit / (sizeof(DdNode) * 01348 DD_MAX_LOOSE_FRACTION)); 01349 } 01350 dd->looseUpTo = lut; 01351 01352 } /* end of Cudd_SetLooseUpTo */
void Cudd_SetMaxCacheHard | ( | DdManager * | dd, | |
unsigned int | mc | |||
) |
Function********************************************************************
Synopsis [Sets the maxCacheHard parameter of the manager.]
Description [Sets the maxCacheHard parameter of the manager. The cache cannot grow larger than maxCacheHard entries. This parameter allows an application to control the trade-off of memory versus speed. If the value passed to this function is 0, the function determines a suitable maximum cache size based on the available memory.]
SideEffects [None]
SeeAlso [Cudd_ReadMaxCacheHard Cudd_SetMaxCache]
Definition at line 1411 of file cuddAPI.c.
01414 { 01415 if (mc == 0) { 01416 unsigned long datalimit = getSoftDataLimit(); 01417 mc = (unsigned int) (datalimit / (sizeof(DdCache) * 01418 DD_MAX_CACHE_FRACTION)); 01419 } 01420 dd->maxCacheHard = mc; 01421 01422 } /* end of Cudd_SetMaxCacheHard */
void Cudd_SetMaxGrowth | ( | DdManager * | dd, | |
double | mg | |||
) |
Function********************************************************************
Synopsis [Sets the maxGrowth parameter of the manager.]
Description [Sets the maxGrowth parameter of the manager. This parameter determines how much the number of nodes can grow during sifting of a variable. Overall, sifting never increases the size of the decision diagrams. This parameter only refers to intermediate results. A lower value will speed up sifting, possibly at the expense of quality.]
SideEffects [None]
SeeAlso [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate]
Definition at line 2009 of file cuddAPI.c.
02012 { 02013 dd->maxGrowth = mg; 02014 02015 } /* end of Cudd_SetMaxGrowth */
void Cudd_SetMaxGrowthAlternate | ( | DdManager * | dd, | |
double | mg | |||
) |
Function********************************************************************
Synopsis [Sets the maxGrowthAlt parameter of the manager.]
Description [Sets the maxGrowthAlt parameter of the manager. This parameter is analogous to the maxGrowth paramter, and is used every given number of reorderings instead of maxGrowth. The number of reorderings is set with Cudd_SetReorderingCycle. If the number of reorderings is 0 (default) maxGrowthAlt is never used.]
SideEffects [None]
SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowth Cudd_SetReorderingCycle Cudd_ReadReorderingCycle]
Definition at line 2060 of file cuddAPI.c.
02063 { 02064 dd->maxGrowthAlt = mg; 02065 02066 } /* end of Cudd_SetMaxGrowthAlternate */
void Cudd_SetMaxLive | ( | DdManager * | dd, | |
unsigned int | maxLive | |||
) |
Function********************************************************************
Synopsis [Sets the maximum allowed number of live nodes.]
Description [Sets the maximum allowed number of live nodes. When this number is exceeded, the package returns NULL.]
SideEffects [none]
SeeAlso [Cudd_ReadMaxLive]
Definition at line 3830 of file cuddAPI.c.
03833 { 03834 dd->maxLive = maxLive; 03835 03836 } /* end of Cudd_SetMaxLive */
void Cudd_SetMaxMemory | ( | DdManager * | dd, | |
unsigned long | maxMemory | |||
) |
Function********************************************************************
Synopsis [Sets the maximum allowed memory.]
Description [Sets the maximum allowed memory. When this number is exceeded, the package returns NULL.]
SideEffects [none]
SeeAlso [Cudd_ReadMaxMemory]
Definition at line 3873 of file cuddAPI.c.
03876 { 03877 dd->maxmemhard = maxMemory; 03878 03879 } /* end of Cudd_SetMaxMemory */
void Cudd_SetMinHit | ( | DdManager * | dd, | |
unsigned int | hr | |||
) |
Function********************************************************************
Synopsis [Sets the hit rate that causes resizinig of the computed table.]
Description [Sets the minHit parameter of the manager. This parameter controls the resizing of the computed table. If the hit rate is larger than the specified value, and the cache is not already too large, then its size is doubled.]
SideEffects [None]
SeeAlso [Cudd_ReadMinHit]
Definition at line 1294 of file cuddAPI.c.
01297 { 01298 /* Internally, the package manipulates the ratio of hits to 01299 ** misses instead of the ratio of hits to accesses. */ 01300 dd->minHit = (double) hr / (100.0 - (double) hr); 01301 01302 } /* end of Cudd_SetMinHit */
void Cudd_SetNextReordering | ( | DdManager * | dd, | |
unsigned int | next | |||
) |
Function********************************************************************
Synopsis [Sets the threshold for the next dynamic reordering.]
Description [Sets the threshold for the next dynamic reordering. The threshold is in terms of number of nodes and is in effect only if reordering is enabled. The count does not include the dead nodes, unless the countDead parameter of the manager has been changed from its default setting.]
SideEffects [None]
SeeAlso [Cudd_ReadNextReordering]
Definition at line 3763 of file cuddAPI.c.
03766 { 03767 dd->nextDyn = next; 03768 03769 } /* end of Cudd_SetNextReordering */
void Cudd_SetNumberXovers | ( | DdManager * | dd, | |
int | numberXovers | |||
) |
Function********************************************************************
Synopsis [Sets the number of crossovers used by the genetic algorithm for reordering.]
Description [Sets the number of crossovers used by the genetic algorithm for variable reordering. A larger number of crossovers will cause the genetic algorithm to take more time, but will generally produce better results. The default value is 0, in which case the package uses three times the number of variables as number of crossovers, with a maximum of 60.]
SideEffects [None]
SeeAlso [Cudd_ReadNumberXovers]
Definition at line 2892 of file cuddAPI.c.
02895 { 02896 dd->numberXovers = numberXovers; 02897 02898 } /* end of Cudd_SetNumberXovers */
void Cudd_SetPopulationSize | ( | DdManager * | dd, | |
int | populationSize | |||
) |
Function********************************************************************
Synopsis [Sets the size of the population used by the genetic algorithm for reordering.]
Description [Sets the size of the population used by the genetic algorithm for variable reordering. A larger population size will cause the genetic algorithm to take more time, but will generally produce better results. The default value is 0, in which case the package uses three times the number of variables as population size, with a maximum of 120.]
SideEffects [Changes the manager.]
SeeAlso [Cudd_ReadPopulationSize]
Definition at line 2839 of file cuddAPI.c.
02842 { 02843 dd->populationSize = populationSize; 02844 02845 } /* end of Cudd_SetPopulationSize */
void Cudd_SetRecomb | ( | DdManager * | dd, | |
int | recomb | |||
) |
Function********************************************************************
Synopsis [Sets the value of the recombination parameter used in group sifting.]
Description [Sets the value of the recombination parameter used in group sifting. A larger (positive) value makes the aggregation of variables due to the second difference criterion more likely. A smaller (negative) value makes aggregation less likely. The default value is 0.]
SideEffects [Changes the manager.]
SeeAlso [Cudd_ReadRecomb]
Definition at line 2678 of file cuddAPI.c.
02681 { 02682 dd->recomb = recomb; 02683 02684 } /* end of Cudd_SetRecomb */
void Cudd_SetReorderingCycle | ( | DdManager * | dd, | |
int | cycle | |||
) |
Function********************************************************************
Synopsis [Sets the reordCycle parameter of the manager.]
Description [Sets the reordCycle parameter of the manager. This parameter determines how often the alternate threshold on maximum growth is used in reordering.]
SideEffects [None]
SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate Cudd_ReadReorderingCycle]
Definition at line 2107 of file cuddAPI.c.
02110 { 02111 dd->reordCycle = cycle; 02112 02113 } /* end of Cudd_SetReorderingCycle */
void Cudd_SetSiftMaxSwap | ( | DdManager * | dd, | |
int | sms | |||
) |
Function********************************************************************
Synopsis [Sets the siftMaxSwap parameter of the manager.]
Description [Sets the siftMaxSwap parameter of the manager. This parameter gives the maximum number of swaps that will be attempted for each invocation of sifting. The real number of swaps may exceed the set limit because the package will always complete the sifting of the variable that causes the limit to be reached.]
SideEffects [None]
SeeAlso [Cudd_SetSiftMaxVar Cudd_ReadSiftMaxSwap]
Definition at line 1958 of file cuddAPI.c.
01961 { 01962 dd->siftMaxSwap = sms; 01963 01964 } /* end of Cudd_SetSiftMaxSwap */
void Cudd_SetSiftMaxVar | ( | DdManager * | dd, | |
int | smv | |||
) |
Function********************************************************************
Synopsis [Sets the siftMaxVar parameter of the manager.]
Description [Sets the siftMaxVar parameter of the manager. This parameter gives the maximum number of variables that will be sifted for each invocation of sifting.]
SideEffects [None]
SeeAlso [Cudd_SetSiftMaxSwap Cudd_ReadSiftMaxVar]
Definition at line 1909 of file cuddAPI.c.
01912 { 01913 dd->siftMaxVar = smv; 01914 01915 } /* end of Cudd_SetSiftMaxVar */
void Cudd_SetStderr | ( | DdManager * | dd, | |
FILE * | fp | |||
) |
Function********************************************************************
Synopsis [Sets the stderr of a manager.]
Description []
SideEffects [None]
SeeAlso [Cudd_ReadStderr Cudd_SetStdout]
Definition at line 3714 of file cuddAPI.c.
03717 { 03718 dd->err = fp; 03719 03720 } /* end of Cudd_SetStderr */
void Cudd_SetStdout | ( | DdManager * | dd, | |
FILE * | fp | |||
) |
Function********************************************************************
Synopsis [Sets the stdout of a manager.]
Description []
SideEffects [None]
SeeAlso [Cudd_ReadStdout Cudd_SetStderr]
Definition at line 3671 of file cuddAPI.c.
03674 { 03675 dd->out = fp; 03676 03677 } /* end of Cudd_SetStdout */
void Cudd_SetSymmviolation | ( | DdManager * | dd, | |
int | symmviolation | |||
) |
Function********************************************************************
Synopsis [Sets the value of the symmviolation parameter used in group sifting.]
Description [Sets the value of the symmviolation parameter. This parameter is used in group sifting to decide how many violations to the symmetry conditions f10 = f01
or f11 = f00
are tolerable when checking for aggregation due to extended symmetry. The value should be between 0 and 100. A small value causes fewer variables to be aggregated. The default value is 0.]
SideEffects [Changes the manager.]
SeeAlso [Cudd_ReadSymmviolation]
Definition at line 2733 of file cuddAPI.c.
02736 { 02737 dd->symmviolation = symmviolation; 02738 02739 } /* end of Cudd_SetSymmviolation */
Function********************************************************************
Synopsis [Sets the variable group tree of the manager.]
Description []
SideEffects [None]
SeeAlso [Cudd_FreeTree Cudd_ReadTree Cudd_SetZddTree]
Definition at line 2148 of file cuddAPI.c.
02151 { 02152 if (dd->tree != NULL) { 02153 Mtr_FreeTree(dd->tree); 02154 } 02155 dd->tree = tree; 02156 if (tree == NULL) return; 02157 02158 fixVarTree(tree, dd->perm, dd->size); 02159 return; 02160 02161 } /* end of Cudd_SetTree */
Function********************************************************************
Synopsis [Registers a variable mapping with the manager.]
Description [Registers with the manager a variable mapping described by two sets of variables. This variable mapping is then used by functions like Cudd_bddVarMap. This function is convenient for those applications that perform the same mapping several times. However, if several different permutations are used, it may be more efficient not to rely on the registered mapping, because changing mapping causes the cache to be cleared. (The initial setting, however, does not clear the cache.) The two sets of variables (x and y) must have the same size (x and y). The size is given by n. The two sets of variables are normally disjoint, but this restriction is not imposeded by the function. When new variables are created, the map is automatically extended (each new variable maps to itself). The typical use, however, is to wait until all variables are created, and then create the map. Returns 1 if the mapping is successfully registered with the manager; 0 otherwise.]
SideEffects [Modifies the manager. May clear the cache.]
SeeAlso [Cudd_bddVarMap Cudd_bddPermute Cudd_bddSwapVariables]
Definition at line 412 of file cuddCompose.c.
00417 { 00418 int i; 00419 00420 if (manager->map != NULL) { 00421 cuddCacheFlush(manager); 00422 } else { 00423 manager->map = ALLOC(int,manager->maxSize); 00424 if (manager->map == NULL) { 00425 manager->errorCode = CUDD_MEMORY_OUT; 00426 return(0); 00427 } 00428 manager->memused += sizeof(int) * manager->maxSize; 00429 } 00430 /* Initialize the map to the identity. */ 00431 for (i = 0; i < manager->size; i++) { 00432 manager->map[i] = i; 00433 } 00434 /* Create the map. */ 00435 for (i = 0; i < n; i++) { 00436 manager->map[x[i]->index] = y[i]->index; 00437 manager->map[y[i]->index] = x[i]->index; 00438 } 00439 return(1); 00440 00441 } /* end of Cudd_SetVarMap */
Function********************************************************************
Synopsis [Sets the ZDD variable group tree of the manager.]
Description []
SideEffects [None]
SeeAlso [Cudd_FreeZddTree Cudd_ReadZddTree Cudd_SetTree]
Definition at line 2220 of file cuddAPI.c.
02223 { 02224 if (dd->treeZ != NULL) { 02225 Mtr_FreeTree(dd->treeZ); 02226 } 02227 dd->treeZ = tree; 02228 if (tree == NULL) return; 02229 02230 fixVarTree(tree, dd->permZ, dd->sizeZ); 02231 return; 02232 02233 } /* end of Cudd_SetZddTree */
int Cudd_SharingSize | ( | DdNode ** | nodeArray, | |
int | n | |||
) |
Function********************************************************************
Synopsis [Counts the number of nodes in an array of DDs.]
Description [Counts the number of nodes in an array of DDs. Shared nodes are counted only once. Returns the total number of nodes.]
SideEffects [None]
SeeAlso [Cudd_DagSize]
Definition at line 540 of file cuddUtil.c.
00543 { 00544 int i,j; 00545 00546 i = 0; 00547 for (j = 0; j < n; j++) { 00548 i += ddDagInt(Cudd_Regular(nodeArray[j])); 00549 } 00550 for (j = 0; j < n; j++) { 00551 ddClearFlag(Cudd_Regular(nodeArray[j])); 00552 } 00553 return(i); 00554 00555 } /* end of Cudd_SharingSize */
Function********************************************************************
Synopsis [Find the length of the shortest path(s) in a DD.]
Description [Find the length of the shortest path(s) in a DD. f is the DD we want to get the shortest path for; weight\[i\] is the weight of the THEN edge coming from the node whose index is i. All ELSE edges have 0 weight. Returns the length of the shortest path(s) if such a path is found; a large number if the function is identically 0, and CUDD_OUT_OF_MEM in case of failure.]
SideEffects [None]
SeeAlso [Cudd_ShortestPath]
Definition at line 353 of file cuddSat.c.
00357 { 00358 register DdNode *F; 00359 st_table *visited; 00360 cuddPathPair *my_pair; 00361 int complement, cost; 00362 00363 one = DD_ONE(manager); 00364 zero = DD_ZERO(manager); 00365 00366 if (f == Cudd_Not(one) || f == zero) { 00367 return(DD_BIGGY); 00368 } 00369 00370 /* From this point on, a path exists. */ 00371 /* Initialize visited table and support. */ 00372 visited = st_init_table(st_ptrcmp, st_ptrhash); 00373 00374 /* Now get the length of the shortest path(s) from f to 1. */ 00375 (void) getShortest(f, weight, NULL, visited); 00376 00377 complement = Cudd_IsComplement(f); 00378 00379 F = Cudd_Regular(f); 00380 00381 if (!st_lookup(visited, F, &my_pair)) return(CUDD_OUT_OF_MEM); 00382 00383 if (complement) { 00384 cost = my_pair->neg; 00385 } else { 00386 cost = my_pair->pos; 00387 } 00388 00389 st_foreach(visited, freePathPair, NULL); 00390 st_free_table(visited); 00391 00392 return(cost); 00393 00394 } /* end of Cudd_ShortestLength */
DdNode* Cudd_ShortestPath | ( | DdManager * | manager, | |
DdNode * | f, | |||
int * | weight, | |||
int * | support, | |||
int * | length | |||
) |
Function********************************************************************
Synopsis [Finds a shortest path in a DD.]
Description [Finds a shortest path in a DD. f is the DD we want to get the shortest path for; weight\[i\] is the weight of the THEN arc coming from the node whose index is i. If weight is NULL, then unit weights are assumed for all THEN arcs. All ELSE arcs have 0 weight. If non-NULL, both weight and support should point to arrays with at least as many entries as there are variables in the manager. Returns the shortest path as the BDD of a cube.]
SideEffects [support contains on return the true support of f. If support is NULL on entry, then Cudd_ShortestPath does not compute the true support info. length contains the length of the path.]
SeeAlso [Cudd_ShortestLength Cudd_LargestCube]
Definition at line 197 of file cuddSat.c.
00203 { 00204 DdNode *F; 00205 st_table *visited; 00206 DdNode *sol; 00207 cuddPathPair *rootPair; 00208 int complement, cost; 00209 int i; 00210 00211 one = DD_ONE(manager); 00212 zero = DD_ZERO(manager); 00213 00214 /* Initialize support. Support does not depend on variable order. 00215 ** Hence, it does not need to be reinitialized if reordering occurs. 00216 */ 00217 if (support) { 00218 for (i = 0; i < manager->size; i++) { 00219 support[i] = 0; 00220 } 00221 } 00222 00223 if (f == Cudd_Not(one) || f == zero) { 00224 *length = DD_BIGGY; 00225 return(Cudd_Not(one)); 00226 } 00227 /* From this point on, a path exists. */ 00228 00229 do { 00230 manager->reordered = 0; 00231 00232 /* Initialize visited table. */ 00233 visited = st_init_table(st_ptrcmp, st_ptrhash); 00234 00235 /* Now get the length of the shortest path(s) from f to 1. */ 00236 (void) getShortest(f, weight, support, visited); 00237 00238 complement = Cudd_IsComplement(f); 00239 00240 F = Cudd_Regular(f); 00241 00242 if (!st_lookup(visited, F, &rootPair)) return(NULL); 00243 00244 if (complement) { 00245 cost = rootPair->neg; 00246 } else { 00247 cost = rootPair->pos; 00248 } 00249 00250 /* Recover an actual shortest path. */ 00251 sol = getPath(manager,visited,f,weight,cost); 00252 00253 st_foreach(visited, freePathPair, NULL); 00254 st_free_table(visited); 00255 00256 } while (manager->reordered == 1); 00257 00258 *length = cost; 00259 return(sol); 00260 00261 } /* end of Cudd_ShortestPath */
int Cudd_ShuffleHeap | ( | DdManager * | table, | |
int * | permutation | |||
) |
Function********************************************************************
Synopsis [Reorders variables according to given permutation.]
Description [Reorders variables according to given permutation. The i-th entry of the permutation array contains the index of the variable that should be brought to the i-th level. The size of the array should be equal or greater to the number of variables currently in use. Returns 1 in case of success; 0 otherwise.]
SideEffects [Changes the variable order for all diagrams and clears the cache.]
SeeAlso [Cudd_ReduceHeap]
Definition at line 334 of file cuddReorder.c.
00337 { 00338 00339 int result; 00340 int i; 00341 int identity = 1; 00342 int *perm; 00343 00344 /* Don't waste time in case of identity permutation. */ 00345 for (i = 0; i < table->size; i++) { 00346 if (permutation[i] != table->invperm[i]) { 00347 identity = 0; 00348 break; 00349 } 00350 } 00351 if (identity == 1) { 00352 return(1); 00353 } 00354 if (!ddReorderPreprocess(table)) return(0); 00355 if (table->keys > table->peakLiveNodes) { 00356 table->peakLiveNodes = table->keys; 00357 } 00358 00359 perm = ALLOC(int, table->size); 00360 for (i = 0; i < table->size; i++) 00361 perm[permutation[i]] = i; 00362 if (!ddCheckPermuation(table,table->tree,perm,permutation)) { 00363 FREE(perm); 00364 return(0); 00365 } 00366 if (!ddUpdateMtrTree(table,table->tree,perm,permutation)) { 00367 FREE(perm); 00368 return(0); 00369 } 00370 FREE(perm); 00371 00372 result = ddShuffle(table,permutation); 00373 00374 if (!ddReorderPostprocess(table)) return(0); 00375 00376 return(result); 00377 00378 } /* end of Cudd_ShuffleHeap */
DdNode* Cudd_SolveEqn | ( | DdManager * | bdd, | |
DdNode * | F, | |||
DdNode * | Y, | |||
DdNode ** | G, | |||
int ** | yIndex, | |||
int | n | |||
) |
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Implements the solution of F(x,y) = 0.]
Description [Implements the solution for F(x,y) = 0. The return value is the consistency condition. The y variables are the unknowns and the remaining variables are the parameters. Returns the consistency condition if successful; NULL otherwise. Cudd_SolveEqn allocates an array and fills it with the indices of the unknowns. This array is used by Cudd_VerifySol.]
SideEffects [The solution is returned in G; the indices of the y variables are returned in yIndex.]
SeeAlso [Cudd_VerifySol]
Definition at line 122 of file cuddSolve.c.
00129 { 00130 DdNode *res; 00131 int *temp; 00132 00133 *yIndex = temp = ALLOC(int, n); 00134 if (temp == NULL) { 00135 bdd->errorCode = CUDD_MEMORY_OUT; 00136 (void) fprintf(bdd->out, 00137 "Cudd_SolveEqn: Out of memory for yIndex\n"); 00138 return(NULL); 00139 } 00140 00141 do { 00142 bdd->reordered = 0; 00143 res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0); 00144 } while (bdd->reordered == 1); 00145 00146 return(res); 00147 00148 } /* end of Cudd_SolveEqn */
AutomaticEnd Function********************************************************************
Synopsis [Returns m minterms from a BDD.]
Description [Returns m
minterms from a BDD whose support has n
variables at most. The procedure tries to create as few extra nodes as possible. The function represented by S
depends on at most n
of the variables in xVars
. Returns a BDD with m
minterms of the on-set of S if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 124 of file cuddSplit.c.
00130 { 00131 DdNode *result; 00132 DdNode *zero, *one; 00133 double max, num; 00134 st_table *mtable; 00135 int *varSeen; 00136 int i,index, size; 00137 00138 size = manager->size; 00139 one = DD_ONE(manager); 00140 zero = Cudd_Not(one); 00141 00142 /* Trivial cases. */ 00143 if (m == 0.0) { 00144 return(zero); 00145 } 00146 if (S == zero) { 00147 return(NULL); 00148 } 00149 00150 max = pow(2.0,(double)n); 00151 if (m > max) 00152 return(NULL); 00153 00154 do { 00155 manager->reordered = 0; 00156 /* varSeen is used to mark the variables that are encountered 00157 ** while traversing the BDD S. 00158 */ 00159 varSeen = ALLOC(int, size); 00160 if (varSeen == NULL) { 00161 manager->errorCode = CUDD_MEMORY_OUT; 00162 return(NULL); 00163 } 00164 for (i = 0; i < size; i++) { 00165 varSeen[i] = -1; 00166 } 00167 for (i = 0; i < n; i++) { 00168 index = (xVars[i])->index; 00169 varSeen[manager->invperm[index]] = 0; 00170 } 00171 00172 if (S == one) { 00173 if (m == max) { 00174 FREE(varSeen); 00175 return(S); 00176 } 00177 result = selectMintermsFromUniverse(manager,varSeen,m); 00178 if (result) 00179 cuddRef(result); 00180 FREE(varSeen); 00181 } else { 00182 mtable = st_init_table(st_ptrcmp,st_ptrhash); 00183 if (mtable == NULL) { 00184 (void) fprintf(manager->out, 00185 "Cudd_SplitSet: out-of-memory.\n"); 00186 FREE(varSeen); 00187 manager->errorCode = CUDD_MEMORY_OUT; 00188 return(NULL); 00189 } 00190 /* The nodes of BDD S are annotated by the number of minterms 00191 ** in their onset. The node and the number of minterms in its 00192 ** onset are stored in mtable. 00193 */ 00194 num = bddAnnotateMintermCount(manager,S,max,mtable); 00195 if (m == num) { 00196 st_foreach(mtable,cuddStCountfree,NIL(char)); 00197 st_free_table(mtable); 00198 FREE(varSeen); 00199 return(S); 00200 } 00201 00202 result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0); 00203 if (result) 00204 cuddRef(result); 00205 st_foreach(mtable,cuddStCountfree,NULL); 00206 st_free_table(mtable); 00207 FREE(varSeen); 00208 } 00209 } while (manager->reordered == 1); 00210 00211 cuddDeref(result); 00212 return(result); 00213 00214 } /* end of Cudd_SplitSet */
void Cudd_Srandom | ( | long | seed | ) |
Function********************************************************************
Synopsis [Initializer for the portable random number generator.]
Description [Initializer for the portable number generator based on ran2 in "Numerical Recipes in C." The input is the seed for the generator. If it is negative, its absolute value is taken as seed. If it is 0, then 1 is taken as seed. The initialized sets up the two recurrences used to generate a long-period stream, and sets up the shuffle table.]
SideEffects [None]
SeeAlso [Cudd_Random]
Definition at line 2760 of file cuddUtil.c.
02762 { 02763 int i; 02764 02765 if (seed < 0) cuddRand = -seed; 02766 else if (seed == 0) cuddRand = 1; 02767 else cuddRand = seed; 02768 cuddRand2 = cuddRand; 02769 /* Load the shuffle table (after 11 warm-ups). */ 02770 for (i = 0; i < STAB_SIZE + 11; i++) { 02771 long int w; 02772 w = cuddRand / LEQQ1; 02773 cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; 02774 cuddRand += (cuddRand < 0) * MODULUS1; 02775 shuffleTable[i % STAB_SIZE] = cuddRand; 02776 } 02777 shuffleSelect = shuffleTable[1 % STAB_SIZE]; 02778 02779 } /* end of Cudd_Srandom */
int Cudd_StdPostReordHook | ( | DdManager * | dd, | |
const char * | str, | |||
void * | data | |||
) |
Function********************************************************************
Synopsis [Sample hook function to call after reordering.]
Description [Sample hook function to call after reordering. Prints on the manager's stdout final size and reordering time. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_StdPreReordHook]
Definition at line 3498 of file cuddAPI.c.
03502 { 03503 long initialTime = (long) data; 03504 int retval; 03505 long finalTime = util_cpu_time(); 03506 double totalTimeSec = (double)(finalTime - initialTime) / 1000.0; 03507 03508 retval = fprintf(dd->out,"%ld nodes in %g sec\n", strcmp(str, "BDD") == 0 ? 03509 Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd), 03510 totalTimeSec); 03511 if (retval == EOF) return(0); 03512 retval = fflush(dd->out); 03513 if (retval == EOF) return(0); 03514 return(1); 03515 03516 } /* end of Cudd_StdPostReordHook */
int Cudd_StdPreReordHook | ( | DdManager * | dd, | |
const char * | str, | |||
void * | data | |||
) |
Function********************************************************************
Synopsis [Sample hook function to call before reordering.]
Description [Sample hook function to call before reordering. Prints on the manager's stdout reordering method and initial size. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_StdPostReordHook]
Definition at line 3405 of file cuddAPI.c.
03409 { 03410 Cudd_ReorderingType method = (Cudd_ReorderingType) (ptruint) data; 03411 int retval; 03412 03413 retval = fprintf(dd->out,"%s reordering with ", str); 03414 if (retval == EOF) return(0); 03415 switch (method) { 03416 case CUDD_REORDER_SIFT_CONVERGE: 03417 case CUDD_REORDER_SYMM_SIFT_CONV: 03418 case CUDD_REORDER_GROUP_SIFT_CONV: 03419 case CUDD_REORDER_WINDOW2_CONV: 03420 case CUDD_REORDER_WINDOW3_CONV: 03421 case CUDD_REORDER_WINDOW4_CONV: 03422 case CUDD_REORDER_LINEAR_CONVERGE: 03423 retval = fprintf(dd->out,"converging "); 03424 if (retval == EOF) return(0); 03425 break; 03426 default: 03427 break; 03428 } 03429 switch (method) { 03430 case CUDD_REORDER_RANDOM: 03431 case CUDD_REORDER_RANDOM_PIVOT: 03432 retval = fprintf(dd->out,"random"); 03433 break; 03434 case CUDD_REORDER_SIFT: 03435 case CUDD_REORDER_SIFT_CONVERGE: 03436 retval = fprintf(dd->out,"sifting"); 03437 break; 03438 case CUDD_REORDER_SYMM_SIFT: 03439 case CUDD_REORDER_SYMM_SIFT_CONV: 03440 retval = fprintf(dd->out,"symmetric sifting"); 03441 break; 03442 case CUDD_REORDER_LAZY_SIFT: 03443 retval = fprintf(dd->out,"lazy sifting"); 03444 break; 03445 case CUDD_REORDER_GROUP_SIFT: 03446 case CUDD_REORDER_GROUP_SIFT_CONV: 03447 retval = fprintf(dd->out,"group sifting"); 03448 break; 03449 case CUDD_REORDER_WINDOW2: 03450 case CUDD_REORDER_WINDOW3: 03451 case CUDD_REORDER_WINDOW4: 03452 case CUDD_REORDER_WINDOW2_CONV: 03453 case CUDD_REORDER_WINDOW3_CONV: 03454 case CUDD_REORDER_WINDOW4_CONV: 03455 retval = fprintf(dd->out,"window"); 03456 break; 03457 case CUDD_REORDER_ANNEALING: 03458 retval = fprintf(dd->out,"annealing"); 03459 break; 03460 case CUDD_REORDER_GENETIC: 03461 retval = fprintf(dd->out,"genetic"); 03462 break; 03463 case CUDD_REORDER_LINEAR: 03464 case CUDD_REORDER_LINEAR_CONVERGE: 03465 retval = fprintf(dd->out,"linear sifting"); 03466 break; 03467 case CUDD_REORDER_EXACT: 03468 retval = fprintf(dd->out,"exact"); 03469 break; 03470 default: 03471 return(0); 03472 } 03473 if (retval == EOF) return(0); 03474 03475 retval = fprintf(dd->out,": from %ld to ... ", strcmp(str, "BDD") == 0 ? 03476 Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd)); 03477 if (retval == EOF) return(0); 03478 fflush(dd->out); 03479 return(1); 03480 03481 } /* end of Cudd_StdPreReordHook */
Function********************************************************************
Synopsis [Find a dense subset of BDD f
.]
Description [Finds a dense subset of BDD f
. Density is the ratio of number of minterms to number of nodes. Uses several techniques in series. It is more expensive than other subsetting procedures, but often produces better results. See Cudd_SubsetShortPaths for a description of the threshold and nvars parameters. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_SubsetRemap Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_bddSqueeze]
Definition at line 696 of file cuddGenCof.c.
00701 { 00702 DdNode *res, *tmp1, *tmp2; 00703 00704 tmp1 = Cudd_SubsetShortPaths(dd, f, nvars, threshold, 0); 00705 if (tmp1 == NULL) return(NULL); 00706 cuddRef(tmp1); 00707 tmp2 = Cudd_RemapUnderApprox(dd,tmp1,nvars,0,1.0); 00708 if (tmp2 == NULL) { 00709 Cudd_IterDerefBdd(dd,tmp1); 00710 return(NULL); 00711 } 00712 cuddRef(tmp2); 00713 Cudd_IterDerefBdd(dd,tmp1); 00714 res = Cudd_bddSqueeze(dd,tmp2,f); 00715 if (res == NULL) { 00716 Cudd_IterDerefBdd(dd,tmp2); 00717 return(NULL); 00718 } 00719 cuddRef(res); 00720 Cudd_IterDerefBdd(dd,tmp2); 00721 cuddDeref(res); 00722 return(res); 00723 00724 } /* end of Cudd_SubsetCompress */
AutomaticEnd Function********************************************************************
Synopsis [Extracts a dense subset from a BDD with the heavy branch heuristic.]
Description [Extracts a dense subset from a BDD. This procedure builds a subset by throwing away one of the children of each node, starting from the root, until the result is small enough. The child that is eliminated from the result is the one that contributes the fewer minterms. Returns a pointer to the BDD of the subset if successful. NULL if the procedure runs out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation and node count calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]
SideEffects [None]
SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize]
Definition at line 205 of file cuddSubsetHB.c.
DdNode* Cudd_SubsetShortPaths | ( | DdManager * | dd, | |
DdNode * | f, | |||
int | numVars, | |||
int | threshold, | |||
int | hardlimit | |||
) |
AutomaticEnd Function********************************************************************
Synopsis [Extracts a dense subset from a BDD with the shortest paths heuristic.]
Description [Extracts a dense subset from a BDD. This procedure tries to preserve the shortest paths of the input BDD, because they give many minterms and contribute few nodes. This procedure may increase the number of nodes in trying to create the subset or reduce the number of nodes due to recombination as compared to the original BDD. Hence the threshold may not be strictly adhered to. In practice, recombination overshadows the increase in the number of nodes and results in small BDDs as compared to the threshold. The hardlimit specifies whether threshold needs to be strictly adhered to. If it is set to 1, the procedure ensures that result is never larger than the specified limit but may be considerably less than the threshold. Returns a pointer to the BDD for the subset if successful; NULL otherwise. The value for numVars should be as close as possible to the size of the support of f for better efficiency. However, it is safe to pass the value returned by Cudd_ReadSize for numVars. If 0 is passed, then the value returned by Cudd_ReadSize is used.]
SideEffects [None]
SeeAlso [Cudd_SupersetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize]
Definition at line 216 of file cuddSubsetSP.c.
00221 : 1 if threshold is a hard limit */) 00222 { 00223 DdNode *subset; 00224 00225 memOut = 0; 00226 do { 00227 dd->reordered = 0; 00228 subset = cuddSubsetShortPaths(dd, f, numVars, threshold, hardlimit); 00229 } while((dd->reordered ==1) && (!memOut)); 00230 00231 return(subset); 00232 00233 } /* end of Cudd_SubsetShortPaths */
DdNode* Cudd_SubsetWithMaskVars | ( | DdManager * | dd, | |
DdNode * | f, | |||
DdNode ** | vars, | |||
int | nvars, | |||
DdNode ** | maskVars, | |||
int | mvars | |||
) |
Function********************************************************************
Synopsis [Extracts a subset from a BDD.]
Description [Extracts a subset from a BDD in the following procedure. 1. Compute the weight for each mask variable by counting the number of minterms for both positive and negative cofactors of the BDD with respect to each mask variable. (weight = positive - negative) 2. Find a representative cube of the BDD by using the weight. From the top variable of the BDD, for each variable, if the weight is greater than 0.0, choose THEN branch, othereise ELSE branch, until meeting the constant 1. 3. Quantify out the variables not in maskVars from the representative cube and if a variable in maskVars is don't care, replace the variable with a constant(1 or 0) depending on the weight. 4. Make a subset of the BDD by multiplying with the modified cube.]
SideEffects [None]
SeeAlso []
Definition at line 1598 of file cuddUtil.c.
01605 { 01606 double *weight; 01607 char *string; 01608 int i, size; 01609 int *indices, *mask; 01610 int result; 01611 DdNode *zero, *cube, *newCube, *subset; 01612 DdNode *cof; 01613 01614 DdNode *support; 01615 support = Cudd_Support(dd,f); 01616 cuddRef(support); 01617 Cudd_RecursiveDeref(dd,support); 01618 01619 zero = Cudd_Not(dd->one); 01620 size = dd->size; 01621 01622 weight = ALLOC(double,size); 01623 if (weight == NULL) { 01624 dd->errorCode = CUDD_MEMORY_OUT; 01625 return(NULL); 01626 } 01627 for (i = 0; i < size; i++) { 01628 weight[i] = 0.0; 01629 } 01630 for (i = 0; i < mvars; i++) { 01631 cof = Cudd_Cofactor(dd, f, maskVars[i]); 01632 cuddRef(cof); 01633 weight[i] = Cudd_CountMinterm(dd, cof, nvars); 01634 Cudd_RecursiveDeref(dd,cof); 01635 01636 cof = Cudd_Cofactor(dd, f, Cudd_Not(maskVars[i])); 01637 cuddRef(cof); 01638 weight[i] -= Cudd_CountMinterm(dd, cof, nvars); 01639 Cudd_RecursiveDeref(dd,cof); 01640 } 01641 01642 string = ALLOC(char, size + 1); 01643 if (string == NULL) { 01644 dd->errorCode = CUDD_MEMORY_OUT; 01645 FREE(weight); 01646 return(NULL); 01647 } 01648 mask = ALLOC(int, size); 01649 if (mask == NULL) { 01650 dd->errorCode = CUDD_MEMORY_OUT; 01651 FREE(weight); 01652 FREE(string); 01653 return(NULL); 01654 } 01655 for (i = 0; i < size; i++) { 01656 string[i] = '2'; 01657 mask[i] = 0; 01658 } 01659 string[size] = '\0'; 01660 indices = ALLOC(int,nvars); 01661 if (indices == NULL) { 01662 dd->errorCode = CUDD_MEMORY_OUT; 01663 FREE(weight); 01664 FREE(string); 01665 FREE(mask); 01666 return(NULL); 01667 } 01668 for (i = 0; i < nvars; i++) { 01669 indices[i] = vars[i]->index; 01670 } 01671 01672 result = ddPickRepresentativeCube(dd,f,weight,string); 01673 if (result == 0) { 01674 FREE(weight); 01675 FREE(string); 01676 FREE(mask); 01677 FREE(indices); 01678 return(NULL); 01679 } 01680 01681 cube = Cudd_ReadOne(dd); 01682 cuddRef(cube); 01683 zero = Cudd_Not(Cudd_ReadOne(dd)); 01684 for (i = 0; i < nvars; i++) { 01685 if (string[indices[i]] == '0') { 01686 newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); 01687 } else if (string[indices[i]] == '1') { 01688 newCube = Cudd_bddIte(dd,cube,vars[i],zero); 01689 } else 01690 continue; 01691 if (newCube == NULL) { 01692 FREE(weight); 01693 FREE(string); 01694 FREE(mask); 01695 FREE(indices); 01696 Cudd_RecursiveDeref(dd,cube); 01697 return(NULL); 01698 } 01699 cuddRef(newCube); 01700 Cudd_RecursiveDeref(dd,cube); 01701 cube = newCube; 01702 } 01703 Cudd_RecursiveDeref(dd,cube); 01704 01705 for (i = 0; i < mvars; i++) { 01706 mask[maskVars[i]->index] = 1; 01707 } 01708 for (i = 0; i < nvars; i++) { 01709 if (mask[indices[i]]) { 01710 if (string[indices[i]] == '2') { 01711 if (weight[indices[i]] >= 0.0) 01712 string[indices[i]] = '1'; 01713 else 01714 string[indices[i]] = '0'; 01715 } 01716 } else { 01717 string[indices[i]] = '2'; 01718 } 01719 } 01720 01721 cube = Cudd_ReadOne(dd); 01722 cuddRef(cube); 01723 zero = Cudd_Not(Cudd_ReadOne(dd)); 01724 01725 /* Build result BDD. */ 01726 for (i = 0; i < nvars; i++) { 01727 if (string[indices[i]] == '0') { 01728 newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); 01729 } else if (string[indices[i]] == '1') { 01730 newCube = Cudd_bddIte(dd,cube,vars[i],zero); 01731 } else 01732 continue; 01733 if (newCube == NULL) { 01734 FREE(weight); 01735 FREE(string); 01736 FREE(mask); 01737 FREE(indices); 01738 Cudd_RecursiveDeref(dd,cube); 01739 return(NULL); 01740 } 01741 cuddRef(newCube); 01742 Cudd_RecursiveDeref(dd,cube); 01743 cube = newCube; 01744 } 01745 01746 subset = Cudd_bddAnd(dd,f,cube); 01747 cuddRef(subset); 01748 Cudd_RecursiveDeref(dd,cube); 01749 01750 /* Test. */ 01751 if (Cudd_bddLeq(dd,subset,f)) { 01752 cuddDeref(subset); 01753 } else { 01754 Cudd_RecursiveDeref(dd,subset); 01755 subset = NULL; 01756 } 01757 01758 FREE(weight); 01759 FREE(string); 01760 FREE(mask); 01761 FREE(indices); 01762 return(subset); 01763 01764 } /* end of Cudd_SubsetWithMaskVars */
Function********************************************************************
Synopsis [Find a dense superset of BDD f
.]
Description [Finds a dense superset of BDD f
. Density is the ratio of number of minterms to number of nodes. Uses several techniques in series. It is more expensive than other supersetting procedures, but often produces better results. See Cudd_SupersetShortPaths for a description of the threshold and nvars parameters. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_SubsetCompress Cudd_SupersetRemap Cudd_SupersetShortPaths Cudd_SupersetHeavyBranch Cudd_bddSqueeze]
Definition at line 746 of file cuddGenCof.c.
00751 { 00752 DdNode *subset; 00753 00754 subset = Cudd_SubsetCompress(dd, Cudd_Not(f),nvars,threshold); 00755 00756 return(Cudd_NotCond(subset, (subset != NULL))); 00757 00758 } /* end of Cudd_SupersetCompress */
Function********************************************************************
Synopsis [Extracts a dense superset from a BDD with the heavy branch heuristic.]
Description [Extracts a dense superset from a BDD. The procedure is identical to the subset procedure except for the fact that it receives the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. This procedure builds a superset by throwing away one of the children of each node starting from the root of the complement function, until the result is small enough. The child that is eliminated from the result is the one that contributes the fewer minterms. Returns a pointer to the BDD of the superset if successful. NULL if intermediate result causes the procedure to run out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation and node count calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]
SideEffects [None]
SeeAlso [Cudd_SubsetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize]
Definition at line 255 of file cuddSubsetHB.c.
00260 { 00261 DdNode *subset, *g; 00262 00263 g = Cudd_Not(f); 00264 memOut = 0; 00265 do { 00266 dd->reordered = 0; 00267 subset = cuddSubsetHeavyBranch(dd, g, numVars, threshold); 00268 } while ((dd->reordered == 1) && (!memOut)); 00269 00270 return(Cudd_NotCond(subset, (subset != NULL))); 00271 00272 } /* end of Cudd_SupersetHeavyBranch */
DdNode* Cudd_SupersetShortPaths | ( | DdManager * | dd, | |
DdNode * | f, | |||
int | numVars, | |||
int | threshold, | |||
int | hardlimit | |||
) |
Function********************************************************************
Synopsis [Extracts a dense superset from a BDD with the shortest paths heuristic.]
Description [Extracts a dense superset from a BDD. The procedure is identical to the subset procedure except for the fact that it receives the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. This procedure tries to preserve the shortest paths of the complement BDD, because they give many minterms and contribute few nodes. This procedure may increase the number of nodes in trying to create the superset or reduce the number of nodes due to recombination as compared to the original BDD. Hence the threshold may not be strictly adhered to. In practice, recombination overshadows the increase in the number of nodes and results in small BDDs as compared to the threshold. The hardlimit specifies whether threshold needs to be strictly adhered to. If it is set to 1, the procedure ensures that result is never larger than the specified limit but may be considerably less than the threshold. Returns a pointer to the BDD for the superset if successful; NULL otherwise. The value for numVars should be as close as possible to the size of the support of f for better efficiency. However, it is safe to pass the value returned by Cudd_ReadSize for numVar. If 0 is passed, then the value returned by Cudd_ReadSize is used.]
SideEffects [None]
SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize]
Definition at line 268 of file cuddSubsetSP.c.
00273 : 1 if threshold is a hard limit */) 00274 { 00275 DdNode *subset, *g; 00276 00277 g = Cudd_Not(f); 00278 memOut = 0; 00279 do { 00280 dd->reordered = 0; 00281 subset = cuddSubsetShortPaths(dd, g, numVars, threshold, hardlimit); 00282 } while((dd->reordered ==1) && (!memOut)); 00283 00284 return(Cudd_NotCond(subset, (subset != NULL))); 00285 00286 } /* end of Cudd_SupersetShortPaths */
Function********************************************************************
Synopsis [Finds the variables on which a DD depends.]
Description [Finds the variables on which a DD depends. Returns a BDD consisting of the product of the variables if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_VectorSupport Cudd_ClassifySupport]
Definition at line 736 of file cuddUtil.c.
00739 { 00740 int *support; 00741 DdNode *res, *tmp, *var; 00742 int i,j; 00743 int size; 00744 00745 /* Allocate and initialize support array for ddSupportStep. */ 00746 size = ddMax(dd->size, dd->sizeZ); 00747 support = ALLOC(int,size); 00748 if (support == NULL) { 00749 dd->errorCode = CUDD_MEMORY_OUT; 00750 return(NULL); 00751 } 00752 for (i = 0; i < size; i++) { 00753 support[i] = 0; 00754 } 00755 00756 /* Compute support and clean up markers. */ 00757 ddSupportStep(Cudd_Regular(f),support); 00758 ddClearFlag(Cudd_Regular(f)); 00759 00760 /* Transform support from array to cube. */ 00761 do { 00762 dd->reordered = 0; 00763 res = DD_ONE(dd); 00764 cuddRef(res); 00765 for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ 00766 i = (j >= dd->size) ? j : dd->invperm[j]; 00767 if (support[i] == 1) { 00768 /* The following call to cuddUniqueInter is guaranteed 00769 ** not to trigger reordering because the node we look up 00770 ** already exists. */ 00771 var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); 00772 cuddRef(var); 00773 tmp = cuddBddAndRecur(dd,res,var); 00774 if (tmp == NULL) { 00775 Cudd_RecursiveDeref(dd,res); 00776 Cudd_RecursiveDeref(dd,var); 00777 res = NULL; 00778 break; 00779 } 00780 cuddRef(tmp); 00781 Cudd_RecursiveDeref(dd,res); 00782 Cudd_RecursiveDeref(dd,var); 00783 res = tmp; 00784 } 00785 } 00786 } while (dd->reordered == 1); 00787 00788 FREE(support); 00789 if (res != NULL) cuddDeref(res); 00790 return(res); 00791 00792 } /* end of Cudd_Support */
Function********************************************************************
Synopsis [Finds the variables on which a DD depends.]
Description [Finds the variables on which a DD depends. Returns an index array of the variables if successful; NULL otherwise. The size of the array equals the number of variables in the manager. Each entry of the array is 1 if the corresponding variable is in the support of the DD and 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_Support Cudd_VectorSupport Cudd_ClassifySupport]
Definition at line 811 of file cuddUtil.c.
00814 { 00815 int *support; 00816 int i; 00817 int size; 00818 00819 /* Allocate and initialize support array for ddSupportStep. */ 00820 size = ddMax(dd->size, dd->sizeZ); 00821 support = ALLOC(int,size); 00822 if (support == NULL) { 00823 dd->errorCode = CUDD_MEMORY_OUT; 00824 return(NULL); 00825 } 00826 for (i = 0; i < size; i++) { 00827 support[i] = 0; 00828 } 00829 00830 /* Compute support and clean up markers. */ 00831 ddSupportStep(Cudd_Regular(f),support); 00832 ddClearFlag(Cudd_Regular(f)); 00833 00834 return(support); 00835 00836 } /* end of Cudd_SupportIndex */
Function********************************************************************
Synopsis [Counts the variables on which a DD depends.]
Description [Counts the variables on which a DD depends. Returns the number of the variables if successful; CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_Support]
Definition at line 853 of file cuddUtil.c.
00856 { 00857 int *support; 00858 int i; 00859 int size; 00860 int count; 00861 00862 /* Allocate and initialize support array for ddSupportStep. */ 00863 size = ddMax(dd->size, dd->sizeZ); 00864 support = ALLOC(int,size); 00865 if (support == NULL) { 00866 dd->errorCode = CUDD_MEMORY_OUT; 00867 return(CUDD_OUT_OF_MEM); 00868 } 00869 for (i = 0; i < size; i++) { 00870 support[i] = 0; 00871 } 00872 00873 /* Compute support and clean up markers. */ 00874 ddSupportStep(Cudd_Regular(f),support); 00875 ddClearFlag(Cudd_Regular(f)); 00876 00877 /* Count support variables. */ 00878 count = 0; 00879 for (i = 0; i < size; i++) { 00880 if (support[i] == 1) count++; 00881 } 00882 00883 FREE(support); 00884 return(count); 00885 00886 } /* end of Cudd_SupportSize */
void Cudd_SymmProfile | ( | DdManager * | table, | |
int | lower, | |||
int | upper | |||
) |
AutomaticEnd Function********************************************************************
Synopsis [Prints statistics on symmetric variables.]
Description []
SideEffects [None]
Definition at line 138 of file cuddSymmetry.c.
00142 { 00143 int i,x,gbot; 00144 int TotalSymm = 0; 00145 int TotalSymmGroups = 0; 00146 00147 for (i = lower; i <= upper; i++) { 00148 if (table->subtables[i].next != (unsigned) i) { 00149 x = i; 00150 (void) fprintf(table->out,"Group:"); 00151 do { 00152 (void) fprintf(table->out," %d",table->invperm[x]); 00153 TotalSymm++; 00154 gbot = x; 00155 x = table->subtables[x].next; 00156 } while (x != i); 00157 TotalSymmGroups++; 00158 #ifdef DD_DEBUG 00159 assert(table->subtables[gbot].next == (unsigned) i); 00160 #endif 00161 i = gbot; 00162 (void) fprintf(table->out,"\n"); 00163 } 00164 } 00165 (void) fprintf(table->out,"Total Symmetric = %d\n",TotalSymm); 00166 (void) fprintf(table->out,"Total Groups = %d\n",TotalSymmGroups); 00167 00168 } /* end of Cudd_SymmProfile */
void Cudd_tlcInfoFree | ( | DdTlcInfo * | t | ) |
Function********************************************************************
Synopsis [Frees a DdTlcInfo Structure.]
Description [Frees a DdTlcInfo Structure as well as the memory pointed by it.]
SideEffects [None]
SeeAlso []
Definition at line 451 of file cuddEssent.c.
void Cudd_TurnOffCountDead | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Causes the dead nodes not to be counted towards triggering reordering.]
Description [Causes the dead nodes not to be counted towards triggering reordering. This causes less frequent reorderings. By default dead nodes are not counted. Therefore there is no need to call this function unless Cudd_TurnOnCountDead has been previously called.]
SideEffects [Changes the manager.]
SeeAlso [Cudd_TurnOnCountDead Cudd_DeadAreCounted]
Definition at line 2629 of file cuddAPI.c.
02631 { 02632 dd->countDead = ~0; 02633 02634 } /* end of Cudd_TurnOffCountDead */
void Cudd_TurnOnCountDead | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Causes the dead nodes to be counted towards triggering reordering.]
Description [Causes the dead nodes to be counted towards triggering reordering. This causes more frequent reorderings. By default dead nodes are not counted.]
SideEffects [Changes the manager.]
SeeAlso [Cudd_TurnOffCountDead Cudd_DeadAreCounted]
Definition at line 2604 of file cuddAPI.c.
02606 { 02607 dd->countDead = 0; 02608 02609 } /* end of Cudd_TurnOnCountDead */
DdNode* Cudd_UnderApprox | ( | DdManager * | dd, | |
DdNode * | f, | |||
int | numVars, | |||
int | threshold, | |||
int | safe, | |||
double | quality | |||
) |
AutomaticEnd Function********************************************************************
Synopsis [Extracts a dense subset from a BDD with Shiple's underapproximation method.]
Description [Extracts a dense subset from a BDD. This procedure uses a variant of Tom Shiple's underapproximation method. The main difference from the original method is that density is used as cost function. Returns a pointer to the BDD of the subset if successful. NULL if the procedure runs out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will cause overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]
SideEffects [None]
SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize]
Definition at line 224 of file cuddApprox.c.
00231 { 00232 DdNode *subset; 00233 00234 do { 00235 dd->reordered = 0; 00236 subset = cuddUnderApprox(dd, f, numVars, threshold, safe, quality); 00237 } while (dd->reordered == 1); 00238 00239 return(subset); 00240 00241 } /* end of Cudd_UnderApprox */
Function********************************************************************
Synopsis [Finds the variables on which a set of DDs depends.]
Description [Finds the variables on which a set of DDs depends. The set must contain either BDDs and ADDs, or ZDDs. Returns a BDD consisting of the product of the variables if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_Support Cudd_ClassifySupport]
Definition at line 904 of file cuddUtil.c.
00908 { 00909 int *support; 00910 DdNode *res, *tmp, *var; 00911 int i,j; 00912 int size; 00913 00914 /* Allocate and initialize support array for ddSupportStep. */ 00915 size = ddMax(dd->size, dd->sizeZ); 00916 support = ALLOC(int,size); 00917 if (support == NULL) { 00918 dd->errorCode = CUDD_MEMORY_OUT; 00919 return(NULL); 00920 } 00921 for (i = 0; i < size; i++) { 00922 support[i] = 0; 00923 } 00924 00925 /* Compute support and clean up markers. */ 00926 for (i = 0; i < n; i++) { 00927 ddSupportStep(Cudd_Regular(F[i]),support); 00928 } 00929 for (i = 0; i < n; i++) { 00930 ddClearFlag(Cudd_Regular(F[i])); 00931 } 00932 00933 /* Transform support from array to cube. */ 00934 res = DD_ONE(dd); 00935 cuddRef(res); 00936 for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ 00937 i = (j >= dd->size) ? j : dd->invperm[j]; 00938 if (support[i] == 1) { 00939 var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); 00940 cuddRef(var); 00941 tmp = Cudd_bddAnd(dd,res,var); 00942 if (tmp == NULL) { 00943 Cudd_RecursiveDeref(dd,res); 00944 Cudd_RecursiveDeref(dd,var); 00945 FREE(support); 00946 return(NULL); 00947 } 00948 cuddRef(tmp); 00949 Cudd_RecursiveDeref(dd,res); 00950 Cudd_RecursiveDeref(dd,var); 00951 res = tmp; 00952 } 00953 } 00954 00955 FREE(support); 00956 cuddDeref(res); 00957 return(res); 00958 00959 } /* end of Cudd_VectorSupport */
Function********************************************************************
Synopsis [Finds the variables on which a set of DDs depends.]
Description [Finds the variables on which a set of DDs depends. The set must contain either BDDs and ADDs, or ZDDs. Returns an index array of the variables if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_SupportIndex Cudd_VectorSupport Cudd_ClassifySupport]
Definition at line 976 of file cuddUtil.c.
00980 { 00981 int *support; 00982 int i; 00983 int size; 00984 00985 /* Allocate and initialize support array for ddSupportStep. */ 00986 size = ddMax(dd->size, dd->sizeZ); 00987 support = ALLOC(int,size); 00988 if (support == NULL) { 00989 dd->errorCode = CUDD_MEMORY_OUT; 00990 return(NULL); 00991 } 00992 for (i = 0; i < size; i++) { 00993 support[i] = 0; 00994 } 00995 00996 /* Compute support and clean up markers. */ 00997 for (i = 0; i < n; i++) { 00998 ddSupportStep(Cudd_Regular(F[i]),support); 00999 } 01000 for (i = 0; i < n; i++) { 01001 ddClearFlag(Cudd_Regular(F[i])); 01002 } 01003 01004 return(support); 01005 01006 } /* end of Cudd_VectorSupportIndex */
Function********************************************************************
Synopsis [Counts the variables on which a set of DDs depends.]
Description [Counts the variables on which a set of DDs depends. The set must contain either BDDs and ADDs, or ZDDs. Returns the number of the variables if successful; CUDD_OUT_OF_MEM otherwise.]
SideEffects [None]
SeeAlso [Cudd_VectorSupport Cudd_SupportSize]
Definition at line 1024 of file cuddUtil.c.
01028 { 01029 int *support; 01030 int i; 01031 int size; 01032 int count; 01033 01034 /* Allocate and initialize support array for ddSupportStep. */ 01035 size = ddMax(dd->size, dd->sizeZ); 01036 support = ALLOC(int,size); 01037 if (support == NULL) { 01038 dd->errorCode = CUDD_MEMORY_OUT; 01039 return(CUDD_OUT_OF_MEM); 01040 } 01041 for (i = 0; i < size; i++) { 01042 support[i] = 0; 01043 } 01044 01045 /* Compute support and clean up markers. */ 01046 for (i = 0; i < n; i++) { 01047 ddSupportStep(Cudd_Regular(F[i]),support); 01048 } 01049 for (i = 0; i < n; i++) { 01050 ddClearFlag(Cudd_Regular(F[i])); 01051 } 01052 01053 /* Count vriables in support. */ 01054 count = 0; 01055 for (i = 0; i < size; i++) { 01056 if (support[i] == 1) count++; 01057 } 01058 01059 FREE(support); 01060 return(count); 01061 01062 } /* end of Cudd_VectorSupportSize */
Function********************************************************************
Synopsis [Checks the solution of F(x,y) = 0.]
Description [Checks the solution of F(x,y) = 0. This procedure substitutes the solution components for the unknowns of F and returns the resulting BDD for F.]
SideEffects [Frees the memory pointed by yIndex.]
SeeAlso [Cudd_SolveEqn]
Definition at line 165 of file cuddSolve.c.
00171 { 00172 DdNode *res; 00173 00174 do { 00175 bdd->reordered = 0; 00176 res = cuddVerifySol(bdd, F, G, yIndex, n); 00177 } while (bdd->reordered == 1); 00178 00179 FREE(yIndex); 00180 00181 return(res); 00182 00183 } /* end of Cudd_VerifySol */
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 [Substitutes a variable with its complement in a ZDD.]
Description [Substitutes a variable with its complement in a ZDD. returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 388 of file cuddZddSetop.c.
00392 { 00393 DdNode *res; 00394 00395 if ((unsigned int) var >= CUDD_MAXINDEX - 1) return(NULL); 00396 00397 do { 00398 dd->reordered = 0; 00399 res = cuddZddChange(dd, P, var); 00400 } while (dd->reordered == 1); 00401 return(res); 00402 00403 } /* end of Cudd_zddChange */
Function********************************************************************
Synopsis [Computes a complement cover for a ZDD node.]
Description [Computes a complement cover for a ZDD node. For lack of a better method, we first extract the function BDD from the ZDD cover, then make the complement of the ZDD cover from the complement of the BDD node by using ISOP. Returns a pointer to the resulting cover if successful; NULL otherwise. The result depends on current variable order.]
SideEffects [The result depends on current variable order.]
SeeAlso []
Definition at line 328 of file cuddZddFuncs.c.
00331 { 00332 DdNode *b, *isop, *zdd_I; 00333 00334 /* Check cache */ 00335 zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node); 00336 if (zdd_I) 00337 return(zdd_I); 00338 00339 b = Cudd_MakeBddFromZddCover(dd, node); 00340 if (!b) 00341 return(NULL); 00342 Cudd_Ref(b); 00343 isop = Cudd_zddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I); 00344 if (!isop) { 00345 Cudd_RecursiveDeref(dd, b); 00346 return(NULL); 00347 } 00348 Cudd_Ref(isop); 00349 Cudd_Ref(zdd_I); 00350 Cudd_RecursiveDeref(dd, b); 00351 Cudd_RecursiveDeref(dd, isop); 00352 00353 cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I); 00354 Cudd_Deref(zdd_I); 00355 return(zdd_I); 00356 } /* end of Cudd_zddComplement */
AutomaticEnd Function********************************************************************
Synopsis [Counts the number of minterms in a ZDD.]
Description [Returns an integer representing the number of minterms in a ZDD.]
SideEffects [None]
SeeAlso [Cudd_zddCountDouble]
Definition at line 133 of file cuddZddCount.c.
00136 { 00137 st_table *table; 00138 int res; 00139 DdNode *base, *empty; 00140 00141 base = DD_ONE(zdd); 00142 empty = DD_ZERO(zdd); 00143 table = st_init_table(st_ptrcmp, st_ptrhash); 00144 if (table == NULL) return(CUDD_OUT_OF_MEM); 00145 res = cuddZddCountStep(P, table, base, empty); 00146 if (res == CUDD_OUT_OF_MEM) { 00147 zdd->errorCode = CUDD_MEMORY_OUT; 00148 } 00149 st_foreach(table, st_zdd_countfree, NIL(char)); 00150 st_free_table(table); 00151 00152 return(res); 00153 00154 } /* end of Cudd_zddCount */
Function********************************************************************
Synopsis [Counts the number of minterms of a ZDD.]
Description [Counts the number of minterms of a ZDD. The result is returned as a double. If the procedure runs out of memory, it returns (double) CUDD_OUT_OF_MEM. This procedure is used in Cudd_zddCountMinterm.]
SideEffects [None]
SeeAlso [Cudd_zddCountMinterm Cudd_zddCount]
Definition at line 172 of file cuddZddCount.c.
00175 { 00176 st_table *table; 00177 double res; 00178 DdNode *base, *empty; 00179 00180 base = DD_ONE(zdd); 00181 empty = DD_ZERO(zdd); 00182 table = st_init_table(st_ptrcmp, st_ptrhash); 00183 if (table == NULL) return((double)CUDD_OUT_OF_MEM); 00184 res = cuddZddCountDoubleStep(P, table, base, empty); 00185 if (res == (double)CUDD_OUT_OF_MEM) { 00186 zdd->errorCode = CUDD_MEMORY_OUT; 00187 } 00188 st_foreach(table, st_zdd_count_dbl_free, NIL(char)); 00189 st_free_table(table); 00190 00191 return(res); 00192 00193 } /* end of Cudd_zddCountDouble */
Function********************************************************************
Synopsis [Counts the number of minterms of a ZDD.]
Description [Counts the number of minterms of the ZDD rooted at node
. This procedure takes a parameter path
that specifies how many variables are in the support of the function. If the procedure runs out of memory, it returns (double) CUDD_OUT_OF_MEM.]
SideEffects [None]
SeeAlso [Cudd_zddCountDouble]
Definition at line 154 of file cuddZddMisc.c.
00158 { 00159 double dc_var, minterms; 00160 00161 dc_var = (double)((double)(zdd->sizeZ) - (double)path); 00162 minterms = Cudd_zddCountDouble(zdd, node) / pow(2.0, dc_var); 00163 return(minterms); 00164 00165 } /* end of Cudd_zddCountMinterm */
char* Cudd_zddCoverPathToString | ( | DdManager * | zdd, | |
int * | path, | |||
char * | str | |||
) |
Function********************************************************************
Synopsis [Converts a path of a ZDD representing a cover to a string.]
Description [Converts a path of a ZDD representing a cover to a string. The string represents an implicant of the cover. The path is typically produced by Cudd_zddForeachPath. Returns a pointer to the string if successful; NULL otherwise. If the str input is NULL, it allocates a new string. The string passed to this function must have enough room for all variables and for the terminator.]
SideEffects [None]
SeeAlso [Cudd_zddForeachPath]
Definition at line 471 of file cuddZddUtil.c.
00476 { 00477 int nvars = zdd->sizeZ; 00478 int i; 00479 char *res; 00480 00481 if (nvars & 1) return(NULL); 00482 nvars >>= 1; 00483 if (str == NULL) { 00484 res = ALLOC(char, nvars+1); 00485 if (res == NULL) return(NULL); 00486 } else { 00487 res = str; 00488 } 00489 for (i = 0; i < nvars; i++) { 00490 int v = (path[2*i] << 2) | path[2*i+1]; 00491 switch (v) { 00492 case 0: 00493 case 2: 00494 case 8: 00495 case 10: 00496 res[i] = '-'; 00497 break; 00498 case 1: 00499 case 9: 00500 res[i] = '0'; 00501 break; 00502 case 4: 00503 case 6: 00504 res[i] = '1'; 00505 break; 00506 default: 00507 res[i] = '?'; 00508 } 00509 } 00510 res[nvars] = 0; 00511 00512 return(res); 00513 00514 } /* end of Cudd_zddCoverPathToString */
int Cudd_zddDagSize | ( | DdNode * | p_node | ) |
AutomaticEnd Function********************************************************************
Synopsis [Counts the number of nodes in a ZDD.]
Description [Counts the number of nodes in a ZDD. This function duplicates Cudd_DagSize and is only retained for compatibility.]
SideEffects [None]
SeeAlso [Cudd_DagSize]
Definition at line 123 of file cuddZddMisc.c.
00125 { 00126 00127 int i; 00128 st_table *table; 00129 00130 table = st_init_table(st_ptrcmp, st_ptrhash); 00131 i = cuddZddDagInt(p_node, table); 00132 st_free_table(table); 00133 return(i); 00134 00135 } /* end of Cudd_zddDagSize */
Function********************************************************************
Synopsis [Computes the difference of two ZDDs.]
Description [Computes the difference of two ZDDs. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddDiffConst]
Definition at line 232 of file cuddZddSetop.c.
00236 { 00237 DdNode *res; 00238 00239 do { 00240 dd->reordered = 0; 00241 res = cuddZddDiff(dd, P, Q); 00242 } while (dd->reordered == 1); 00243 return(res); 00244 00245 } /* end of Cudd_zddDiff */
Function********************************************************************
Synopsis [Performs the inclusion test for ZDDs (P implies Q).]
Description [Inclusion test for ZDDs (P implies Q). No new nodes are generated by this procedure. Returns empty if true; a valid pointer different from empty or DD_NON_CONSTANT otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddDiff]
Definition at line 262 of file cuddZddSetop.c.
00266 { 00267 int p_top, q_top; 00268 DdNode *empty = DD_ZERO(zdd), *t, *res; 00269 DdManager *table = zdd; 00270 00271 statLine(zdd); 00272 if (P == empty) 00273 return(empty); 00274 if (Q == empty) 00275 return(P); 00276 if (P == Q) 00277 return(empty); 00278 00279 /* Check cache. The cache is shared by cuddZddDiff(). */ 00280 res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q); 00281 if (res != NULL) 00282 return(res); 00283 00284 if (cuddIsConstant(P)) 00285 p_top = P->index; 00286 else 00287 p_top = zdd->permZ[P->index]; 00288 if (cuddIsConstant(Q)) 00289 q_top = Q->index; 00290 else 00291 q_top = zdd->permZ[Q->index]; 00292 if (p_top < q_top) { 00293 res = DD_NON_CONSTANT; 00294 } else if (p_top > q_top) { 00295 res = Cudd_zddDiffConst(zdd, P, cuddE(Q)); 00296 } else { 00297 t = Cudd_zddDiffConst(zdd, cuddT(P), cuddT(Q)); 00298 if (t != empty) 00299 res = DD_NON_CONSTANT; 00300 else 00301 res = Cudd_zddDiffConst(zdd, cuddE(P), cuddE(Q)); 00302 } 00303 00304 cuddCacheInsert2(table, cuddZddDiff, P, Q, res); 00305 00306 return(res); 00307 00308 } /* end of Cudd_zddDiffConst */
Function********************************************************************
Synopsis [Computes the quotient of two unate covers.]
Description [Computes the quotient of two unate covers represented by ZDDs. Unate covers use one ZDD variable for each BDD variable. Returns a pointer to the resulting ZDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddWeakDiv]
Definition at line 237 of file cuddZddFuncs.c.
00241 { 00242 DdNode *res; 00243 00244 do { 00245 dd->reordered = 0; 00246 res = cuddZddDivide(dd, f, g); 00247 } while (dd->reordered == 1); 00248 return(res); 00249 00250 } /* end of Cudd_zddDivide */
Function********************************************************************
Synopsis [Modified version of Cudd_zddDivide.]
Description [Modified version of Cudd_zddDivide. This function may disappear in future releases.]
SideEffects [None]
SeeAlso []
Definition at line 295 of file cuddZddFuncs.c.
00299 { 00300 DdNode *res; 00301 00302 do { 00303 dd->reordered = 0; 00304 res = cuddZddDivideF(dd, f, g); 00305 } while (dd->reordered == 1); 00306 return(res); 00307 00308 } /* end of Cudd_zddDivideF */
int Cudd_zddDumpDot | ( | DdManager * | dd, | |
int | n, | |||
DdNode ** | f, | |||
char ** | inames, | |||
char ** | onames, | |||
FILE * | fp | |||
) |
Function********************************************************************
Synopsis [Writes a dot file representing the argument ZDDs.]
Description [Writes a file representing the argument ZDDs in a format suitable for the graph drawing program dot. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full). Cudd_zddDumpDot does not close the file: This is the caller responsibility. Cudd_zddDumpDot uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames. Cudd_zddDumpDot uses the following convention to draw arcs:
The dot options are chosen so that the drawing fits on a letter-size sheet. ]
SideEffects [None]
SeeAlso [Cudd_DumpDot Cudd_zddPrintDebug]
Definition at line 545 of file cuddZddUtil.c.
00552 { 00553 DdNode *support = NULL; 00554 DdNode *scan; 00555 int *sorted = NULL; 00556 int nvars = dd->sizeZ; 00557 st_table *visited = NULL; 00558 st_generator *gen; 00559 int retval; 00560 int i, j; 00561 int slots; 00562 DdNodePtr *nodelist; 00563 long refAddr, diff, mask; 00564 00565 /* Build a bit array with the support of f. */ 00566 sorted = ALLOC(int,nvars); 00567 if (sorted == NULL) { 00568 dd->errorCode = CUDD_MEMORY_OUT; 00569 goto failure; 00570 } 00571 for (i = 0; i < nvars; i++) sorted[i] = 0; 00572 00573 /* Take the union of the supports of each output function. */ 00574 for (i = 0; i < n; i++) { 00575 support = Cudd_Support(dd,f[i]); 00576 if (support == NULL) goto failure; 00577 cuddRef(support); 00578 scan = support; 00579 while (!cuddIsConstant(scan)) { 00580 sorted[scan->index] = 1; 00581 scan = cuddT(scan); 00582 } 00583 Cudd_RecursiveDeref(dd,support); 00584 } 00585 support = NULL; /* so that we do not try to free it in case of failure */ 00586 00587 /* Initialize symbol table for visited nodes. */ 00588 visited = st_init_table(st_ptrcmp, st_ptrhash); 00589 if (visited == NULL) goto failure; 00590 00591 /* Collect all the nodes of this DD in the symbol table. */ 00592 for (i = 0; i < n; i++) { 00593 retval = cuddCollectNodes(f[i],visited); 00594 if (retval == 0) goto failure; 00595 } 00596 00597 /* Find how many most significant hex digits are identical 00598 ** in the addresses of all the nodes. Build a mask based 00599 ** on this knowledge, so that digits that carry no information 00600 ** will not be printed. This is done in two steps. 00601 ** 1. We scan the symbol table to find the bits that differ 00602 ** in at least 2 addresses. 00603 ** 2. We choose one of the possible masks. There are 8 possible 00604 ** masks for 32-bit integer, and 16 possible masks for 64-bit 00605 ** integers. 00606 */ 00607 00608 /* Find the bits that are different. */ 00609 refAddr = (long) f[0]; 00610 diff = 0; 00611 gen = st_init_gen(visited); 00612 while (st_gen(gen, &scan, NULL)) { 00613 diff |= refAddr ^ (long) scan; 00614 } 00615 st_free_gen(gen); 00616 00617 /* Choose the mask. */ 00618 for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { 00619 mask = (1 << i) - 1; 00620 if (diff <= mask) break; 00621 } 00622 00623 /* Write the header and the global attributes. */ 00624 retval = fprintf(fp,"digraph \"ZDD\" {\n"); 00625 if (retval == EOF) return(0); 00626 retval = fprintf(fp, 00627 "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); 00628 if (retval == EOF) return(0); 00629 00630 /* Write the input name subgraph by scanning the support array. */ 00631 retval = fprintf(fp,"{ node [shape = plaintext];\n"); 00632 if (retval == EOF) goto failure; 00633 retval = fprintf(fp," edge [style = invis];\n"); 00634 if (retval == EOF) goto failure; 00635 /* We use a name ("CONST NODES") with an embedded blank, because 00636 ** it is unlikely to appear as an input name. 00637 */ 00638 retval = fprintf(fp," \"CONST NODES\" [style = invis];\n"); 00639 if (retval == EOF) goto failure; 00640 for (i = 0; i < nvars; i++) { 00641 if (sorted[dd->invpermZ[i]]) { 00642 if (inames == NULL) { 00643 retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]); 00644 } else { 00645 retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]); 00646 } 00647 if (retval == EOF) goto failure; 00648 } 00649 } 00650 retval = fprintf(fp,"\"CONST NODES\"; \n}\n"); 00651 if (retval == EOF) goto failure; 00652 00653 /* Write the output node subgraph. */ 00654 retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); 00655 if (retval == EOF) goto failure; 00656 for (i = 0; i < n; i++) { 00657 if (onames == NULL) { 00658 retval = fprintf(fp,"\"F%d\"", i); 00659 } else { 00660 retval = fprintf(fp,"\" %s \"", onames[i]); 00661 } 00662 if (retval == EOF) goto failure; 00663 if (i == n - 1) { 00664 retval = fprintf(fp,"; }\n"); 00665 } else { 00666 retval = fprintf(fp," -> "); 00667 } 00668 if (retval == EOF) goto failure; 00669 } 00670 00671 /* Write rank info: All nodes with the same index have the same rank. */ 00672 for (i = 0; i < nvars; i++) { 00673 if (sorted[dd->invpermZ[i]]) { 00674 retval = fprintf(fp,"{ rank = same; "); 00675 if (retval == EOF) goto failure; 00676 if (inames == NULL) { 00677 retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]); 00678 } else { 00679 retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]); 00680 } 00681 if (retval == EOF) goto failure; 00682 nodelist = dd->subtableZ[i].nodelist; 00683 slots = dd->subtableZ[i].slots; 00684 for (j = 0; j < slots; j++) { 00685 scan = nodelist[j]; 00686 while (scan != NULL) { 00687 if (st_is_member(visited,(char *) scan)) { 00688 retval = fprintf(fp,"\"%p\";\n", (void *) 00689 ((mask & (ptrint) scan) / 00690 sizeof(DdNode))); 00691 if (retval == EOF) goto failure; 00692 } 00693 scan = scan->next; 00694 } 00695 } 00696 retval = fprintf(fp,"}\n"); 00697 if (retval == EOF) goto failure; 00698 } 00699 } 00700 00701 /* All constants have the same rank. */ 00702 retval = fprintf(fp, 00703 "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); 00704 if (retval == EOF) goto failure; 00705 nodelist = dd->constants.nodelist; 00706 slots = dd->constants.slots; 00707 for (j = 0; j < slots; j++) { 00708 scan = nodelist[j]; 00709 while (scan != NULL) { 00710 if (st_is_member(visited,(char *) scan)) { 00711 retval = fprintf(fp,"\"%p\";\n", (void *) 00712 ((mask & (ptrint) scan) / sizeof(DdNode))); 00713 if (retval == EOF) goto failure; 00714 } 00715 scan = scan->next; 00716 } 00717 } 00718 retval = fprintf(fp,"}\n}\n"); 00719 if (retval == EOF) goto failure; 00720 00721 /* Write edge info. */ 00722 /* Edges from the output nodes. */ 00723 for (i = 0; i < n; i++) { 00724 if (onames == NULL) { 00725 retval = fprintf(fp,"\"F%d\"", i); 00726 } else { 00727 retval = fprintf(fp,"\" %s \"", onames[i]); 00728 } 00729 if (retval == EOF) goto failure; 00730 retval = fprintf(fp," -> \"%p\" [style = solid];\n", 00731 (void *) ((mask & (ptrint) f[i]) / 00732 sizeof(DdNode))); 00733 if (retval == EOF) goto failure; 00734 } 00735 00736 /* Edges from internal nodes. */ 00737 for (i = 0; i < nvars; i++) { 00738 if (sorted[dd->invpermZ[i]]) { 00739 nodelist = dd->subtableZ[i].nodelist; 00740 slots = dd->subtableZ[i].slots; 00741 for (j = 0; j < slots; j++) { 00742 scan = nodelist[j]; 00743 while (scan != NULL) { 00744 if (st_is_member(visited,(char *) scan)) { 00745 retval = fprintf(fp, 00746 "\"%p\" -> \"%p\";\n", 00747 (void *) ((mask & (ptrint) scan) / sizeof(DdNode)), 00748 (void *) ((mask & (ptrint) cuddT(scan)) / 00749 sizeof(DdNode))); 00750 if (retval == EOF) goto failure; 00751 retval = fprintf(fp, 00752 "\"%p\" -> \"%p\" [style = dashed];\n", 00753 (void *) ((mask & (ptrint) scan) 00754 / sizeof(DdNode)), 00755 (void *) ((mask & (ptrint) 00756 cuddE(scan)) / 00757 sizeof(DdNode))); 00758 if (retval == EOF) goto failure; 00759 } 00760 scan = scan->next; 00761 } 00762 } 00763 } 00764 } 00765 00766 /* Write constant labels. */ 00767 nodelist = dd->constants.nodelist; 00768 slots = dd->constants.slots; 00769 for (j = 0; j < slots; j++) { 00770 scan = nodelist[j]; 00771 while (scan != NULL) { 00772 if (st_is_member(visited,(char *) scan)) { 00773 retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n", 00774 (void *) ((mask & (ptrint) scan) / 00775 sizeof(DdNode)), 00776 cuddV(scan)); 00777 if (retval == EOF) goto failure; 00778 } 00779 scan = scan->next; 00780 } 00781 } 00782 00783 /* Write trailer and return. */ 00784 retval = fprintf(fp,"}\n"); 00785 if (retval == EOF) goto failure; 00786 00787 st_free_table(visited); 00788 FREE(sorted); 00789 return(1); 00790 00791 failure: 00792 if (sorted != NULL) FREE(sorted); 00793 if (visited != NULL) st_free_table(visited); 00794 return(0); 00795 00796 } /* end of Cudd_zddDumpBlif */
Function********************************************************************
Synopsis [Finds the first path of a ZDD.]
Description [Defines an iterator on the paths of a ZDD and finds its first path. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise.
A path is represented as an array of literals, which are integers in {0, 1, 2}; 0 represents an else arc out of a node, 1 represents a then arc out of a node, and 2 stands for the absence of a node. The size of the array equals the number of variables in the manager at the time Cudd_zddFirstCube is called.
The paths that end in the empty terminal are not enumerated.]
SideEffects [The first path is returned as a side effect.]
SeeAlso [Cudd_zddForeachPath Cudd_zddNextPath Cudd_GenFree Cudd_IsGenEmpty]
Definition at line 271 of file cuddZddUtil.c.
00275 { 00276 DdGen *gen; 00277 DdNode *top, *next, *prev; 00278 int i; 00279 int nvars; 00280 00281 /* Sanity Check. */ 00282 if (zdd == NULL || f == NULL) return(NULL); 00283 00284 /* Allocate generator an initialize it. */ 00285 gen = ALLOC(DdGen,1); 00286 if (gen == NULL) { 00287 zdd->errorCode = CUDD_MEMORY_OUT; 00288 return(NULL); 00289 } 00290 00291 gen->manager = zdd; 00292 gen->type = CUDD_GEN_ZDD_PATHS; 00293 gen->status = CUDD_GEN_EMPTY; 00294 gen->gen.cubes.cube = NULL; 00295 gen->gen.cubes.value = DD_ZERO_VAL; 00296 gen->stack.sp = 0; 00297 gen->stack.stack = NULL; 00298 gen->node = NULL; 00299 00300 nvars = zdd->sizeZ; 00301 gen->gen.cubes.cube = ALLOC(int,nvars); 00302 if (gen->gen.cubes.cube == NULL) { 00303 zdd->errorCode = CUDD_MEMORY_OUT; 00304 FREE(gen); 00305 return(NULL); 00306 } 00307 for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; 00308 00309 /* The maximum stack depth is one plus the number of variables. 00310 ** because a path may have nodes at all levels, including the 00311 ** constant level. 00312 */ 00313 gen->stack.stack = ALLOC(DdNodePtr, nvars+1); 00314 if (gen->stack.stack == NULL) { 00315 zdd->errorCode = CUDD_MEMORY_OUT; 00316 FREE(gen->gen.cubes.cube); 00317 FREE(gen); 00318 return(NULL); 00319 } 00320 for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; 00321 00322 /* Find the first path of the ZDD. */ 00323 gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; 00324 00325 while (1) { 00326 top = gen->stack.stack[gen->stack.sp-1]; 00327 if (!cuddIsConstant(Cudd_Regular(top))) { 00328 /* Take the else branch first. */ 00329 gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; 00330 next = cuddE(Cudd_Regular(top)); 00331 gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; 00332 } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { 00333 /* Backtrack. */ 00334 while (1) { 00335 if (gen->stack.sp == 1) { 00336 /* The current node has no predecessor. */ 00337 gen->status = CUDD_GEN_EMPTY; 00338 gen->stack.sp--; 00339 goto done; 00340 } 00341 prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); 00342 next = cuddT(prev); 00343 if (next != top) { /* follow the then branch next */ 00344 gen->gen.cubes.cube[prev->index] = 1; 00345 gen->stack.stack[gen->stack.sp-1] = next; 00346 break; 00347 } 00348 /* Pop the stack and try again. */ 00349 gen->gen.cubes.cube[prev->index] = 2; 00350 gen->stack.sp--; 00351 top = gen->stack.stack[gen->stack.sp-1]; 00352 } 00353 } else { 00354 gen->status = CUDD_GEN_NONEMPTY; 00355 gen->gen.cubes.value = cuddV(Cudd_Regular(top)); 00356 goto done; 00357 } 00358 } 00359 00360 done: 00361 *path = gen->gen.cubes.cube; 00362 return(gen); 00363 00364 } /* end of Cudd_zddFirstPath */
Function********************************************************************
Synopsis [Computes the intersection of two ZDDs.]
Description [Computes the intersection of two ZDDs. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 203 of file cuddZddSetop.c.
00207 { 00208 DdNode *res; 00209 00210 do { 00211 dd->reordered = 0; 00212 res = cuddZddIntersect(dd, P, Q); 00213 } while (dd->reordered == 1); 00214 return(res); 00215 00216 } /* end of Cudd_zddIntersect */
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Computes an ISOP in ZDD form from BDDs.]
Description [Computes an irredundant sum of products (ISOP) in ZDD form from BDDs. The two BDDs L and U represent the lower bound and the upper bound, respectively, of the function. The ISOP uses two ZDD variables for each BDD variable: One for the positive literal, and one for the negative literal. These two variables should be adjacent in the ZDD order. The two ZDD variables corresponding to BDD variable i
should have indices 2i
and 2i+1
. The result of this procedure depends on the variable order. If successful, Cudd_zddIsop returns the BDD for the function chosen from the interval. The ZDD representing the irredundant cover is returned as a side effect in zdd_I. In case of failure, NULL is returned.]
SideEffects [zdd_I holds the pointer to the ZDD for the ISOP on successful return.]
SeeAlso [Cudd_bddIsop Cudd_zddVarsFromBddVars]
Definition at line 132 of file cuddZddIsop.c.
00137 { 00138 DdNode *res; 00139 int autoDynZ; 00140 00141 autoDynZ = dd->autoDynZ; 00142 dd->autoDynZ = 0; 00143 00144 do { 00145 dd->reordered = 0; 00146 res = cuddZddIsop(dd, L, U, zdd_I); 00147 } while (dd->reordered == 1); 00148 dd->autoDynZ = autoDynZ; 00149 return(res); 00150 00151 } /* end of Cudd_zddIsop */
AutomaticEnd Function********************************************************************
Synopsis [Computes the ITE of three ZDDs.]
Description [Computes the ITE of three ZDDs. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 144 of file cuddZddSetop.c.
00149 { 00150 DdNode *res; 00151 00152 do { 00153 dd->reordered = 0; 00154 res = cuddZddIte(dd, f, g, h); 00155 } while (dd->reordered == 1); 00156 return(res); 00157 00158 } /* end of Cudd_zddIte */
Function********************************************************************
Synopsis [Returns the ZDD variable with index i.]
Description [Retrieves the ZDD variable with index i if it already exists, or creates a new ZDD variable. Returns a pointer to the variable if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddIthVar Cudd_addIthVar]
Definition at line 444 of file cuddAPI.c.
00447 { 00448 DdNode *res; 00449 DdNode *zvar; 00450 DdNode *lower; 00451 int j; 00452 00453 if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); 00454 00455 /* The i-th variable function has the following structure: 00456 ** at the level corresponding to index i there is a node whose "then" 00457 ** child points to the universe, and whose "else" child points to zero. 00458 ** Above that level there are nodes with identical children. 00459 */ 00460 00461 /* First we build the node at the level of index i. */ 00462 lower = (i < dd->sizeZ - 1) ? dd->univ[dd->permZ[i]+1] : DD_ONE(dd); 00463 do { 00464 dd->reordered = 0; 00465 zvar = cuddUniqueInterZdd(dd, i, lower, DD_ZERO(dd)); 00466 } while (dd->reordered == 1); 00467 00468 if (zvar == NULL) 00469 return(NULL); 00470 cuddRef(zvar); 00471 00472 /* Now we add the "filler" nodes above the level of index i. */ 00473 for (j = dd->permZ[i] - 1; j >= 0; j--) { 00474 do { 00475 dd->reordered = 0; 00476 res = cuddUniqueInterZdd(dd, dd->invpermZ[j], zvar, zvar); 00477 } while (dd->reordered == 1); 00478 if (res == NULL) { 00479 Cudd_RecursiveDerefZdd(dd,zvar); 00480 return(NULL); 00481 } 00482 cuddRef(res); 00483 Cudd_RecursiveDerefZdd(dd,zvar); 00484 zvar = res; 00485 } 00486 cuddDeref(zvar); 00487 return(zvar); 00488 00489 } /* end of Cudd_zddIthVar */
int Cudd_zddNextPath | ( | DdGen * | gen, | |
int ** | path | |||
) |
Function********************************************************************
Synopsis [Generates the next path of a ZDD.]
Description [Generates the next path of a ZDD onset, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]
SideEffects [The path is returned as a side effect. The generator is modified.]
SeeAlso [Cudd_zddForeachPath Cudd_zddFirstPath Cudd_GenFree Cudd_IsGenEmpty]
Definition at line 383 of file cuddZddUtil.c.
00386 { 00387 DdNode *top, *next, *prev; 00388 DdManager *zdd = gen->manager; 00389 00390 /* Backtrack from previously reached terminal node. */ 00391 while (1) { 00392 if (gen->stack.sp == 1) { 00393 /* The current node has no predecessor. */ 00394 gen->status = CUDD_GEN_EMPTY; 00395 gen->stack.sp--; 00396 goto done; 00397 } 00398 top = gen->stack.stack[gen->stack.sp-1]; 00399 prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); 00400 next = cuddT(prev); 00401 if (next != top) { /* follow the then branch next */ 00402 gen->gen.cubes.cube[prev->index] = 1; 00403 gen->stack.stack[gen->stack.sp-1] = next; 00404 break; 00405 } 00406 /* Pop the stack and try again. */ 00407 gen->gen.cubes.cube[prev->index] = 2; 00408 gen->stack.sp--; 00409 } 00410 00411 while (1) { 00412 top = gen->stack.stack[gen->stack.sp-1]; 00413 if (!cuddIsConstant(Cudd_Regular(top))) { 00414 /* Take the else branch first. */ 00415 gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; 00416 next = cuddE(Cudd_Regular(top)); 00417 gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; 00418 } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { 00419 /* Backtrack. */ 00420 while (1) { 00421 if (gen->stack.sp == 1) { 00422 /* The current node has no predecessor. */ 00423 gen->status = CUDD_GEN_EMPTY; 00424 gen->stack.sp--; 00425 goto done; 00426 } 00427 prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); 00428 next = cuddT(prev); 00429 if (next != top) { /* follow the then branch next */ 00430 gen->gen.cubes.cube[prev->index] = 1; 00431 gen->stack.stack[gen->stack.sp-1] = next; 00432 break; 00433 } 00434 /* Pop the stack and try again. */ 00435 gen->gen.cubes.cube[prev->index] = 2; 00436 gen->stack.sp--; 00437 top = gen->stack.stack[gen->stack.sp-1]; 00438 } 00439 } else { 00440 gen->status = CUDD_GEN_NONEMPTY; 00441 gen->gen.cubes.value = cuddV(Cudd_Regular(top)); 00442 goto done; 00443 } 00444 } 00445 00446 done: 00447 if (gen->status == CUDD_GEN_EMPTY) return(0); 00448 *path = gen->gen.cubes.cube; 00449 return(1); 00450 00451 } /* end of Cudd_zddNextPath */
AutomaticEnd Function********************************************************************
Synopsis [Converts a BDD into a ZDD.]
Description [Converts a BDD into a ZDD. This function assumes that there is a one-to-one correspondence between the BDD variables and the ZDD variables, and that the variable order is the same for both types of variables. These conditions are established if the ZDD variables are created by one call to Cudd_zddVarsFromBddVars with multiplicity = 1. Returns a pointer to the resulting ZDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddVarsFromBddVars]
Definition at line 127 of file cuddZddPort.c.
00130 { 00131 DdNode *res; 00132 00133 do { 00134 dd->reordered = 0; 00135 res = zddPortFromBddStep(dd,B,0); 00136 } while (dd->reordered == 1); 00137 00138 return(res); 00139 00140 } /* end of Cudd_zddPortFromBdd */
Function********************************************************************
Synopsis [Converts a ZDD into a BDD.]
Description [Converts a ZDD into a BDD. Returns a pointer to the resulting ZDD if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddPortFromBdd]
Definition at line 156 of file cuddZddPort.c.
00159 { 00160 DdNode *res; 00161 00162 do { 00163 dd->reordered = 0; 00164 res = zddPortToBddStep(dd,f,0); 00165 } while (dd->reordered == 1); 00166 00167 return(res); 00168 00169 } /* end of Cudd_zddPortToBdd */
Function********************************************************************
Synopsis [Prints a sum of products from a ZDD representing a cover.]
Description [Prints a sum of products from a ZDD representing a cover. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddPrintMinterm]
Definition at line 165 of file cuddZddUtil.c.
00168 { 00169 int i, size; 00170 int *list; 00171 00172 size = (int)zdd->sizeZ; 00173 if (size % 2 != 0) return(0); /* number of variables should be even */ 00174 list = ALLOC(int, size); 00175 if (list == NULL) { 00176 zdd->errorCode = CUDD_MEMORY_OUT; 00177 return(0); 00178 } 00179 for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ 00180 zddPrintCoverAux(zdd, node, 0, list); 00181 FREE(list); 00182 return(1); 00183 00184 } /* end of Cudd_zddPrintCover */
Function********************************************************************
Synopsis [Prints to the standard output a ZDD and its statistics.]
Description [Prints to the standard output a DD and its statistics. The statistics include the number of nodes and the number of minterms. (The number of minterms is also the number of combinations in the set.) The statistics are printed if pr > 0. Specifically:
Returns 1 if successful; 0 otherwise. ]
SideEffects [None]
SeeAlso []
Definition at line 211 of file cuddZddUtil.c.
00216 { 00217 DdNode *empty = DD_ZERO(zdd); 00218 int nodes; 00219 double minterms; 00220 int retval = 1; 00221 00222 if (f == empty && pr > 0) { 00223 (void) fprintf(zdd->out,": is the empty ZDD\n"); 00224 (void) fflush(zdd->out); 00225 return(1); 00226 } 00227 00228 if (pr > 0) { 00229 nodes = Cudd_zddDagSize(f); 00230 if (nodes == CUDD_OUT_OF_MEM) retval = 0; 00231 minterms = Cudd_zddCountMinterm(zdd, f, n); 00232 if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; 00233 (void) fprintf(zdd->out,": %d nodes %g minterms\n", 00234 nodes, minterms); 00235 if (pr > 2) 00236 if (!cuddZddP(zdd, f)) retval = 0; 00237 if (pr == 2 || pr > 3) { 00238 if (!Cudd_zddPrintMinterm(zdd, f)) retval = 0; 00239 (void) fprintf(zdd->out,"\n"); 00240 } 00241 (void) fflush(zdd->out); 00242 } 00243 return(retval); 00244 00245 } /* end of Cudd_zddPrintDebug */
AutomaticEnd Function********************************************************************
Synopsis [Prints a disjoint sum of product form for a ZDD.]
Description [Prints a disjoint sum of product form for a ZDD. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddPrintDebug Cudd_zddPrintCover]
Definition at line 131 of file cuddZddUtil.c.
00134 { 00135 int i, size; 00136 int *list; 00137 00138 size = (int)zdd->sizeZ; 00139 list = ALLOC(int, size); 00140 if (list == NULL) { 00141 zdd->errorCode = CUDD_MEMORY_OUT; 00142 return(0); 00143 } 00144 for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ 00145 zdd_print_minterm_aux(zdd, node, 0, list); 00146 FREE(list); 00147 return(1); 00148 00149 } /* end of Cudd_zddPrintMinterm */
void Cudd_zddPrintSubtable | ( | DdManager * | table | ) |
Function********************************************************************
Synopsis [Prints the ZDD table.]
Description [Prints the ZDD table for debugging purposes.]
SideEffects [None]
SeeAlso []
Definition at line 180 of file cuddZddMisc.c.
00182 { 00183 int i, j; 00184 DdNode *z1, *z1_next, *base; 00185 DdSubtable *ZSubTable; 00186 00187 base = table->one; 00188 for (i = table->sizeZ - 1; i >= 0; i--) { 00189 ZSubTable = &(table->subtableZ[i]); 00190 printf("subtable[%d]:\n", i); 00191 for (j = ZSubTable->slots - 1; j >= 0; j--) { 00192 z1 = ZSubTable->nodelist[j]; 00193 while (z1 != NIL(DdNode)) { 00194 (void) fprintf(table->out, 00195 #if SIZEOF_VOID_P == 8 00196 "ID = 0x%lx\tindex = %u\tr = %u\t", 00197 (ptruint) z1 / (ptruint) sizeof(DdNode), 00198 z1->index, z1->ref); 00199 #else 00200 "ID = 0x%x\tindex = %hu\tr = %hu\t", 00201 (ptruint) z1 / (ptruint) sizeof(DdNode), 00202 z1->index, z1->ref); 00203 #endif 00204 z1_next = cuddT(z1); 00205 if (Cudd_IsConstant(z1_next)) { 00206 (void) fprintf(table->out, "T = %d\t\t", 00207 (z1_next == base)); 00208 } 00209 else { 00210 #if SIZEOF_VOID_P == 8 00211 (void) fprintf(table->out, "T = 0x%lx\t", 00212 (ptruint) z1_next / (ptruint) sizeof(DdNode)); 00213 #else 00214 (void) fprintf(table->out, "T = 0x%x\t", 00215 (ptruint) z1_next / (ptruint) sizeof(DdNode)); 00216 #endif 00217 } 00218 z1_next = cuddE(z1); 00219 if (Cudd_IsConstant(z1_next)) { 00220 (void) fprintf(table->out, "E = %d\n", 00221 (z1_next == base)); 00222 } 00223 else { 00224 #if SIZEOF_VOID_P == 8 00225 (void) fprintf(table->out, "E = 0x%lx\n", 00226 (ptruint) z1_next / (ptruint) sizeof(DdNode)); 00227 #else 00228 (void) fprintf(table->out, "E = 0x%x\n", 00229 (ptruint) z1_next / (ptruint) sizeof(DdNode)); 00230 #endif 00231 } 00232 00233 z1_next = z1->next; 00234 z1 = z1_next; 00235 } 00236 } 00237 } 00238 putchar('\n'); 00239 00240 } /* Cudd_zddPrintSubtable */
AutomaticStart AutomaticEnd Function********************************************************************
Synopsis [Computes the product of two covers represented by ZDDs.]
Description [Computes the product of two covers represented by ZDDs. The result is also a ZDD. Returns a pointer to the result if successful; NULL otherwise. The covers on which Cudd_zddProduct operates use two ZDD variables for each function variable (one ZDD variable for each literal of the variable). Those two ZDD variables should be adjacent in the order.]
SideEffects [None]
SeeAlso [Cudd_zddUnateProduct]
Definition at line 141 of file cuddZddFuncs.c.
00145 { 00146 DdNode *res; 00147 00148 do { 00149 dd->reordered = 0; 00150 res = cuddZddProduct(dd, f, g); 00151 } while (dd->reordered == 1); 00152 return(res); 00153 00154 } /* end of Cudd_zddProduct */
long Cudd_zddReadNodeCount | ( | DdManager * | dd | ) |
Function********************************************************************
Synopsis [Reports the number of nodes in ZDDs.]
Description [Reports the number of nodes in ZDDs. This number always includes the two constants 1 and 0.]
SideEffects [None]
SeeAlso [Cudd_ReadPeakNodeCount Cudd_ReadNodeCount]
void Cudd_zddRealignDisable | ( | DdManager * | unique | ) |
Function********************************************************************
Synopsis [Disables realignment of ZDD order to BDD order.]
Description []
SideEffects [None]
SeeAlso [Cudd_zddRealignEnable Cudd_zddRealignmentEnabled Cudd_bddRealignEnable Cudd_bddRealignmentEnabled]
Definition at line 885 of file cuddAPI.c.
00887 { 00888 unique->realign = 0; 00889 return; 00890 00891 } /* end of Cudd_zddRealignDisable */
void Cudd_zddRealignEnable | ( | DdManager * | unique | ) |
Function********************************************************************
Synopsis [Enables realignment of ZDD order to BDD order.]
Description [Enables realignment of the ZDD variable order to the BDD variable order after the BDDs and ADDs have been reordered. The number of ZDD variables must be a multiple of the number of BDD variables for realignment to make sense. If this condition is not met, Cudd_ReduceHeap will return 0. Let M
be the ratio of the two numbers. For the purpose of realignment, the ZDD variables from M*i
to (M+1)*i-1
are reagarded as corresponding to BDD variable i
. Realignment is initially disabled.]
SideEffects [None]
SeeAlso [Cudd_ReduceHeap Cudd_zddRealignDisable Cudd_zddRealignmentEnabled Cudd_bddRealignDisable Cudd_bddRealignmentEnabled]
Definition at line 863 of file cuddAPI.c.
00865 { 00866 unique->realign = 1; 00867 return; 00868 00869 } /* end of Cudd_zddRealignEnable */
int Cudd_zddRealignmentEnabled | ( | DdManager * | unique | ) |
Function********************************************************************
Synopsis [Tells whether the realignment of ZDD order to BDD order is enabled.]
Description [Returns 1 if the realignment of ZDD order to BDD order is enabled; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddRealignEnable Cudd_zddRealignDisable Cudd_bddRealignEnable Cudd_bddRealignDisable]
Definition at line 833 of file cuddAPI.c.
00835 { 00836 return(unique->realign); 00837 00838 } /* end of Cudd_zddRealignmentEnabled */
int Cudd_zddReduceHeap | ( | DdManager * | table, | |
Cudd_ReorderingType | heuristic, | |||
int | minsize | |||
) |
AutomaticEnd Function********************************************************************
Synopsis [Main dynamic reordering routine for ZDDs.]
Description [Main dynamic reordering routine for ZDDs. Calls one of the possible reordering procedures:
For sifting and symmetric sifting it is possible to request reordering to convergence.
The core of all methods is the reordering procedure cuddZddSwapInPlace() which swaps two adjacent variables. Returns 1 in case of success; 0 otherwise. In the case of symmetric sifting (with and without convergence) returns 1 plus the number of symmetric variables, in case of success.]
SideEffects [Changes the variable order for all ZDDs and clears the cache.]
Definition at line 167 of file cuddZddReord.c.
00171 { 00172 DdHook *hook; 00173 int result; 00174 unsigned int nextDyn; 00175 #ifdef DD_STATS 00176 unsigned int initialSize; 00177 unsigned int finalSize; 00178 #endif 00179 long localTime; 00180 00181 /* Don't reorder if there are too many dead nodes. */ 00182 if (table->keysZ - table->deadZ < (unsigned) minsize) 00183 return(1); 00184 00185 if (heuristic == CUDD_REORDER_SAME) { 00186 heuristic = table->autoMethodZ; 00187 } 00188 if (heuristic == CUDD_REORDER_NONE) { 00189 return(1); 00190 } 00191 00192 /* This call to Cudd_zddReduceHeap does initiate reordering. Therefore 00193 ** we count it. 00194 */ 00195 table->reorderings++; 00196 empty = table->zero; 00197 00198 localTime = util_cpu_time(); 00199 00200 /* Run the hook functions. */ 00201 hook = table->preReorderingHook; 00202 while (hook != NULL) { 00203 int res = (hook->f)(table, "ZDD", (void *)heuristic); 00204 if (res == 0) return(0); 00205 hook = hook->next; 00206 } 00207 00208 /* Clear the cache and collect garbage. */ 00209 zddReorderPreprocess(table); 00210 zddTotalNumberSwapping = 0; 00211 00212 #ifdef DD_STATS 00213 initialSize = table->keysZ; 00214 00215 switch(heuristic) { 00216 case CUDD_REORDER_RANDOM: 00217 case CUDD_REORDER_RANDOM_PIVOT: 00218 (void) fprintf(table->out,"#:I_RANDOM "); 00219 break; 00220 case CUDD_REORDER_SIFT: 00221 case CUDD_REORDER_SIFT_CONVERGE: 00222 case CUDD_REORDER_SYMM_SIFT: 00223 case CUDD_REORDER_SYMM_SIFT_CONV: 00224 (void) fprintf(table->out,"#:I_SIFTING "); 00225 break; 00226 case CUDD_REORDER_LINEAR: 00227 case CUDD_REORDER_LINEAR_CONVERGE: 00228 (void) fprintf(table->out,"#:I_LINSIFT "); 00229 break; 00230 default: 00231 (void) fprintf(table->err,"Unsupported ZDD reordering method\n"); 00232 return(0); 00233 } 00234 (void) fprintf(table->out,"%8d: initial size",initialSize); 00235 #endif 00236 00237 result = cuddZddTreeSifting(table,heuristic); 00238 00239 #ifdef DD_STATS 00240 (void) fprintf(table->out,"\n"); 00241 finalSize = table->keysZ; 00242 (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); 00243 (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n", 00244 ((double)(util_cpu_time() - localTime)/1000.0)); 00245 (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n", 00246 zddTotalNumberSwapping); 00247 #endif 00248 00249 if (result == 0) 00250 return(0); 00251 00252 if (!zddReorderPostprocess(table)) 00253 return(0); 00254 00255 if (table->realignZ) { 00256 if (!cuddBddAlignToZdd(table)) 00257 return(0); 00258 } 00259 00260 nextDyn = table->keysZ * DD_DYN_RATIO; 00261 if (table->reorderings < 20 || nextDyn > table->nextDyn) 00262 table->nextDyn = nextDyn; 00263 else 00264 table->nextDyn += 20; 00265 00266 table->reordered = 1; 00267 00268 /* Run hook functions. */ 00269 hook = table->postReorderingHook; 00270 while (hook != NULL) { 00271 int res = (hook->f)(table, "ZDD", (void *)localTime); 00272 if (res == 0) return(0); 00273 hook = hook->next; 00274 } 00275 /* Update cumulative reordering time. */ 00276 table->reordTime += util_cpu_time() - localTime; 00277 00278 return(result); 00279 00280 } /* end of Cudd_zddReduceHeap */
int Cudd_zddShuffleHeap | ( | DdManager * | table, | |
int * | permutation | |||
) |
Function********************************************************************
Synopsis [Reorders ZDD variables according to given permutation.]
Description [Reorders ZDD variables according to given permutation. The i-th entry of the permutation array contains the index of the variable that should be brought to the i-th level. The size of the array should be equal or greater to the number of variables currently in use. Returns 1 in case of success; 0 otherwise.]
SideEffects [Changes the ZDD variable order for all diagrams and clears the cache.]
SeeAlso [Cudd_zddReduceHeap]
Definition at line 300 of file cuddZddReord.c.
00303 { 00304 00305 int result; 00306 00307 empty = table->zero; 00308 zddReorderPreprocess(table); 00309 00310 result = zddShuffle(table,permutation); 00311 00312 if (!zddReorderPostprocess(table)) return(0); 00313 00314 return(result); 00315 00316 } /* end of Cudd_zddShuffleHeap */
Function********************************************************************
Synopsis [Computes the negative cofactor of a ZDD w.r.t. a variable.]
Description [Computes the negative cofactor of a ZDD w.r.t. a variable. In terms of combinations, the result is the set of all combinations in which the variable is negated. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddSubset1]
Definition at line 358 of file cuddZddSetop.c.
00362 { 00363 DdNode *r; 00364 00365 do { 00366 dd->reordered = 0; 00367 r = cuddZddSubset0(dd, P, var); 00368 } while (dd->reordered == 1); 00369 00370 return(r); 00371 00372 } /* end of Cudd_zddSubset0 */
Function********************************************************************
Synopsis [Computes the positive cofactor of a ZDD w.r.t. a variable.]
Description [Computes the positive cofactor of a ZDD w.r.t. a variable. In terms of combinations, the result is the set of all combinations in which the variable is asserted. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddSubset0]
Definition at line 326 of file cuddZddSetop.c.
00330 { 00331 DdNode *r; 00332 00333 do { 00334 dd->reordered = 0; 00335 r = cuddZddSubset1(dd, P, var); 00336 } while (dd->reordered == 1); 00337 00338 return(r); 00339 00340 } /* end of Cudd_zddSubset1 */
void Cudd_zddSymmProfile | ( | DdManager * | table, | |
int | lower, | |||
int | upper | |||
) |
AutomaticEnd Function********************************************************************
Synopsis [Prints statistics on symmetric ZDD variables.]
Description []
SideEffects [None]
SeeAlso []
Definition at line 141 of file cuddZddSymm.c.
00145 { 00146 int i, x, gbot; 00147 int TotalSymm = 0; 00148 int TotalSymmGroups = 0; 00149 00150 for (i = lower; i < upper; i++) { 00151 if (table->subtableZ[i].next != (unsigned) i) { 00152 x = i; 00153 (void) fprintf(table->out,"Group:"); 00154 do { 00155 (void) fprintf(table->out," %d", table->invpermZ[x]); 00156 TotalSymm++; 00157 gbot = x; 00158 x = table->subtableZ[x].next; 00159 } while (x != i); 00160 TotalSymmGroups++; 00161 #ifdef DD_DEBUG 00162 assert(table->subtableZ[gbot].next == (unsigned) i); 00163 #endif 00164 i = gbot; 00165 (void) fprintf(table->out,"\n"); 00166 } 00167 } 00168 (void) fprintf(table->out,"Total Symmetric = %d\n", TotalSymm); 00169 (void) fprintf(table->out,"Total Groups = %d\n", TotalSymmGroups); 00170 00171 } /* end of Cudd_zddSymmProfile */
Function********************************************************************
Synopsis [Computes the product of two unate covers.]
Description [Computes the product of two unate covers represented as ZDDs. Unate covers use one ZDD variable for each BDD variable. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_zddProduct]
Definition at line 172 of file cuddZddFuncs.c.
00176 { 00177 DdNode *res; 00178 00179 do { 00180 dd->reordered = 0; 00181 res = cuddZddUnateProduct(dd, f, g); 00182 } while (dd->reordered == 1); 00183 return(res); 00184 00185 } /* end of Cudd_zddUnateProduct */
Function********************************************************************
Synopsis [Computes the union of two ZDDs.]
Description [Computes the union of two ZDDs. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
Definition at line 174 of file cuddZddSetop.c.
00178 { 00179 DdNode *res; 00180 00181 do { 00182 dd->reordered = 0; 00183 res = cuddZddUnion(dd, P, Q); 00184 } while (dd->reordered == 1); 00185 return(res); 00186 00187 } /* end of Cudd_zddUnion */
int Cudd_zddVarsFromBddVars | ( | DdManager * | dd, | |
int | multiplicity | |||
) |
Function********************************************************************
Synopsis [Creates one or more ZDD variables for each BDD variable.]
Description [Creates one or more ZDD variables for each BDD variable. If some ZDD variables already exist, only the missing variables are created. Parameter multiplicity allows the caller to control how many variables are created for each BDD variable in existence. For instance, if ZDDs are used to represent covers, two ZDD variables are required for each BDD variable. The order of the BDD variables is transferred to the ZDD variables. If a variable group tree exists for the BDD variables, a corresponding ZDD variable group tree is created by expanding the BDD variable tree. In any case, the ZDD variables derived from the same BDD variable are merged in a ZDD variable group. If a ZDD variable group tree exists, it is freed. Returns 1 if successful; 0 otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel]
Definition at line 515 of file cuddAPI.c.
00518 { 00519 int res; 00520 int i, j; 00521 int allnew; 00522 int *permutation; 00523 00524 if (multiplicity < 1) return(0); 00525 allnew = dd->sizeZ == 0; 00526 if (dd->size * multiplicity > dd->sizeZ) { 00527 res = cuddResizeTableZdd(dd,dd->size * multiplicity - 1); 00528 if (res == 0) return(0); 00529 } 00530 /* Impose the order of the BDD variables to the ZDD variables. */ 00531 if (allnew) { 00532 for (i = 0; i < dd->size; i++) { 00533 for (j = 0; j < multiplicity; j++) { 00534 dd->permZ[i * multiplicity + j] = 00535 dd->perm[i] * multiplicity + j; 00536 dd->invpermZ[dd->permZ[i * multiplicity + j]] = 00537 i * multiplicity + j; 00538 } 00539 } 00540 for (i = 0; i < dd->sizeZ; i++) { 00541 dd->univ[i]->index = dd->invpermZ[i]; 00542 } 00543 } else { 00544 permutation = ALLOC(int,dd->sizeZ); 00545 if (permutation == NULL) { 00546 dd->errorCode = CUDD_MEMORY_OUT; 00547 return(0); 00548 } 00549 for (i = 0; i < dd->size; i++) { 00550 for (j = 0; j < multiplicity; j++) { 00551 permutation[i * multiplicity + j] = 00552 dd->invperm[i] * multiplicity + j; 00553 } 00554 } 00555 for (i = dd->size * multiplicity; i < dd->sizeZ; i++) { 00556 permutation[i] = i; 00557 } 00558 res = Cudd_zddShuffleHeap(dd, permutation); 00559 FREE(permutation); 00560 if (res == 0) return(0); 00561 } 00562 /* Copy and expand the variable group tree if it exists. */ 00563 if (dd->treeZ != NULL) { 00564 Cudd_FreeZddTree(dd); 00565 } 00566 if (dd->tree != NULL) { 00567 dd->treeZ = Mtr_CopyTree(dd->tree, multiplicity); 00568 if (dd->treeZ == NULL) return(0); 00569 } else if (multiplicity > 1) { 00570 dd->treeZ = Mtr_InitGroupTree(0, dd->sizeZ); 00571 if (dd->treeZ == NULL) return(0); 00572 dd->treeZ->index = dd->invpermZ[0]; 00573 } 00574 /* Create groups for the ZDD variables derived from the same BDD variable. 00575 */ 00576 if (multiplicity > 1) { 00577 char *vmask, *lmask; 00578 00579 vmask = ALLOC(char, dd->size); 00580 if (vmask == NULL) { 00581 dd->errorCode = CUDD_MEMORY_OUT; 00582 return(0); 00583 } 00584 lmask = ALLOC(char, dd->size); 00585 if (lmask == NULL) { 00586 dd->errorCode = CUDD_MEMORY_OUT; 00587 return(0); 00588 } 00589 for (i = 0; i < dd->size; i++) { 00590 vmask[i] = lmask[i] = 0; 00591 } 00592 res = addMultiplicityGroups(dd,dd->treeZ,multiplicity,vmask,lmask); 00593 FREE(vmask); 00594 FREE(lmask); 00595 if (res == 0) return(0); 00596 } 00597 return(1); 00598 00599 } /* end of Cudd_zddVarsFromBddVars */
Function********************************************************************
Synopsis [Applies weak division to two covers.]
Description [Applies weak division to two ZDDs representing two covers. Returns a pointer to the ZDD representing the result if successful; NULL otherwise. The result of weak division depends on the variable order. The covers on which Cudd_zddWeakDiv operates use two ZDD variables for each function variable (one ZDD variable for each literal of the variable). Those two ZDD variables should be adjacent in the order.]
SideEffects [None]
SeeAlso [Cudd_zddDivide]
Definition at line 206 of file cuddZddFuncs.c.
00210 { 00211 DdNode *res; 00212 00213 do { 00214 dd->reordered = 0; 00215 res = cuddZddWeakDiv(dd, f, g); 00216 } while (dd->reordered == 1); 00217 return(res); 00218 00219 } /* end of Cudd_zddWeakDiv */
Function********************************************************************
Synopsis [Modified version of Cudd_zddWeakDiv.]
Description [Modified version of Cudd_zddWeakDiv. This function may disappear in future releases.]
SideEffects [None]
SeeAlso [Cudd_zddWeakDiv]
Definition at line 266 of file cuddZddFuncs.c.
00270 { 00271 DdNode *res; 00272 00273 do { 00274 dd->reordered = 0; 00275 res = cuddZddWeakDivF(dd, f, g); 00276 } while (dd->reordered == 1); 00277 return(res); 00278 00279 } /* end of Cudd_zddWeakDivF */