SVF
Classes | Macros | Typedefs | Functions
cuddInt.h File Reference
#include <math.h>
#include "cudd.h"
#include "st.h"

Go to the source code of this file.

Classes

struct  DdGen
 
struct  DdHook
 
struct  DdLocalCacheItem
 
struct  DdLocalCache
 
struct  DdHashItem
 
struct  DdHashTable
 
struct  DdCache
 
struct  DdSubtable
 
struct  DdManager
 
struct  Move
 
struct  DdQueueItem
 
struct  DdLevelQueue
 

Macros

#define DD_INLINE
 
#define DD_UNUSED
 
#define DD_MAXREF   ((DdHalfWord) ~0)
 
#define DD_DEFAULT_RESIZE   10 /* how many extra variables */
 
#define DD_MEM_CHUNK   1022
 
#define DD_ONE_VAL   (1.0)
 
#define DD_ZERO_VAL   (0.0)
 
#define DD_EPSILON   (1.0e-12)
 
#define DD_PLUS_INF_VAL   (10e301)
 
#define DD_CRI_HI_MARK   (10e150)
 
#define DD_CRI_LO_MARK   (-(DD_CRI_HI_MARK))
 
#define DD_MINUS_INF_VAL   (-(DD_PLUS_INF_VAL))
 
#define DD_NON_CONSTANT   ((DdNode *) 1) /* for Cudd_bddIteConstant */
 
#define DD_MAX_SUBTABLE_DENSITY   4 /* tells when to resize a subtable */
 
#define DD_GC_FRAC_LO   DD_MAX_SUBTABLE_DENSITY * 0.25
 
#define DD_GC_FRAC_HI   DD_MAX_SUBTABLE_DENSITY * 1.0
 
#define DD_GC_FRAC_MIN   0.2
 
#define DD_MIN_HIT
 
#define DD_MAX_LOOSE_FRACTION
 
#define DD_MAX_CACHE_FRACTION
 
#define DD_STASH_FRACTION
 
#define DD_MAX_CACHE_TO_SLOTS_RATIO   4 /* used to limit the cache size */
 
#define DD_SIFT_MAX_VAR   1000
 
#define DD_SIFT_MAX_SWAPS   2000000
 
#define DD_DEFAULT_RECOMB   0
 
#define DD_MAX_REORDER_GROWTH   1.2
 
#define DD_FIRST_REORDER   4004 /* 4 for the constants */
 
#define DD_DYN_RATIO   2 /* when to dynamically reorder */
 
#define DD_P1   12582917
 
#define DD_P2   4256249
 
#define DD_P3   741457
 
#define DD_P4   1618033999
 
#define DD_ADD_ITE_TAG   0x02
 
#define DD_BDD_AND_ABSTRACT_TAG   0x06
 
#define DD_BDD_XOR_EXIST_ABSTRACT_TAG   0x0a
 
#define DD_BDD_ITE_TAG   0x0e
 
#define DD_ADD_BDD_DO_INTERVAL_TAG   0x22
 
#define DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG   0x26
 
#define DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG   0x2a
 
#define DD_BDD_COMPOSE_RECUR_TAG   0x2e
 
#define DD_ADD_COMPOSE_RECUR_TAG   0x42
 
#define DD_ADD_NON_SIM_COMPOSE_TAG   0x46
 
#define DD_EQUIV_DC_TAG   0x4a
 
#define DD_ZDD_ITE_TAG   0x4e
 
#define DD_ADD_ITE_CONSTANT_TAG   0x62
 
#define DD_ADD_EVAL_CONST_TAG   0x66
 
#define DD_BDD_ITE_CONSTANT_TAG   0x6a
 
#define DD_ADD_OUT_SUM_TAG   0x6e
 
#define DD_BDD_LEQ_UNLESS_TAG   0x82
 
#define DD_ADD_TRIANGLE_TAG   0x86
 
#define DD_BDD_MAX_EXP_TAG   0x8a
 
#define CUDD_GEN_CUBES   0
 
#define CUDD_GEN_PRIMES   1
 
#define CUDD_GEN_NODES   2
 
#define CUDD_GEN_ZDD_PATHS   3
 
#define CUDD_GEN_EMPTY   0
 
#define CUDD_GEN_NONEMPTY   1
 
#define cuddDeallocNode(unique, node)
 
#define cuddDeallocMove(unique, node)
 
#define cuddRef(n)   cuddSatInc(Cudd_Regular(n)->ref)
 
#define cuddDeref(n)   cuddSatDec(Cudd_Regular(n)->ref)
 
#define cuddIsConstant(node)   ((node)->index == CUDD_CONST_INDEX)
 
#define cuddT(node)   ((node)->type.kids.T)
 
#define cuddE(node)   ((node)->type.kids.E)
 
#define cuddV(node)   ((node)->type.value)
 
#define cuddI(dd, index)   (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->perm[(index)])
 
#define cuddIZ(dd, index)   (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->permZ[(index)])
 
#define ddHash(f, g, s)   ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s))
 
#define ddCHash(o, f, g, h, s)
 
#define ddCHash2(o, f, g, s)   (((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s))
 
#define cuddClean(p)   ((DdNode *)((ptruint)(p) & ~0xf))
 
#define ddMin(x, y)   (((y) < (x)) ? (y) : (x))
 
#define ddMax(x, y)   (((y) > (x)) ? (y) : (x))
 
#define ddAbs(x)   (((x)<0) ? -(x) : (x))
 
#define ddEqualVal(x, y, e)   (ddAbs((x)-(y))<(e))
 
#define cuddSatInc(x)   ((x) += (x) != (DdHalfWord)DD_MAXREF)
 
#define cuddSatDec(x)   ((x) -= (x) != (DdHalfWord)DD_MAXREF)
 
#define DD_ONE(dd)   ((dd)->one)
 
#define DD_ZERO(dd)   ((dd)->zero)
 
#define DD_PLUS_INFINITY(dd)   ((dd)->plusinfinity)
 
#define DD_MINUS_INFINITY(dd)   ((dd)->minusinfinity)
 
#define cuddAdjust(x)   ((x) = ((x) >= DD_CRI_HI_MARK) ? DD_PLUS_INF_VAL : (((x) <= DD_CRI_LO_MARK) ? DD_MINUS_INF_VAL : (x)))
 
#define DD_LSDIGIT(x)   ((x) & DD_APA_MASK)
 
#define DD_MSDIGIT(x)   ((x) >> DD_APA_BITS)
 
#define statLine(dd)
 

Typedefs

typedef struct DdHook DdHook
 
typedef int ptrint
 
typedef unsigned int ptruint
 
typedef DdNodeDdNodePtr
 
typedef struct DdLocalCacheItem DdLocalCacheItem
 
typedef struct DdLocalCache DdLocalCache
 
typedef struct DdHashItem DdHashItem
 
typedef struct DdHashTable DdHashTable
 
typedef struct DdCache DdCache
 
typedef struct DdSubtable DdSubtable
 
typedef struct Move Move
 
typedef struct DdQueueItem DdQueueItem
 
typedef struct DdLevelQueue DdLevelQueue
 

Functions

DdNodecuddAddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube)
 
DdNodecuddAddUnivAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube)
 
DdNodecuddAddOrAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube)
 
DdNodecuddAddApplyRecur (DdManager *dd, DdNode *(*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g)
 
DdNodecuddAddMonadicApplyRecur (DdManager *dd, DdNode *(*op)(DdManager *, DdNode *), DdNode *f)
 
DdNodecuddAddScalarInverseRecur (DdManager *dd, DdNode *f, DdNode *epsilon)
 
DdNodecuddAddIteRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
 
DdNodecuddAddCmplRecur (DdManager *dd, DdNode *f)
 
DdNodecuddAddNegateRecur (DdManager *dd, DdNode *f)
 
DdNodecuddAddRoundOffRecur (DdManager *dd, DdNode *f, double trunc)
 
DdNodecuddUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality)
 
DdNodecuddRemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality)
 
DdNodecuddBiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0)
 
DdNodecuddBddAndAbstractRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
 
int cuddAnnealing (DdManager *table, int lower, int upper)
 
DdNodecuddBddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube)
 
DdNodecuddBddXorExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
 
DdNodecuddBddBooleanDiffRecur (DdManager *manager, DdNode *f, DdNode *var)
 
DdNodecuddBddIteRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
 
DdNodecuddBddIntersectRecur (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddBddAndRecur (DdManager *manager, DdNode *f, DdNode *g)
 
DdNodecuddBddXorRecur (DdManager *manager, DdNode *f, DdNode *g)
 
DdNodecuddBddTransfer (DdManager *ddS, DdManager *ddD, DdNode *f)
 
DdNodecuddAddBddDoPattern (DdManager *dd, DdNode *f)
 
int cuddInitCache (DdManager *unique, unsigned int cacheSize, unsigned int maxCacheSize)
 
void cuddCacheInsert (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
 
void cuddCacheInsert2 (DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
 
void cuddCacheInsert1 (DdManager *table, DdNode *(*)(DdManager *, DdNode *), DdNode *f, DdNode *data)
 
DdNodecuddCacheLookup (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
 
DdNodecuddCacheLookupZdd (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
 
DdNodecuddCacheLookup2 (DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
 
DdNodecuddCacheLookup1 (DdManager *table, DdNode *(*)(DdManager *, DdNode *), DdNode *f)
 
DdNodecuddCacheLookup2Zdd (DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
 
DdNodecuddCacheLookup1Zdd (DdManager *table, DdNode *(*)(DdManager *, DdNode *), DdNode *f)
 
DdNodecuddConstantLookup (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
 
int cuddCacheProfile (DdManager *table, FILE *fp)
 
void cuddCacheResize (DdManager *table)
 
void cuddCacheFlush (DdManager *table)
 
int cuddComputeFloorLog2 (unsigned int value)
 
int cuddHeapProfile (DdManager *dd)
 
void cuddPrintNode (DdNode *f, FILE *fp)
 
void cuddPrintVarGroups (DdManager *dd, MtrNode *root, int zdd, int silent)
 
DdNodecuddBddClippingAnd (DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction)
 
DdNodecuddBddClippingAndAbstract (DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction)
 
void cuddGetBranches (DdNode *g, DdNode **g1, DdNode **g0)
 
DdNodecuddCofactorRecur (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddBddComposeRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *proj)
 
DdNodecuddAddComposeRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *proj)
 
int cuddExact (DdManager *table, int lower, int upper)
 
DdNodecuddBddConstrainRecur (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodecuddBddRestrictRecur (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodecuddBddNPAndRecur (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodecuddAddConstrainRecur (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodecuddAddRestrictRecur (DdManager *dd, DdNode *f, DdNode *c)
 
DdNodecuddBddLICompaction (DdManager *dd, DdNode *f, DdNode *c)
 
int cuddGa (DdManager *table, int lower, int upper)
 
int cuddTreeSifting (DdManager *table, Cudd_ReorderingType method)
 
int cuddZddInitUniv (DdManager *zdd)
 
void cuddZddFreeUniv (DdManager *zdd)
 
void cuddSetInteract (DdManager *table, int x, int y)
 
int cuddTestInteract (DdManager *table, int x, int y)
 
int cuddInitInteract (DdManager *table)
 
DdLocalCachecuddLocalCacheInit (DdManager *manager, unsigned int keySize, unsigned int cacheSize, unsigned int maxCacheSize)
 
void cuddLocalCacheQuit (DdLocalCache *cache)
 
void cuddLocalCacheInsert (DdLocalCache *cache, DdNodePtr *key, DdNode *value)
 
DdNodecuddLocalCacheLookup (DdLocalCache *cache, DdNodePtr *key)
 
void cuddLocalCacheClearDead (DdManager *manager)
 
int cuddIsInDeathRow (DdManager *dd, DdNode *f)
 
int cuddTimesInDeathRow (DdManager *dd, DdNode *f)
 
void cuddLocalCacheClearAll (DdManager *manager)
 
DdHashTablecuddHashTableInit (DdManager *manager, unsigned int keySize, unsigned int initSize)
 
void cuddHashTableQuit (DdHashTable *hash)
 
void cuddHashTableGenericQuit (DdHashTable *hash)
 
int cuddHashTableInsert (DdHashTable *hash, DdNodePtr *key, DdNode *value, ptrint count)
 
DdNodecuddHashTableLookup (DdHashTable *hash, DdNodePtr *key)
 
int cuddHashTableInsert1 (DdHashTable *hash, DdNode *f, DdNode *value, ptrint count)
 
DdNodecuddHashTableLookup1 (DdHashTable *hash, DdNode *f)
 
int cuddHashTableInsert2 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *value, ptrint count)
 
DdNodecuddHashTableLookup2 (DdHashTable *hash, DdNode *f, DdNode *g)
 
int cuddHashTableInsert3 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h, DdNode *value, ptrint count)
 
DdNodecuddHashTableLookup3 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h)
 
int cuddHashTableGenericInsert (DdHashTable *hash, DdNode *f, void *value)
 
void * cuddHashTableGenericLookup (DdHashTable *hash, DdNode *f)
 
DdLevelQueuecuddLevelQueueInit (int levels, int itemSize, int numBuckets)
 
void cuddLevelQueueQuit (DdLevelQueue *queue)
 
void * cuddLevelQueueFirst (DdLevelQueue *queue, void *key, int level)
 
void * cuddLevelQueueEnqueue (DdLevelQueue *queue, void *key, int level)
 
void cuddLevelQueueDequeue (DdLevelQueue *queue, int level)
 
int cuddLinearAndSifting (DdManager *table, int lower, int upper)
 
int cuddLinearInPlace (DdManager *table, int x, int y)
 
void cuddUpdateInteractionMatrix (DdManager *table, int xindex, int yindex)
 
int cuddInitLinear (DdManager *table)
 
int cuddResizeLinear (DdManager *table)
 
DdNodecuddBddLiteralSetIntersectionRecur (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddCProjectionRecur (DdManager *dd, DdNode *R, DdNode *Y, DdNode *Ysupp)
 
DdNodecuddBddClosestCube (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE bound)
 
void cuddReclaim (DdManager *table, DdNode *n)
 
void cuddReclaimZdd (DdManager *table, DdNode *n)
 
void cuddClearDeathRow (DdManager *table)
 
void cuddShrinkDeathRow (DdManager *table)
 
DdNodecuddDynamicAllocNode (DdManager *table)
 
int cuddSifting (DdManager *table, int lower, int upper)
 
int cuddSwapping (DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)
 
int cuddNextHigh (DdManager *table, int x)
 
int cuddNextLow (DdManager *table, int x)
 
int cuddSwapInPlace (DdManager *table, int x, int y)
 
int cuddBddAlignToZdd (DdManager *table)
 
DdNodecuddBddMakePrime (DdManager *dd, DdNode *cube, DdNode *f)
 
DdNodecuddSolveEqnRecur (DdManager *bdd, DdNode *F, DdNode *Y, DdNode **G, int n, int *yIndex, int i)
 
DdNodecuddVerifySol (DdManager *bdd, DdNode *F, DdNode **G, int *yIndex, int n)
 
DdNodecuddSplitSetRecur (DdManager *manager, st_table *mtable, int *varSeen, DdNode *p, double n, double max, int index)
 
DdNodecuddSubsetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold)
 
DdNodecuddSubsetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)
 
int cuddSymmCheck (DdManager *table, int x, int y)
 
int cuddSymmSifting (DdManager *table, int lower, int upper)
 
int cuddSymmSiftingConv (DdManager *table, int lower, int upper)
 
DdNodecuddAllocNode (DdManager *unique)
 
DdManagercuddInitTable (unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int looseUpTo)
 
void cuddFreeTable (DdManager *unique)
 
int cuddGarbageCollect (DdManager *unique, int clearCache)
 
DdNodecuddZddGetNode (DdManager *zdd, int id, DdNode *T, DdNode *E)
 
DdNodecuddZddGetNodeIVO (DdManager *dd, int index, DdNode *g, DdNode *h)
 
DdNodecuddUniqueInter (DdManager *unique, int index, DdNode *T, DdNode *E)
 
DdNodecuddUniqueInterIVO (DdManager *unique, int index, DdNode *T, DdNode *E)
 
DdNodecuddUniqueInterZdd (DdManager *unique, int index, DdNode *T, DdNode *E)
 
DdNodecuddUniqueConst (DdManager *unique, CUDD_VALUE_TYPE value)
 
void cuddRehash (DdManager *unique, int i)
 
void cuddShrinkSubtable (DdManager *unique, int i)
 
int cuddInsertSubtables (DdManager *unique, int n, int level)
 
int cuddDestroySubtables (DdManager *unique, int n)
 
int cuddResizeTableZdd (DdManager *unique, int index)
 
void cuddSlowTableGrowth (DdManager *unique)
 
int cuddP (DdManager *dd, DdNode *f)
 
enum st_retval cuddStCountfree (char *key, char *value, char *arg)
 
int cuddCollectNodes (DdNode *f, st_table *visited)
 
DdNodePtrcuddNodeArray (DdNode *f, int *n)
 
int cuddWindowReorder (DdManager *table, int low, int high, Cudd_ReorderingType submethod)
 
DdNodecuddZddProduct (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddZddUnateProduct (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddZddWeakDiv (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddZddWeakDivF (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddZddDivide (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddZddDivideF (DdManager *dd, DdNode *f, DdNode *g)
 
int cuddZddGetCofactors3 (DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)
 
int cuddZddGetCofactors2 (DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0)
 
DdNodecuddZddComplement (DdManager *dd, DdNode *node)
 
int cuddZddGetPosVarIndex (DdManager *dd, int index)
 
int cuddZddGetNegVarIndex (DdManager *dd, int index)
 
int cuddZddGetPosVarLevel (DdManager *dd, int index)
 
int cuddZddGetNegVarLevel (DdManager *dd, int index)
 
int cuddZddTreeSifting (DdManager *table, Cudd_ReorderingType method)
 
DdNodecuddZddIsop (DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)
 
DdNodecuddBddIsop (DdManager *dd, DdNode *L, DdNode *U)
 
DdNodecuddMakeBddFromZddCover (DdManager *dd, DdNode *node)
 
int cuddZddLinearSifting (DdManager *table, int lower, int upper)
 
int cuddZddAlignToBdd (DdManager *table)
 
int cuddZddNextHigh (DdManager *table, int x)
 
int cuddZddNextLow (DdManager *table, int x)
 
int cuddZddUniqueCompare (int *ptr_x, int *ptr_y)
 
int cuddZddSwapInPlace (DdManager *table, int x, int y)
 
int cuddZddSwapping (DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)
 
int cuddZddSifting (DdManager *table, int lower, int upper)
 
DdNodecuddZddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
 
DdNodecuddZddUnion (DdManager *zdd, DdNode *P, DdNode *Q)
 
DdNodecuddZddIntersect (DdManager *zdd, DdNode *P, DdNode *Q)
 
DdNodecuddZddDiff (DdManager *zdd, DdNode *P, DdNode *Q)
 
DdNodecuddZddChangeAux (DdManager *zdd, DdNode *P, DdNode *zvar)
 
DdNodecuddZddSubset1 (DdManager *dd, DdNode *P, int var)
 
DdNodecuddZddSubset0 (DdManager *dd, DdNode *P, int var)
 
DdNodecuddZddChange (DdManager *dd, DdNode *P, int var)
 
int cuddZddSymmCheck (DdManager *table, int x, int y)
 
int cuddZddSymmSifting (DdManager *table, int lower, int upper)
 
int cuddZddSymmSiftingConv (DdManager *table, int lower, int upper)
 
int cuddZddP (DdManager *zdd, DdNode *f)
 

Macro Definition Documentation

◆ CUDD_GEN_CUBES

#define CUDD_GEN_CUBES   0

Definition at line 194 of file cuddInt.h.

◆ CUDD_GEN_EMPTY

#define CUDD_GEN_EMPTY   0

Definition at line 198 of file cuddInt.h.

◆ CUDD_GEN_NODES

#define CUDD_GEN_NODES   2

Definition at line 196 of file cuddInt.h.

◆ CUDD_GEN_NONEMPTY

#define CUDD_GEN_NONEMPTY   1

Definition at line 199 of file cuddInt.h.

◆ CUDD_GEN_PRIMES

#define CUDD_GEN_PRIMES   1

Definition at line 195 of file cuddInt.h.

◆ CUDD_GEN_ZDD_PATHS

#define CUDD_GEN_ZDD_PATHS   3

Definition at line 197 of file cuddInt.h.

◆ cuddAdjust

#define cuddAdjust (   x)    ((x) = ((x) >= DD_CRI_HI_MARK) ? DD_PLUS_INF_VAL : (((x) <= DD_CRI_LO_MARK) ? DD_MINUS_INF_VAL : (x)))

Macro***********************************************************************

Synopsis [Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL.]

Description [Enforces DD_MINUS_INF_VAL <= x <= DD_PLUS_INF_VAL. Furthermore, if x <= DD_MINUS_INF_VAL/2, x is set to DD_MINUS_INF_VAL. Similarly, if DD_PLUS_INF_VAL/2 <= x, x is set to DD_PLUS_INF_VAL. Normally this macro is a NOOP. However, if HAVE_IEEE_754 is not defined, it makes sure that a value does not get larger than infinity in absolute value, and once it gets to infinity, stays there. If the value overflows before this macro is applied, no recovery is possible.]

SideEffects [none]

SeeAlso []

Definition at line 932 of file cuddInt.h.

◆ cuddClean

#define cuddClean (   p)    ((DdNode *)((ptruint)(p) & ~0xf))

Macro***********************************************************************

Synopsis [Clears the 4 least significant bits of a pointer.]

Description []

SideEffects [none]

SeeAlso []

Definition at line 757 of file cuddInt.h.

◆ cuddDeallocMove

#define cuddDeallocMove (   unique,
  node 
)
Value:
((DdNode *)(node))->ref = 0; \
((DdNode *)(node))->next = (unique)->nextFree; \
(unique)->nextFree = (DdNode *)(node);
Definition: cudd.h:270

Macro***********************************************************************

Synopsis [Adds node to the head of the free list.]

Description [Adds node to the head of the free list. Does not deallocate memory chunks that become free. This function is also used by the dynamic reordering functions.]

SideEffects [None]

SeeAlso [cuddDeallocNode cuddDynamicAllocNode]

Definition at line 537 of file cuddInt.h.

◆ cuddDeallocNode

#define cuddDeallocNode (   unique,
  node 
)
Value:
(node)->next = (unique)->nextFree; \
(unique)->nextFree = node;

Macro***********************************************************************

Synopsis [Adds node to the head of the free list.]

Description [Adds node to the head of the free list. Does not deallocate memory chunks that become free. This function is also used by the dynamic reordering functions.]

SideEffects [None]

SeeAlso [cuddAllocNode cuddDynamicAllocNode cuddDeallocMove]

Definition at line 520 of file cuddInt.h.

◆ cuddDeref

#define cuddDeref (   n)    cuddSatDec(Cudd_Regular(n)->ref)

Macro***********************************************************************

Synopsis [Decreases the reference count of a node, if it is not saturated.]

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 cuddRef. This being a macro, it is faster than Cudd_Deref, but it cannot be used in constructs like cuddDeref(a = b()).]

SideEffects [none]

SeeAlso [Cudd_Deref]

Definition at line 577 of file cuddInt.h.

◆ cuddE

#define cuddE (   node)    ((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. The pointer passed to cuddE must be regular.]

SideEffects [none]

SeeAlso [Cudd_E]

Definition at line 625 of file cuddInt.h.

◆ cuddI

#define cuddI (   dd,
  index 
)    (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->perm[(index)])

Macro***********************************************************************

Synopsis [Finds the current position of variable index in the order.]

Description [Finds the current position of variable index in the order. This macro duplicates the functionality of Cudd_ReadPerm, but it does not check for out-of-bounds indices and it is more efficient.]

SideEffects [none]

SeeAlso [Cudd_ReadPerm]

Definition at line 659 of file cuddInt.h.

◆ cuddIsConstant

#define cuddIsConstant (   node)    ((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 cuddIsConstant must be regular.]

SideEffects [none]

SeeAlso [Cudd_IsConstant]

Definition at line 593 of file cuddInt.h.

◆ cuddIZ

#define cuddIZ (   dd,
  index 
)    (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->permZ[(index)])

Macro***********************************************************************

Synopsis [Finds the current position of ZDD variable index in the order.]

Description [Finds the current position of ZDD variable index in the order. This macro duplicates the functionality of Cudd_ReadPermZdd, but it does not check for out-of-bounds indices and it is more efficient.]

SideEffects [none]

SeeAlso [Cudd_ReadPermZdd]

Definition at line 677 of file cuddInt.h.

◆ cuddRef

#define cuddRef (   n)    cuddSatInc(Cudd_Regular(n)->ref)

Macro***********************************************************************

Synopsis [Increases the reference count of a node, if it is not saturated.]

Description [Increases the reference count of a node, if it is not saturated. This being a macro, it is faster than Cudd_Ref, but it cannot be used in constructs like cuddRef(a = b()).]

SideEffects [none]

SeeAlso [Cudd_Ref]

Definition at line 557 of file cuddInt.h.

◆ cuddSatDec

#define cuddSatDec (   x)    ((x) -= (x) != (DdHalfWord)DD_MAXREF)

Macro***********************************************************************

Synopsis [Saturating decrement operator.]

Description []

SideEffects [none]

SeeAlso [cuddSatInc]

Definition at line 849 of file cuddInt.h.

◆ cuddSatInc

#define cuddSatInc (   x)    ((x) += (x) != (DdHalfWord)DD_MAXREF)

Macro***********************************************************************

Synopsis [Saturating increment operator.]

Description []

SideEffects [none]

SeeAlso [cuddSatDec]

Definition at line 831 of file cuddInt.h.

◆ cuddT

#define cuddT (   node)    ((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. The pointer passed to cuddT must be regular.]

SideEffects [none]

SeeAlso [Cudd_T]

Definition at line 609 of file cuddInt.h.

◆ cuddV

#define cuddV (   node)    ((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. The pointer passed to cuddV must be regular.]

SideEffects [none]

SeeAlso [Cudd_V]

Definition at line 641 of file cuddInt.h.

◆ DD_ADD_BDD_DO_INTERVAL_TAG

#define DD_ADD_BDD_DO_INTERVAL_TAG   0x22

Definition at line 177 of file cuddInt.h.

◆ DD_ADD_COMPOSE_RECUR_TAG

#define DD_ADD_COMPOSE_RECUR_TAG   0x42

Definition at line 181 of file cuddInt.h.

◆ DD_ADD_EVAL_CONST_TAG

#define DD_ADD_EVAL_CONST_TAG   0x66

Definition at line 186 of file cuddInt.h.

◆ DD_ADD_ITE_CONSTANT_TAG

#define DD_ADD_ITE_CONSTANT_TAG   0x62

Definition at line 185 of file cuddInt.h.

◆ DD_ADD_ITE_TAG

#define DD_ADD_ITE_TAG   0x02

Definition at line 173 of file cuddInt.h.

◆ DD_ADD_NON_SIM_COMPOSE_TAG

#define DD_ADD_NON_SIM_COMPOSE_TAG   0x46

Definition at line 182 of file cuddInt.h.

◆ DD_ADD_OUT_SUM_TAG

#define DD_ADD_OUT_SUM_TAG   0x6e

Definition at line 188 of file cuddInt.h.

◆ DD_ADD_TRIANGLE_TAG

#define DD_ADD_TRIANGLE_TAG   0x86

Definition at line 190 of file cuddInt.h.

◆ DD_BDD_AND_ABSTRACT_TAG

#define DD_BDD_AND_ABSTRACT_TAG   0x06

Definition at line 174 of file cuddInt.h.

◆ DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG

#define DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG   0x2a

Definition at line 179 of file cuddInt.h.

◆ DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG

#define DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG   0x26

Definition at line 178 of file cuddInt.h.

◆ DD_BDD_COMPOSE_RECUR_TAG

#define DD_BDD_COMPOSE_RECUR_TAG   0x2e

Definition at line 180 of file cuddInt.h.

◆ DD_BDD_ITE_CONSTANT_TAG

#define DD_BDD_ITE_CONSTANT_TAG   0x6a

Definition at line 187 of file cuddInt.h.

◆ DD_BDD_ITE_TAG

#define DD_BDD_ITE_TAG   0x0e

Definition at line 176 of file cuddInt.h.

◆ DD_BDD_LEQ_UNLESS_TAG

#define DD_BDD_LEQ_UNLESS_TAG   0x82

Definition at line 189 of file cuddInt.h.

◆ DD_BDD_MAX_EXP_TAG

#define DD_BDD_MAX_EXP_TAG   0x8a

Definition at line 191 of file cuddInt.h.

◆ DD_BDD_XOR_EXIST_ABSTRACT_TAG

#define DD_BDD_XOR_EXIST_ABSTRACT_TAG   0x0a

Definition at line 175 of file cuddInt.h.

◆ DD_CRI_HI_MARK

#define DD_CRI_HI_MARK   (10e150)

Definition at line 119 of file cuddInt.h.

◆ DD_CRI_LO_MARK

#define DD_CRI_LO_MARK   (-(DD_CRI_HI_MARK))

Definition at line 120 of file cuddInt.h.

◆ DD_DEFAULT_RECOMB

#define DD_DEFAULT_RECOMB   0

Definition at line 150 of file cuddInt.h.

◆ DD_DEFAULT_RESIZE

#define DD_DEFAULT_RESIZE   10 /* how many extra variables */

Definition at line 103 of file cuddInt.h.

◆ DD_DYN_RATIO

#define DD_DYN_RATIO   2 /* when to dynamically reorder */

Definition at line 153 of file cuddInt.h.

◆ DD_EPSILON

#define DD_EPSILON   (1.0e-12)

Definition at line 110 of file cuddInt.h.

◆ DD_EQUIV_DC_TAG

#define DD_EQUIV_DC_TAG   0x4a

Definition at line 183 of file cuddInt.h.

◆ DD_FIRST_REORDER

#define DD_FIRST_REORDER   4004 /* 4 for the constants */

Definition at line 152 of file cuddInt.h.

◆ DD_GC_FRAC_HI

#define DD_GC_FRAC_HI   DD_MAX_SUBTABLE_DENSITY * 1.0

Definition at line 135 of file cuddInt.h.

◆ DD_GC_FRAC_LO

#define DD_GC_FRAC_LO   DD_MAX_SUBTABLE_DENSITY * 0.25

Definition at line 134 of file cuddInt.h.

◆ DD_GC_FRAC_MIN

#define DD_GC_FRAC_MIN   0.2

Definition at line 136 of file cuddInt.h.

◆ DD_INLINE

#define DD_INLINE

CHeaderFile*****************************************************************

FileName [cuddInt.h]

PackageName [cudd]

Synopsis [Internal data structures of the CUDD package.]

Description []

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, 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 [

Id
cuddInt.h,v 1.142 2012/02/05 01:07:19 fabio Exp

]

Definition at line 91 of file cuddInt.h.

◆ DD_LSDIGIT

#define DD_LSDIGIT (   x)    ((x) & DD_APA_MASK)

Macro***********************************************************************

Synopsis [Extract the least significant digit of a double digit.]

Description [Extract the least significant digit of a double digit. Used in the manipulation of arbitrary precision integers.]

SideEffects [None]

SeeAlso [DD_MSDIGIT]

Definition at line 948 of file cuddInt.h.

◆ DD_MAX_CACHE_FRACTION

#define DD_MAX_CACHE_FRACTION
Value:
3 /* 1 / (max fraction of memory used for
computed table if resizing enabled) */

Definition at line 141 of file cuddInt.h.

◆ DD_MAX_CACHE_TO_SLOTS_RATIO

#define DD_MAX_CACHE_TO_SLOTS_RATIO   4 /* used to limit the cache size */

Definition at line 145 of file cuddInt.h.

◆ DD_MAX_LOOSE_FRACTION

#define DD_MAX_LOOSE_FRACTION
Value:
5 /* 1 / (max fraction of memory used for
unique table in fast growth mode) */

Definition at line 139 of file cuddInt.h.

◆ DD_MAX_REORDER_GROWTH

#define DD_MAX_REORDER_GROWTH   1.2

Definition at line 151 of file cuddInt.h.

◆ DD_MAX_SUBTABLE_DENSITY

#define DD_MAX_SUBTABLE_DENSITY   4 /* tells when to resize a subtable */

Definition at line 127 of file cuddInt.h.

◆ DD_MAXREF

#define DD_MAXREF   ((DdHalfWord) ~0)

Definition at line 101 of file cuddInt.h.

◆ DD_MEM_CHUNK

#define DD_MEM_CHUNK   1022

Definition at line 105 of file cuddInt.h.

◆ DD_MIN_HIT

#define DD_MIN_HIT
Value:
30 /* resize cache when hit ratio
above this percentage (default) */

Definition at line 137 of file cuddInt.h.

◆ DD_MINUS_INF_VAL

#define DD_MINUS_INF_VAL   (-(DD_PLUS_INF_VAL))

Definition at line 122 of file cuddInt.h.

◆ DD_MINUS_INFINITY

#define DD_MINUS_INFINITY (   dd)    ((dd)->minusinfinity)

Macro***********************************************************************

Synopsis [Returns the minus infinity constant node.]

Description []

SideEffects [none]

SeeAlso [DD_ONE DD_ZERO DD_PLUS_INFINITY]

Definition at line 908 of file cuddInt.h.

◆ DD_MSDIGIT

#define DD_MSDIGIT (   x)    ((x) >> DD_APA_BITS)

Macro***********************************************************************

Synopsis [Extract the most significant digit of a double digit.]

Description [Extract the most significant digit of a double digit. Used in the manipulation of arbitrary precision integers.]

SideEffects [None]

SeeAlso [DD_LSDIGIT]

Definition at line 963 of file cuddInt.h.

◆ DD_NON_CONSTANT

#define DD_NON_CONSTANT   ((DdNode *) 1) /* for Cudd_bddIteConstant */

Definition at line 124 of file cuddInt.h.

◆ DD_ONE

#define DD_ONE (   dd)    ((dd)->one)

Macro***********************************************************************

Synopsis [Returns the constant 1 node.]

Description []

SideEffects [none]

SeeAlso [DD_ZERO DD_PLUS_INFINITY DD_MINUS_INFINITY]

Definition at line 864 of file cuddInt.h.

◆ DD_ONE_VAL

#define DD_ONE_VAL   (1.0)

Definition at line 108 of file cuddInt.h.

◆ DD_P1

#define DD_P1   12582917

Definition at line 156 of file cuddInt.h.

◆ DD_P2

#define DD_P2   4256249

Definition at line 157 of file cuddInt.h.

◆ DD_P3

#define DD_P3   741457

Definition at line 158 of file cuddInt.h.

◆ DD_P4

#define DD_P4   1618033999

Definition at line 159 of file cuddInt.h.

◆ DD_PLUS_INF_VAL

#define DD_PLUS_INF_VAL   (10e301)

Definition at line 118 of file cuddInt.h.

◆ DD_PLUS_INFINITY

#define DD_PLUS_INFINITY (   dd)    ((dd)->plusinfinity)

Macro***********************************************************************

Synopsis [Returns the plus infinity constant node.]

Description []

SideEffects [none]

SeeAlso [DD_ONE DD_ZERO DD_MINUS_INFINITY]

Definition at line 894 of file cuddInt.h.

◆ DD_SIFT_MAX_SWAPS

#define DD_SIFT_MAX_SWAPS   2000000

Definition at line 149 of file cuddInt.h.

◆ DD_SIFT_MAX_VAR

#define DD_SIFT_MAX_VAR   1000

Definition at line 148 of file cuddInt.h.

◆ DD_STASH_FRACTION

#define DD_STASH_FRACTION
Value:
64 /* 1 / (fraction of memory set
aside for emergencies) */

Definition at line 143 of file cuddInt.h.

◆ DD_UNUSED

#define DD_UNUSED

Definition at line 93 of file cuddInt.h.

◆ DD_ZDD_ITE_TAG

#define DD_ZDD_ITE_TAG   0x4e

Definition at line 184 of file cuddInt.h.

◆ DD_ZERO

#define DD_ZERO (   dd)    ((dd)->zero)

Macro***********************************************************************

Synopsis [Returns the arithmetic 0 constant node.]

Description [Returns the arithmetic 0 constant node. This is different from the logical zero. The latter is obtained by Cudd_Not(DD_ONE(dd)).]

SideEffects [none]

SeeAlso [DD_ONE Cudd_Not DD_PLUS_INFINITY DD_MINUS_INFINITY]

Definition at line 880 of file cuddInt.h.

◆ DD_ZERO_VAL

#define DD_ZERO_VAL   (0.0)

Definition at line 109 of file cuddInt.h.

◆ ddAbs

#define ddAbs (   x)    (((x)<0) ? -(x) : (x))

Macro***********************************************************************

Synopsis [Computes the absolute value of a number.]

Description []

SideEffects [none]

SeeAlso []

Definition at line 799 of file cuddInt.h.

◆ ddCHash

#define ddCHash (   o,
  f,
  g,
  h,
 
)
Value:
((((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2 + \
(unsigned)(h)) * DD_P3) >> (s))
#define DD_P3
Definition: cuddInt.h:158
#define DD_P2
Definition: cuddInt.h:157
#define DD_P1
Definition: cuddInt.h:156

Macro***********************************************************************

Synopsis [Hash function for the cache.]

Description []

SideEffects [none]

SeeAlso [ddHash ddCHash2]

Definition at line 718 of file cuddInt.h.

◆ ddCHash2

#define ddCHash2 (   o,
  f,
  g,
 
)    (((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s))

Macro***********************************************************************

Synopsis [Hash function for the cache for functions with two operands.]

Description []

SideEffects [none]

SeeAlso [ddHash ddCHash]

Definition at line 741 of file cuddInt.h.

◆ ddEqualVal

#define ddEqualVal (   x,
  y,
 
)    (ddAbs((x)-(y))<(e))

Macro***********************************************************************

Synopsis [Returns 1 if the absolute value of the difference of the two arguments x and y is less than e.]

Description []

SideEffects [none]

SeeAlso []

Definition at line 814 of file cuddInt.h.

◆ ddHash

#define ddHash (   f,
  g,
 
)    ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s))

Macro***********************************************************************

Synopsis [Hash function for the unique table.]

Description []

SideEffects [none]

SeeAlso [ddCHash ddCHash2]

Definition at line 696 of file cuddInt.h.

◆ ddMax

#define ddMax (   x,
 
)    (((y) > (x)) ? (y) : (x))

Macro***********************************************************************

Synopsis [Computes the maximum of two numbers.]

Description []

SideEffects [none]

SeeAlso [ddMin]

Definition at line 785 of file cuddInt.h.

◆ ddMin

#define ddMin (   x,
 
)    (((y) < (x)) ? (y) : (x))

Macro***********************************************************************

Synopsis [Computes the minimum of two numbers.]

Description []

SideEffects [none]

SeeAlso [ddMax]

Definition at line 771 of file cuddInt.h.

◆ statLine

#define statLine (   dd)

Macro***********************************************************************

Synopsis [Outputs a line of stats.]

Description [Outputs a line of stats if DD_COUNT and DD_STATS are defined. Increments the number of recursive calls if DD_COUNT is defined.]

SideEffects [None]

SeeAlso []

Definition at line 990 of file cuddInt.h.

Typedef Documentation

◆ DdCache

typedef struct DdCache DdCache

◆ DdHashItem

typedef struct DdHashItem DdHashItem

◆ DdHashTable

typedef struct DdHashTable DdHashTable

◆ DdHook

typedef struct DdHook DdHook

◆ DdLevelQueue

typedef struct DdLevelQueue DdLevelQueue

◆ DdLocalCache

typedef struct DdLocalCache DdLocalCache

◆ DdLocalCacheItem

◆ DdNodePtr

typedef DdNode* DdNodePtr

Definition at line 253 of file cuddInt.h.

◆ DdQueueItem

typedef struct DdQueueItem DdQueueItem

◆ DdSubtable

typedef struct DdSubtable DdSubtable

◆ Move

typedef struct Move Move

◆ ptrint

typedef int ptrint

Definition at line 249 of file cuddInt.h.

◆ ptruint

typedef unsigned int ptruint

Definition at line 250 of file cuddInt.h.

Function Documentation

◆ cuddAddApplyRecur()

DdNode* cuddAddApplyRecur ( DdManager dd,
DdNode *)(DdManager *, DdNode **, DdNode **,
DdNode f,
DdNode g 
)

◆ cuddAddBddDoPattern()

DdNode* cuddAddBddDoPattern ( DdManager dd,
DdNode f 
)

◆ cuddAddCmplRecur()

DdNode* cuddAddCmplRecur ( DdManager dd,
DdNode f 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_addCmpl.]

Description [Performs the recursive step of Cudd_addCmpl. Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addCmpl]

Definition at line 558 of file cuddAddIte.c.

561 {
562  DdNode *one,*zero;
563  DdNode *r,*Fv,*Fnv,*t,*e;
564 
565  statLine(dd);
566  one = DD_ONE(dd);
567  zero = DD_ZERO(dd);
568 
569  if (cuddIsConstant(f)) {
570  if (f == zero) {
571  return(one);
572  } else {
573  return(zero);
574  }
575  }
576  r = cuddCacheLookup1(dd,Cudd_addCmpl,f);
577  if (r != NULL) {
578  return(r);
579  }
580  Fv = cuddT(f);
581  Fnv = cuddE(f);
582  t = cuddAddCmplRecur(dd,Fv);
583  if (t == NULL) return(NULL);
584  cuddRef(t);
585  e = cuddAddCmplRecur(dd,Fnv);
586  if (e == NULL) {
587  Cudd_RecursiveDeref(dd,t);
588  return(NULL);
589  }
590  cuddRef(e);
591  r = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e);
592  if (r == NULL) {
593  Cudd_RecursiveDeref(dd, t);
594  Cudd_RecursiveDeref(dd, e);
595  return(NULL);
596  }
597  cuddDeref(t);
598  cuddDeref(e);
600  return(r);
601 
602 } /* end of cuddAddCmplRecur */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
DdNode * cuddCacheLookup1(DdManager *table, DdNode *(*)(DdManager *, DdNode *), DdNode *f)
DdNode * Cudd_addCmpl(DdManager *dd, DdNode *f)
Definition: cuddAddIte.c:343
void cuddCacheInsert1(DdManager *table, DdNode *(*)(DdManager *, DdNode *), DdNode *f, DdNode *data)
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137
DdNode * cuddAddCmplRecur(DdManager *dd, DdNode *f)
Definition: cuddAddIte.c:558
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddAddComposeRecur()

DdNode* cuddAddComposeRecur ( DdManager dd,
DdNode f,
DdNode g,
DdNode proj 
)

◆ cuddAddConstrainRecur()

DdNode* cuddAddConstrainRecur ( DdManager dd,
DdNode f,
DdNode c 
)

◆ cuddAddExistAbstractRecur()

DdNode* cuddAddExistAbstractRecur ( DdManager manager,
DdNode f,
DdNode cube 
)

AutomaticStart

◆ cuddAddIteRecur()

DdNode* cuddAddIteRecur ( DdManager dd,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Implements the recursive step of Cudd_addIte(f,g,h).]

Description [Implements the recursive step of Cudd_addIte(f,g,h). Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addIte]

Definition at line 441 of file cuddAddIte.c.

446 {
447  DdNode *one,*zero;
448  DdNode *r,*Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*t,*e;
449  unsigned int topf,topg,toph,v;
450  int index;
451 
452  statLine(dd);
453  /* Trivial cases. */
454 
455  /* One variable cases. */
456  if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */
457  return(g);
458  }
459  if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
460  return(h);
461  }
462 
463  /* From now on, f is known to not be a constant. */
464  addVarToConst(f,&g,&h,one,zero);
465 
466  /* Check remaining one variable cases. */
467  if (g == h) { /* ITE(F,G,G) = G */
468  return(g);
469  }
470 
471  if (g == one) { /* ITE(F,1,0) = F */
472  if (h == zero) return(f);
473  }
474 
475  topf = cuddI(dd,f->index);
476  topg = cuddI(dd,g->index);
477  toph = cuddI(dd,h->index);
478  v = ddMin(topg,toph);
479 
480  /* A shortcut: ITE(F,G,H) = (x,G,H) if F=(x,1,0), x < top(G,H). */
481  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
482  r = cuddUniqueInter(dd,(int)f->index,g,h);
483  return(r);
484  }
485  if (topf < v && cuddT(f) == zero && cuddE(f) == one) {
486  r = cuddUniqueInter(dd,(int)f->index,h,g);
487  return(r);
488  }
489 
490  /* Check cache. */
491  r = cuddCacheLookup(dd,DD_ADD_ITE_TAG,f,g,h);
492  if (r != NULL) {
493  return(r);
494  }
495 
496  /* Compute cofactors. */
497  if (topf <= v) {
498  v = ddMin(topf,v); /* v = top_var(F,G,H) */
499  index = f->index;
500  Fv = cuddT(f); Fnv = cuddE(f);
501  } else {
502  Fv = Fnv = f;
503  }
504  if (topg == v) {
505  index = g->index;
506  Gv = cuddT(g); Gnv = cuddE(g);
507  } else {
508  Gv = Gnv = g;
509  }
510  if (toph == v) {
511  index = h->index;
512  Hv = cuddT(h); Hnv = cuddE(h);
513  } else {
514  Hv = Hnv = h;
515  }
516 
517  /* Recursive step. */
518  t = cuddAddIteRecur(dd,Fv,Gv,Hv);
519  if (t == NULL) return(NULL);
520  cuddRef(t);
521 
522  e = cuddAddIteRecur(dd,Fnv,Gnv,Hnv);
523  if (e == NULL) {
524  Cudd_RecursiveDeref(dd,t);
525  return(NULL);
526  }
527  cuddRef(e);
528 
529  r = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
530  if (r == NULL) {
531  Cudd_RecursiveDeref(dd,t);
532  Cudd_RecursiveDeref(dd,e);
533  return(NULL);
534  }
535  cuddDeref(t);
536  cuddDeref(e);
537 
538  cuddCacheInsert(dd,DD_ADD_ITE_TAG,f,g,h,r);
539 
540  return(r);
541 
542 } /* end of cuddAddIteRecur */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
static void addVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero)
Definition: cuddAddIte.c:621
#define DD_ADD_ITE_TAG
Definition: cuddInt.h:173
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:347
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:217
DdNode * cuddAddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddAddIte.c:441
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddAddMonadicApplyRecur()

DdNode* cuddAddMonadicApplyRecur ( DdManager dd,
DdNode *(*)(DdManager *, DdNode *)  op,
DdNode f 
)

◆ cuddAddNegateRecur()

DdNode* cuddAddNegateRecur ( DdManager dd,
DdNode f 
)

◆ cuddAddOrAbstractRecur()

DdNode* cuddAddOrAbstractRecur ( DdManager manager,
DdNode f,
DdNode cube 
)

◆ cuddAddRestrictRecur()

DdNode* cuddAddRestrictRecur ( DdManager dd,
DdNode f,
DdNode c 
)

◆ cuddAddRoundOffRecur()

DdNode* cuddAddRoundOffRecur ( DdManager dd,
DdNode f,
double  trunc 
)

◆ cuddAddScalarInverseRecur()

DdNode* cuddAddScalarInverseRecur ( DdManager dd,
DdNode f,
DdNode epsilon 
)

◆ cuddAddUnivAbstractRecur()

DdNode* cuddAddUnivAbstractRecur ( DdManager manager,
DdNode f,
DdNode cube 
)

◆ cuddAllocNode()

DdNode* cuddAllocNode ( DdManager unique)

Function********************************************************************

Synopsis [Fast storage allocation for DdNodes in the table.]

Description [Fast storage allocation for DdNodes in the table. The first 4 bytes of a chunk contain a pointer to the next block; the rest contains DD_MEM_CHUNK spaces for DdNodes. Returns a pointer to a new node if successful; NULL is memory is full.]

SideEffects [None]

SeeAlso [cuddDynamicAllocNode]

Definition at line 266 of file cuddTable.c.

268 {
269  int i;
270  DdNodePtr *mem;
271  DdNode *list, *node;
272  extern DD_OOMFP MMoutOfMemory;
273  DD_OOMFP saveHandler;
274 
275  if (unique->nextFree == NULL) { /* free list is empty */
276  /* Check for exceeded limits. */
277  if ((unique->keys - unique->dead) + (unique->keysZ - unique->deadZ) >
278  unique->maxLive) {
279  unique->errorCode = CUDD_TOO_MANY_NODES;
280  return(NULL);
281  }
282  if (util_cpu_time() - unique->startTime > unique->timeLimit) {
284  return(NULL);
285  }
286  if (unique->stash == NULL || unique->memused > unique->maxmemhard) {
287  (void) cuddGarbageCollect(unique,1);
288  mem = NULL;
289  }
290  if (unique->nextFree == NULL) {
291  if (unique->memused > unique->maxmemhard) {
293  return(NULL);
294  }
295  /* Try to allocate a new block. */
296  saveHandler = MMoutOfMemory;
297  MMoutOfMemory = Cudd_OutOfMem;
298  mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1);
299  MMoutOfMemory = saveHandler;
300  if (mem == NULL) {
301  /* No more memory: Try collecting garbage. If this succeeds,
302  ** we end up with mem still NULL, but unique->nextFree !=
303  ** NULL. */
304  if (cuddGarbageCollect(unique,1) == 0) {
305  /* Last resort: Free the memory stashed away, if there
306  ** any. If this succeeeds, mem != NULL and
307  ** unique->nextFree still NULL. */
308  if (unique->stash != NULL) {
309  FREE(unique->stash);
310  unique->stash = NULL;
311  /* Inhibit resizing of tables. */
312  cuddSlowTableGrowth(unique);
313  /* Now try again. */
314  mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1);
315  }
316  if (mem == NULL) {
317  /* Out of luck. Call the default handler to do
318  ** whatever it specifies for a failed malloc.
319  ** If this handler returns, then set error code,
320  ** print warning, and return. */
321  (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1));
322  unique->errorCode = CUDD_MEMORY_OUT;
323 #ifdef DD_VERBOSE
324  (void) fprintf(unique->err,
325  "cuddAllocNode: out of memory");
326  (void) fprintf(unique->err, "Memory in use = %lu\n",
327  unique->memused);
328 #endif
329  return(NULL);
330  }
331  }
332  }
333  if (mem != NULL) { /* successful allocation; slice memory */
334  ptruint offset;
335  unique->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode);
336  mem[0] = (DdNodePtr) unique->memoryList;
337  unique->memoryList = mem;
338 
339  /* Here we rely on the fact that a DdNode is as large
340  ** as 4 pointers. */
341  offset = (ptruint) mem & (sizeof(DdNode) - 1);
342  mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr);
343  assert(((ptruint) mem & (sizeof(DdNode) - 1)) == 0);
344  list = (DdNode *) mem;
345 
346  i = 1;
347  do {
348  list[i - 1].ref = 0;
349  list[i - 1].next = &list[i];
350  } while (++i < DD_MEM_CHUNK);
351 
352  list[DD_MEM_CHUNK-1].ref = 0;
353  list[DD_MEM_CHUNK-1].next = NULL;
354 
355  unique->nextFree = &list[0];
356  }
357  }
358  }
359  unique->allocated++;
360  node = unique->nextFree;
361  unique->nextFree = node->next;
362  return(node);
363 
364 } /* end of cuddAllocNode */
DdHalfWord ref
Definition: cudd.h:272
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2845
double allocated
Definition: cuddInt.h:365
Definition: cudd.h:270
unsigned int deadZ
Definition: cuddInt.h:356
#define FREE(obj)
Definition: util.h:80
unsigned long startTime
Definition: cuddInt.h:426
#define assert(ex)
Definition: util.h:141
FILE * err
Definition: cuddInt.h:424
DdNode * DdNodePtr
Definition: cuddInt.h:253
void(* DD_OOMFP)(long)
Definition: cudd.h:311
struct DdNode DdNode
Definition: cudd.h:262
unsigned int dead
Definition: cuddInt.h:355
unsigned int maxLive
Definition: cuddInt.h:357
char * stash
Definition: cuddInt.h:382
unsigned int keys
Definition: cuddInt.h:353
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:762
#define ALLOC(type, num)
Definition: util.h:76
DdNode * next
Definition: cudd.h:273
long util_cpu_time(void)
Definition: cpu_time.c:34
void(* MMoutOfMemory)(long)
Definition: safe_mem.c:32
DdNode ** memoryList
Definition: cuddInt.h:380
void cuddSlowTableGrowth(DdManager *unique)
Definition: cuddTable.c:2414
unsigned long memused
Definition: cuddInt.h:429
unsigned int ptruint
Definition: cuddInt.h:250
DdNode * nextFree
Definition: cuddInt.h:381
unsigned long maxmemhard
Definition: cuddInt.h:431
#define DD_MEM_CHUNK
Definition: cuddInt.h:105
unsigned int keysZ
Definition: cuddInt.h:354
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddAnnealing()

int cuddAnnealing ( DdManager table,
int  lower,
int  upper 
)

AutomaticEnd Function********************************************************************

Synopsis [Get new variable-order by simulated annealing algorithm.]

Description [Get x, y by random selection. Choose either exchange or jump randomly. In case of jump, choose between jump_up and jump_down randomly. Do exchange or jump and get optimal case. Loop until there is no improvement or temperature reaches minimum. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 154 of file cuddAnneal.c.

158 {
159  int nvars;
160  int size;
161  int x,y;
162  int result;
163  int c1, c2, c3, c4;
164  int BestCost;
165  int *BestOrder;
166  double NewTemp, temp;
167  double rand1;
168  int innerloop, maxGen;
169  int ecount, ucount, dcount;
170 
171  nvars = upper - lower + 1;
172 
173  result = cuddSifting(table,lower,upper);
174 #ifdef DD_STATS
175  (void) fprintf(table->out,"\n");
176 #endif
177  if (result == 0) return(0);
178 
179  size = table->keys - table->isolated;
180 
181  /* Keep track of the best order. */
182  BestCost = size;
183  BestOrder = ALLOC(int,nvars);
184  if (BestOrder == NULL) {
185  table->errorCode = CUDD_MEMORY_OUT;
186  return(0);
187  }
188  copyOrder(table,BestOrder,lower,upper);
189 
190  temp = BETA * size;
191  maxGen = (int) (MAXGEN_RATIO * nvars);
192 
193  c1 = size + 10;
194  c2 = c1 + 10;
195  c3 = size;
196  c4 = c2 + 10;
197  ecount = ucount = dcount = 0;
198 
199  while (!stopping_criterion(c1, c2, c3, c4, temp)) {
200 #ifdef DD_STATS
201  (void) fprintf(table->out,"temp=%f\tsize=%d\tgen=%d\t",
202  temp,size,maxGen);
203  tosses = acceptances = 0;
204 #endif
205  for (innerloop = 0; innerloop < maxGen; innerloop++) {
206  /* Choose x, y randomly. */
207  x = (int) Cudd_Random() % nvars;
208  do {
209  y = (int) Cudd_Random() % nvars;
210  } while (x == y);
211  x += lower;
212  y += lower;
213  if (x > y) {
214  int tmp = x;
215  x = y;
216  y = tmp;
217  }
218 
219  /* Choose move with roulette wheel. */
220  rand1 = random_generator();
221  if (rand1 < EXC_PROB) {
222  result = ddExchange(table,x,y,temp); /* exchange */
223  ecount++;
224 #if 0
225  (void) fprintf(table->out,
226  "Exchange of %d and %d: size = %d\n",
227  x,y,table->keys - table->isolated);
228 #endif
229  } else if (rand1 < EXC_PROB + JUMP_UP_PROB) {
230  result = ddJumpingAux(table,y,x,y,temp); /* jumping_up */
231  ucount++;
232 #if 0
233  (void) fprintf(table->out,
234  "Jump up of %d to %d: size = %d\n",
235  y,x,table->keys - table->isolated);
236 #endif
237  } else {
238  result = ddJumpingAux(table,x,x,y,temp); /* jumping_down */
239  dcount++;
240 #if 0
241  (void) fprintf(table->out,
242  "Jump down of %d to %d: size = %d\n",
243  x,y,table->keys - table->isolated);
244 #endif
245  }
246 
247  if (!result) {
248  FREE(BestOrder);
249  return(0);
250  }
251 
252  size = table->keys - table->isolated; /* keep current size */
253  if (size < BestCost) { /* update best order */
254  BestCost = size;
255  copyOrder(table,BestOrder,lower,upper);
256  }
257  }
258  c1 = c2;
259  c2 = c3;
260  c3 = c4;
261  c4 = size;
262  NewTemp = ALPHA * temp;
263  if (NewTemp >= 1.0) {
264  maxGen = (int)(log(NewTemp) / log(temp) * maxGen);
265  }
266  temp = NewTemp; /* control variable */
267 #ifdef DD_STATS
268  (void) fprintf(table->out,"uphill = %d\taccepted = %d\n",
269  tosses,acceptances);
270  fflush(table->out);
271 #endif
272  }
273 
274  result = restoreOrder(table,BestOrder,lower,upper);
275  FREE(BestOrder);
276  if (!result) return(0);
277 #ifdef DD_STATS
278  fprintf(table->out,"#:N_EXCHANGE %8d : total exchanges\n",ecount);
279  fprintf(table->out,"#:N_JUMPUP %8d : total jumps up\n",ucount);
280  fprintf(table->out,"#:N_JUMPDOWN %8d : total jumps down",dcount);
281 #endif
282  return(1);
283 
284 } /* end of cuddAnnealing */
#define FREE(obj)
Definition: util.h:80
static int stopping_criterion(int c1, int c2, int c3, int c4, double temp)
Definition: cuddAnneal.c:305
static void copyOrder(DdManager *table, int *array, int lower, int upper)
Definition: cuddAnneal.c:758
static double random_generator(void)
Definition: cuddAnneal.c:335
#define ALPHA
Definition: cuddAnneal.c:74
int cuddSifting(DdManager *table, int lower, int upper)
Definition: cuddReorder.c:502
static int restoreOrder(DdManager *table, int *array, int lower, int upper)
Definition: cuddAnneal.c:788
static int ddExchange(DdManager *table, int x, int y, double temp)
Definition: cuddAnneal.c:355
#define BETA
Definition: cuddAnneal.c:73
long Cudd_Random(void)
Definition: cuddUtil.c:2710
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
#define EXC_PROB
Definition: cuddAnneal.c:75
static int ddJumpingAux(DdManager *table, int x, int x_low, int x_high, double temp)
Definition: cuddAnneal.c:504
#define JUMP_UP_PROB
Definition: cuddAnneal.c:76
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368
#define MAXGEN_RATIO
Definition: cuddAnneal.c:77
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddBddAlignToZdd()

int cuddBddAlignToZdd ( DdManager table)

Function********************************************************************

Synopsis [Reorders BDD variables according to the order of the ZDD variables.]

Description [Reorders BDD variables according to the order of the ZDD variables. This function can be called at the end of ZDD reordering to insure that the order of the BDD variables is consistent with the order of the ZDD variables. The number of ZDD variables must be a multiple of the number of BDD variables. Let M be the ratio of the two numbers. cuddBddAlignToZdd then considers the ZDD variables from M*i to (M+1)*i-1 as corresponding to BDD variable i. This function should be normally called from Cudd_zddReduceHeap, which clears the cache. Returns 1 in case of success; 0 otherwise.]

SideEffects [Changes the BDD variable order for all diagrams and performs garbage collection of the BDD unique table.]

SeeAlso [Cudd_ShuffleHeap Cudd_zddReduceHeap]

Definition at line 1250 of file cuddReorder.c.

1252 {
1253  int *invperm; /* permutation array */
1254  int M; /* ratio of ZDD variables to BDD variables */
1255  int i; /* loop index */
1256  int result; /* return value */
1257 
1258  /* We assume that a ratio of 0 is OK. */
1259  if (table->size == 0)
1260  return(1);
1261 
1262  M = table->sizeZ / table->size;
1263  /* Check whether the number of ZDD variables is a multiple of the
1264  ** number of BDD variables.
1265  */
1266  if (M * table->size != table->sizeZ)
1267  return(0);
1268  /* Create and initialize the inverse permutation array. */
1269  invperm = ALLOC(int,table->size);
1270  if (invperm == NULL) {
1271  table->errorCode = CUDD_MEMORY_OUT;
1272  return(0);
1273  }
1274  for (i = 0; i < table->sizeZ; i += M) {
1275  int indexZ = table->invpermZ[i];
1276  int index = indexZ / M;
1277  invperm[i / M] = index;
1278  }
1279  /* Eliminate dead nodes. Do not scan the cache again, because we
1280  ** assume that Cudd_zddReduceHeap has already cleared it.
1281  */
1282  cuddGarbageCollect(table,0);
1283 
1284  /* Initialize number of isolated projection functions. */
1285  table->isolated = 0;
1286  for (i = 0; i < table->size; i++) {
1287  if (table->vars[i]->ref == 1) table->isolated++;
1288  }
1289 
1290  /* Initialize the interaction matrix. */
1291  result = cuddInitInteract(table);
1292  if (result == 0) return(0);
1293 
1294  result = ddShuffle(table, invperm);
1295  FREE(invperm);
1296  /* Free interaction matrix. */
1297  FREE(table->interact);
1298  /* Fix the BDD variable group tree. */
1299  bddFixTree(table,table->tree);
1300  return(result);
1301 
1302 } /* end of cuddBddAlignToZdd */
DdHalfWord ref
Definition: cudd.h:272
#define FREE(obj)
Definition: util.h:80
int * invpermZ
Definition: cuddInt.h:372
int size
Definition: cuddInt.h:345
int cuddInitInteract(DdManager *table)
Definition: cuddInteract.c:234
MtrNode * tree
Definition: cuddInt.h:408
static void bddFixTree(DdManager *table, MtrNode *treenode)
Definition: cuddReorder.c:2009
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:762
#define ALLOC(type, num)
Definition: util.h:76
long * interact
Definition: cuddInt.h:377
int sizeZ
Definition: cuddInt.h:346
DdNode ** vars
Definition: cuddInt.h:373
static int ddShuffle(DdManager *table, int *permutation)
Definition: cuddReorder.c:1896
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddBddAndAbstractRecur()

DdNode* cuddBddAndAbstractRecur ( DdManager manager,
DdNode f,
DdNode g,
DdNode cube 
)

◆ cuddBddAndRecur()

DdNode* cuddBddAndRecur ( DdManager manager,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Implements the recursive step of Cudd_bddAnd.]

Description [Implements the recursive step of Cudd_bddAnd by taking the conjunction of two BDDs. Returns a pointer to the result is successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddAnd]

Definition at line 995 of file cuddBddIte.c.

999 {
1000  DdNode *F, *fv, *fnv, *G, *gv, *gnv;
1001  DdNode *one, *r, *t, *e;
1002  unsigned int topf, topg, index;
1003 
1004  statLine(manager);
1005  one = DD_ONE(manager);
1006 
1007  /* Terminal cases. */
1008  F = Cudd_Regular(f);
1009  G = Cudd_Regular(g);
1010  if (F == G) {
1011  if (f == g) return(f);
1012  else return(Cudd_Not(one));
1013  }
1014  if (F == one) {
1015  if (f == one) return(g);
1016  else return(f);
1017  }
1018  if (G == one) {
1019  if (g == one) return(f);
1020  else return(g);
1021  }
1022 
1023  /* At this point f and g are not constant. */
1024  if (f > g) { /* Try to increase cache efficiency. */
1025  DdNode *tmp = f;
1026  f = g;
1027  g = tmp;
1028  F = Cudd_Regular(f);
1029  G = Cudd_Regular(g);
1030  }
1031 
1032  /* Check cache. */
1033  if (F->ref != 1 || G->ref != 1) {
1034  r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g);
1035  if (r != NULL) return(r);
1036  }
1037 
1038  /* Here we can skip the use of cuddI, because the operands are known
1039  ** to be non-constant.
1040  */
1041  topf = manager->perm[F->index];
1042  topg = manager->perm[G->index];
1043 
1044  /* Compute cofactors. */
1045  if (topf <= topg) {
1046  index = F->index;
1047  fv = cuddT(F);
1048  fnv = cuddE(F);
1049  if (Cudd_IsComplement(f)) {
1050  fv = Cudd_Not(fv);
1051  fnv = Cudd_Not(fnv);
1052  }
1053  } else {
1054  index = G->index;
1055  fv = fnv = f;
1056  }
1057 
1058  if (topg <= topf) {
1059  gv = cuddT(G);
1060  gnv = cuddE(G);
1061  if (Cudd_IsComplement(g)) {
1062  gv = Cudd_Not(gv);
1063  gnv = Cudd_Not(gnv);
1064  }
1065  } else {
1066  gv = gnv = g;
1067  }
1068 
1069  t = cuddBddAndRecur(manager, fv, gv);
1070  if (t == NULL) return(NULL);
1071  cuddRef(t);
1072 
1073  e = cuddBddAndRecur(manager, fnv, gnv);
1074  if (e == NULL) {
1075  Cudd_IterDerefBdd(manager, t);
1076  return(NULL);
1077  }
1078  cuddRef(e);
1079 
1080  if (t == e) {
1081  r = t;
1082  } else {
1083  if (Cudd_IsComplement(t)) {
1084  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
1085  if (r == NULL) {
1086  Cudd_IterDerefBdd(manager, t);
1087  Cudd_IterDerefBdd(manager, e);
1088  return(NULL);
1089  }
1090  r = Cudd_Not(r);
1091  } else {
1092  r = cuddUniqueInter(manager,(int)index,t,e);
1093  if (r == NULL) {
1094  Cudd_IterDerefBdd(manager, t);
1095  Cudd_IterDerefBdd(manager, e);
1096  return(NULL);
1097  }
1098  }
1099  }
1100  cuddDeref(e);
1101  cuddDeref(t);
1102  if (F->ref != 1 || G->ref != 1)
1103  cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r);
1104  return(r);
1105 
1106 } /* end of cuddBddAndRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
DdHalfWord ref
Definition: cudd.h:272
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define cuddT(node)
Definition: cuddInt.h:609
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:350
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
int * perm
Definition: cuddInt.h:369
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137

◆ cuddBddBooleanDiffRecur()

DdNode* cuddBddBooleanDiffRecur ( DdManager manager,
DdNode f,
DdNode var 
)

Function********************************************************************

Synopsis [Performs the recursive steps of Cudd_bddBoleanDiff.]

Description [Performs the recursive steps of Cudd_bddBoleanDiff. Returns the BDD obtained by XORing the cofactors of f with respect to var if successful; NULL otherwise. Exploits the fact that dF/dx = dF'/dx.]

SideEffects [None]

SeeAlso []

Definition at line 675 of file cuddBddAbs.c.

679 {
680  DdNode *T, *E, *res, *res1, *res2;
681 
682  statLine(manager);
683  if (cuddI(manager,f->index) > manager->perm[var->index]) {
684  /* f does not depend on var. */
685  return(Cudd_Not(DD_ONE(manager)));
686  }
687 
688  /* From now on, f is non-constant. */
689 
690  /* If the two indices are the same, so are their levels. */
691  if (f->index == var->index) {
692  res = cuddBddXorRecur(manager, cuddT(f), cuddE(f));
693  return(res);
694  }
695 
696  /* From now on, cuddI(manager,f->index) < cuddI(manager,cube->index). */
697 
698  /* Check the cache. */
699  res = cuddCacheLookup2(manager, cuddBddBooleanDiffRecur, f, var);
700  if (res != NULL) {
701  return(res);
702  }
703 
704  /* Compute the cofactors of f. */
705  T = cuddT(f); E = cuddE(f);
706 
707  res1 = cuddBddBooleanDiffRecur(manager, T, var);
708  if (res1 == NULL) return(NULL);
709  cuddRef(res1);
710  res2 = cuddBddBooleanDiffRecur(manager, Cudd_Regular(E), var);
711  if (res2 == NULL) {
712  Cudd_IterDerefBdd(manager, res1);
713  return(NULL);
714  }
715  cuddRef(res2);
716  /* ITE takes care of possible complementation of res1 and of the
717  ** case in which res1 == res2. */
718  res = cuddBddIteRecur(manager, manager->vars[f->index], res1, res2);
719  if (res == NULL) {
720  Cudd_IterDerefBdd(manager, res1);
721  Cudd_IterDerefBdd(manager, res2);
722  return(NULL);
723  }
724  cuddDeref(res1);
725  cuddDeref(res2);
726  cuddCacheInsert2(manager, cuddBddBooleanDiffRecur, f, var, res);
727  return(res);
728 
729 } /* end of cuddBddBooleanDiffRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddBddBooleanDiffRecur(DdManager *manager, DdNode *f, DdNode *var)
Definition: cuddBddAbs.c:675
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:742
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369

◆ cuddBddClippingAnd()

DdNode* cuddBddClippingAnd ( DdManager dd,
DdNode f,
DdNode g,
int  maxDepth,
int  direction 
)

◆ cuddBddClippingAndAbstract()

DdNode* cuddBddClippingAndAbstract ( DdManager dd,
DdNode f,
DdNode g,
DdNode cube,
int  maxDepth,
int  direction 
)

◆ cuddBddClosestCube()

DdNode* cuddBddClosestCube ( DdManager dd,
DdNode f,
DdNode g,
CUDD_VALUE_TYPE  bound 
)

◆ cuddBddComposeRecur()

DdNode* cuddBddComposeRecur ( DdManager dd,
DdNode f,
DdNode g,
DdNode proj 
)

◆ cuddBddConstrainRecur()

DdNode* cuddBddConstrainRecur ( DdManager dd,
DdNode f,
DdNode c 
)

◆ cuddBddExistAbstractRecur()

DdNode* cuddBddExistAbstractRecur ( DdManager manager,
DdNode f,
DdNode cube 
)

Function********************************************************************

Synopsis [Performs the recursive steps of Cudd_bddExistAbstract.]

Description [Performs the recursive steps of Cudd_bddExistAbstract. Returns the BDD obtained by abstracting the variables of cube from f if successful; NULL otherwise. It is also used by Cudd_bddUnivAbstract.]

SideEffects [None]

SeeAlso [Cudd_bddExistAbstract Cudd_bddUnivAbstract]

Definition at line 393 of file cuddBddAbs.c.

397 {
398  DdNode *F, *T, *E, *res, *res1, *res2, *one;
399 
400  statLine(manager);
401  one = DD_ONE(manager);
402  F = Cudd_Regular(f);
403 
404  /* Cube is guaranteed to be a cube at this point. */
405  if (cube == one || F == one) {
406  return(f);
407  }
408  /* From now on, f and cube are non-constant. */
409 
410  /* Abstract a variable that does not appear in f. */
411  while (manager->perm[F->index] > manager->perm[cube->index]) {
412  cube = cuddT(cube);
413  if (cube == one) return(f);
414  }
415 
416  /* Check the cache. */
417  if (F->ref != 1 && (res = cuddCacheLookup2(manager, Cudd_bddExistAbstract, f, cube)) != NULL) {
418  return(res);
419  }
420 
421  /* Compute the cofactors of f. */
422  T = cuddT(F); E = cuddE(F);
423  if (f != F) {
424  T = Cudd_Not(T); E = Cudd_Not(E);
425  }
426 
427  /* If the two indices are the same, so are their levels. */
428  if (F->index == cube->index) {
429  if (T == one || E == one || T == Cudd_Not(E)) {
430  return(one);
431  }
432  res1 = cuddBddExistAbstractRecur(manager, T, cuddT(cube));
433  if (res1 == NULL) return(NULL);
434  if (res1 == one) {
435  if (F->ref != 1)
436  cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, one);
437  return(one);
438  }
439  cuddRef(res1);
440  res2 = cuddBddExistAbstractRecur(manager, E, cuddT(cube));
441  if (res2 == NULL) {
442  Cudd_IterDerefBdd(manager,res1);
443  return(NULL);
444  }
445  cuddRef(res2);
446  res = cuddBddAndRecur(manager, Cudd_Not(res1), Cudd_Not(res2));
447  if (res == NULL) {
448  Cudd_IterDerefBdd(manager, res1);
449  Cudd_IterDerefBdd(manager, res2);
450  return(NULL);
451  }
452  res = Cudd_Not(res);
453  cuddRef(res);
454  Cudd_IterDerefBdd(manager, res1);
455  Cudd_IterDerefBdd(manager, res2);
456  if (F->ref != 1)
457  cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res);
458  cuddDeref(res);
459  return(res);
460  } else { /* if (cuddI(manager,F->index) < cuddI(manager,cube->index)) */
461  res1 = cuddBddExistAbstractRecur(manager, T, cube);
462  if (res1 == NULL) return(NULL);
463  cuddRef(res1);
464  res2 = cuddBddExistAbstractRecur(manager, E, cube);
465  if (res2 == NULL) {
466  Cudd_IterDerefBdd(manager, res1);
467  return(NULL);
468  }
469  cuddRef(res2);
470  /* ITE takes care of possible complementation of res1 and of the
471  ** case in which res1 == res2. */
472  res = cuddBddIteRecur(manager, manager->vars[F->index], res1, res2);
473  if (res == NULL) {
474  Cudd_IterDerefBdd(manager, res1);
475  Cudd_IterDerefBdd(manager, res2);
476  return(NULL);
477  }
478  cuddDeref(res1);
479  cuddDeref(res2);
480  if (F->ref != 1)
481  cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res);
482  return(res);
483  }
484 
485 } /* end of cuddBddExistAbstractRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
DdHalfWord ref
Definition: cudd.h:272
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:393
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:742
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
DdNode * Cudd_bddExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:127
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369

◆ cuddBddIntersectRecur()

DdNode* cuddBddIntersectRecur ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Implements the recursive step of Cudd_bddIntersect.]

Description []

SideEffects [None]

SeeAlso [Cudd_bddIntersect]

Definition at line 880 of file cuddBddIte.c.

884 {
885  DdNode *res;
886  DdNode *F, *G, *t, *e;
887  DdNode *fv, *fnv, *gv, *gnv;
888  DdNode *one, *zero;
889  unsigned int index, topf, topg;
890 
891  statLine(dd);
892  one = DD_ONE(dd);
893  zero = Cudd_Not(one);
894 
895  /* Terminal cases. */
896  if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
897  if (f == g || g == one) return(f);
898  if (f == one) return(g);
899 
900  /* At this point f and g are not constant. */
901  if (f > g) { DdNode *tmp = f; f = g; g = tmp; }
902  res = cuddCacheLookup2(dd,Cudd_bddIntersect,f,g);
903  if (res != NULL) return(res);
904 
905  /* Find splitting variable. Here we can skip the use of cuddI,
906  ** because the operands are known to be non-constant.
907  */
908  F = Cudd_Regular(f);
909  topf = dd->perm[F->index];
910  G = Cudd_Regular(g);
911  topg = dd->perm[G->index];
912 
913  /* Compute cofactors. */
914  if (topf <= topg) {
915  index = F->index;
916  fv = cuddT(F);
917  fnv = cuddE(F);
918  if (Cudd_IsComplement(f)) {
919  fv = Cudd_Not(fv);
920  fnv = Cudd_Not(fnv);
921  }
922  } else {
923  index = G->index;
924  fv = fnv = f;
925  }
926 
927  if (topg <= topf) {
928  gv = cuddT(G);
929  gnv = cuddE(G);
930  if (Cudd_IsComplement(g)) {
931  gv = Cudd_Not(gv);
932  gnv = Cudd_Not(gnv);
933  }
934  } else {
935  gv = gnv = g;
936  }
937 
938  /* Compute partial results. */
939  t = cuddBddIntersectRecur(dd,fv,gv);
940  if (t == NULL) return(NULL);
941  cuddRef(t);
942  if (t != zero) {
943  e = zero;
944  } else {
945  e = cuddBddIntersectRecur(dd,fnv,gnv);
946  if (e == NULL) {
947  Cudd_IterDerefBdd(dd, t);
948  return(NULL);
949  }
950  }
951  cuddRef(e);
952 
953  if (t == e) { /* both equal zero */
954  res = t;
955  } else if (Cudd_IsComplement(t)) {
956  res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e));
957  if (res == NULL) {
958  Cudd_IterDerefBdd(dd, t);
959  Cudd_IterDerefBdd(dd, e);
960  return(NULL);
961  }
962  res = Cudd_Not(res);
963  } else {
964  res = cuddUniqueInter(dd,(int)index,t,e);
965  if (res == NULL) {
966  Cudd_IterDerefBdd(dd, t);
967  Cudd_IterDerefBdd(dd, e);
968  return(NULL);
969  }
970  }
971  cuddDeref(e);
972  cuddDeref(t);
973 
975 
976  return(res);
977 
978 } /* end of cuddBddIntersectRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
DdNode * Cudd_bddIntersect(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:318
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define cuddT(node)
Definition: cuddInt.h:609
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
DdNode * cuddBddIntersectRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:880
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137

◆ cuddBddIsop()

DdNode* cuddBddIsop ( DdManager dd,
DdNode L,
DdNode U 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_bddIsop.]

Description []

SideEffects [None]

SeeAlso [Cudd_bddIsop]

Definition at line 572 of file cuddZddIsop.c.

576 {
577  DdNode *one = DD_ONE(dd);
578  DdNode *zero = Cudd_Not(one);
579  int v, top_l, top_u;
580  DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud;
581  DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1;
582  DdNode *Isub0, *Isub1, *Id;
583  DdNode *x;
584  DdNode *term0, *term1, *sum;
585  DdNode *Lv, *Uv, *Lnv, *Unv;
586  DdNode *r;
587  int index;
588 
589  statLine(dd);
590  if (L == zero)
591  return(zero);
592  if (U == one)
593  return(one);
594 
595  /* Check cache */
596  r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
597  if (r)
598  return(r);
599 
600  top_l = dd->perm[Cudd_Regular(L)->index];
601  top_u = dd->perm[Cudd_Regular(U)->index];
602  v = ddMin(top_l, top_u);
603 
604  /* Compute cofactors */
605  if (top_l == v) {
606  index = Cudd_Regular(L)->index;
607  Lv = Cudd_T(L);
608  Lnv = Cudd_E(L);
609  if (Cudd_IsComplement(L)) {
610  Lv = Cudd_Not(Lv);
611  Lnv = Cudd_Not(Lnv);
612  }
613  }
614  else {
615  index = Cudd_Regular(U)->index;
616  Lv = Lnv = L;
617  }
618 
619  if (top_u == v) {
620  Uv = Cudd_T(U);
621  Unv = Cudd_E(U);
622  if (Cudd_IsComplement(U)) {
623  Uv = Cudd_Not(Uv);
624  Unv = Cudd_Not(Unv);
625  }
626  }
627  else {
628  Uv = Unv = U;
629  }
630 
631  Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
632  if (Lsub0 == NULL)
633  return(NULL);
634  Cudd_Ref(Lsub0);
635  Usub0 = Unv;
636  Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv));
637  if (Lsub1 == NULL) {
638  Cudd_RecursiveDeref(dd, Lsub0);
639  return(NULL);
640  }
641  Cudd_Ref(Lsub1);
642  Usub1 = Uv;
643 
644  Isub0 = cuddBddIsop(dd, Lsub0, Usub0);
645  if (Isub0 == NULL) {
646  Cudd_RecursiveDeref(dd, Lsub0);
647  Cudd_RecursiveDeref(dd, Lsub1);
648  return(NULL);
649  }
650  Cudd_Ref(Isub0);
651  Isub1 = cuddBddIsop(dd, Lsub1, Usub1);
652  if (Isub1 == NULL) {
653  Cudd_RecursiveDeref(dd, Lsub0);
654  Cudd_RecursiveDeref(dd, Lsub1);
655  Cudd_RecursiveDeref(dd, Isub0);
656  return(NULL);
657  }
658  Cudd_Ref(Isub1);
659  Cudd_RecursiveDeref(dd, Lsub0);
660  Cudd_RecursiveDeref(dd, Lsub1);
661 
662  Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0));
663  if (Lsuper0 == NULL) {
664  Cudd_RecursiveDeref(dd, Isub0);
665  Cudd_RecursiveDeref(dd, Isub1);
666  return(NULL);
667  }
668  Cudd_Ref(Lsuper0);
669  Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1));
670  if (Lsuper1 == NULL) {
671  Cudd_RecursiveDeref(dd, Isub0);
672  Cudd_RecursiveDeref(dd, Isub1);
673  Cudd_RecursiveDeref(dd, Lsuper0);
674  return(NULL);
675  }
676  Cudd_Ref(Lsuper1);
677  Usuper0 = Unv;
678  Usuper1 = Uv;
679 
680  /* Ld = Lsuper0 + Lsuper1 */
681  Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1));
682  Ld = Cudd_NotCond(Ld, Ld != NULL);
683  if (Ld == NULL) {
684  Cudd_RecursiveDeref(dd, Isub0);
685  Cudd_RecursiveDeref(dd, Isub1);
686  Cudd_RecursiveDeref(dd, Lsuper0);
687  Cudd_RecursiveDeref(dd, Lsuper1);
688  return(NULL);
689  }
690  Cudd_Ref(Ld);
691  Ud = cuddBddAndRecur(dd, Usuper0, Usuper1);
692  if (Ud == NULL) {
693  Cudd_RecursiveDeref(dd, Isub0);
694  Cudd_RecursiveDeref(dd, Isub1);
695  Cudd_RecursiveDeref(dd, Lsuper0);
696  Cudd_RecursiveDeref(dd, Lsuper1);
697  Cudd_RecursiveDeref(dd, Ld);
698  return(NULL);
699  }
700  Cudd_Ref(Ud);
701  Cudd_RecursiveDeref(dd, Lsuper0);
702  Cudd_RecursiveDeref(dd, Lsuper1);
703 
704  Id = cuddBddIsop(dd, Ld, Ud);
705  if (Id == NULL) {
706  Cudd_RecursiveDeref(dd, Isub0);
707  Cudd_RecursiveDeref(dd, Isub1);
708  Cudd_RecursiveDeref(dd, Ld);
709  Cudd_RecursiveDeref(dd, Ud);
710  return(NULL);
711  }
712  Cudd_Ref(Id);
713  Cudd_RecursiveDeref(dd, Ld);
714  Cudd_RecursiveDeref(dd, Ud);
715 
716  x = cuddUniqueInter(dd, index, one, zero);
717  if (x == NULL) {
718  Cudd_RecursiveDeref(dd, Isub0);
719  Cudd_RecursiveDeref(dd, Isub1);
720  Cudd_RecursiveDeref(dd, Id);
721  return(NULL);
722  }
723  Cudd_Ref(x);
724  term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0);
725  if (term0 == NULL) {
726  Cudd_RecursiveDeref(dd, Isub0);
727  Cudd_RecursiveDeref(dd, Isub1);
728  Cudd_RecursiveDeref(dd, Id);
729  Cudd_RecursiveDeref(dd, x);
730  return(NULL);
731  }
732  Cudd_Ref(term0);
733  Cudd_RecursiveDeref(dd, Isub0);
734  term1 = cuddBddAndRecur(dd, x, Isub1);
735  if (term1 == NULL) {
736  Cudd_RecursiveDeref(dd, Isub1);
737  Cudd_RecursiveDeref(dd, Id);
738  Cudd_RecursiveDeref(dd, x);
739  Cudd_RecursiveDeref(dd, term0);
740  return(NULL);
741  }
742  Cudd_Ref(term1);
743  Cudd_RecursiveDeref(dd, x);
744  Cudd_RecursiveDeref(dd, Isub1);
745  /* sum = term0 + term1 */
746  sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1));
747  sum = Cudd_NotCond(sum, sum != NULL);
748  if (sum == NULL) {
749  Cudd_RecursiveDeref(dd, Id);
750  Cudd_RecursiveDeref(dd, term0);
751  Cudd_RecursiveDeref(dd, term1);
752  return(NULL);
753  }
754  Cudd_Ref(sum);
755  Cudd_RecursiveDeref(dd, term0);
756  Cudd_RecursiveDeref(dd, term1);
757  /* r = sum + Id */
758  r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id));
759  r = Cudd_NotCond(r, r != NULL);
760  if (r == NULL) {
761  Cudd_RecursiveDeref(dd, Id);
762  Cudd_RecursiveDeref(dd, sum);
763  return(NULL);
764  }
765  Cudd_Ref(r);
766  Cudd_RecursiveDeref(dd, sum);
767  Cudd_RecursiveDeref(dd, Id);
768 
769  cuddCacheInsert2(dd, cuddBddIsop, L, U, r);
770 
771  Cudd_Deref(r);
772  return(r);
773 
774 } /* end of cuddBddIsop */
#define Cudd_T(node)
Definition: cudd.h:427
#define Cudd_E(node)
Definition: cudd.h:442
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define ddMin(x, y)
Definition: cuddInt.h:771
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
static DdNode * zero
Definition: cuddSat.c:105
DdNode * cuddBddIsop(DdManager *dd, DdNode *L, DdNode *U)
Definition: cuddZddIsop.c:572
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137

◆ cuddBddIteRecur()

DdNode* cuddBddIteRecur ( DdManager dd,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Implements the recursive step of Cudd_bddIte.]

Description [Implements the recursive step of Cudd_bddIte. Returns a pointer to the resulting BDD. NULL if the intermediate result blows up or if reordering occurs.]

SideEffects [None]

SeeAlso []

Definition at line 742 of file cuddBddIte.c.

747 {
748  DdNode *one, *zero, *res;
749  DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
750  unsigned int topf, topg, toph, v;
751  int index;
752  int comple;
753 
754  statLine(dd);
755  /* Terminal cases. */
756 
757  /* One variable cases. */
758  if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */
759  return(g);
760 
761  if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */
762  return(h);
763 
764  /* From now on, f is known not to be a constant. */
765  if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
766  if (h == zero) { /* ITE(F,1,0) = F */
767  return(f);
768  } else {
769  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h));
770  return(Cudd_NotCond(res,res != NULL));
771  }
772  } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */
773  if (h == one) { /* ITE(F,0,1) = !F */
774  return(Cudd_Not(f));
775  } else {
776  res = cuddBddAndRecur(dd,Cudd_Not(f),h);
777  return(res);
778  }
779  }
780  if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
781  res = cuddBddAndRecur(dd,f,g);
782  return(res);
783  } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */
784  res = cuddBddAndRecur(dd,f,Cudd_Not(g));
785  return(Cudd_NotCond(res,res != NULL));
786  }
787 
788  /* Check remaining one variable case. */
789  if (g == h) { /* ITE(F,G,G) = G */
790  return(g);
791  } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */
792  res = cuddBddXorRecur(dd,f,h);
793  return(res);
794  }
795 
796  /* From here, there are no constants. */
797  comple = bddVarToCanonicalSimple(dd, &f, &g, &h, &topf, &topg, &toph);
798 
799  /* f & g are now regular pointers */
800 
801  v = ddMin(topg, toph);
802 
803  /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */
804  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
805  r = cuddUniqueInter(dd, (int) f->index, g, h);
806  return(Cudd_NotCond(r,comple && r != NULL));
807  }
808 
809  /* Check cache. */
810  r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h);
811  if (r != NULL) {
812  return(Cudd_NotCond(r,comple));
813  }
814 
815  /* Compute cofactors. */
816  if (topf <= v) {
817  v = ddMin(topf, v); /* v = top_var(F,G,H) */
818  index = f->index;
819  Fv = cuddT(f); Fnv = cuddE(f);
820  } else {
821  Fv = Fnv = f;
822  }
823  if (topg == v) {
824  index = g->index;
825  Gv = cuddT(g); Gnv = cuddE(g);
826  } else {
827  Gv = Gnv = g;
828  }
829  if (toph == v) {
830  H = Cudd_Regular(h);
831  index = H->index;
832  Hv = cuddT(H); Hnv = cuddE(H);
833  if (Cudd_IsComplement(h)) {
834  Hv = Cudd_Not(Hv);
835  Hnv = Cudd_Not(Hnv);
836  }
837  } else {
838  Hv = Hnv = h;
839  }
840 
841  /* Recursive step. */
842  t = cuddBddIteRecur(dd,Fv,Gv,Hv);
843  if (t == NULL) return(NULL);
844  cuddRef(t);
845 
846  e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv);
847  if (e == NULL) {
848  Cudd_IterDerefBdd(dd,t);
849  return(NULL);
850  }
851  cuddRef(e);
852 
853  r = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
854  if (r == NULL) {
855  Cudd_IterDerefBdd(dd,t);
856  Cudd_IterDerefBdd(dd,e);
857  return(NULL);
858  }
859  cuddDeref(t);
860  cuddDeref(e);
861 
862  cuddCacheInsert(dd, DD_BDD_ITE_TAG, f, g, h, r);
863  return(Cudd_NotCond(r,comple));
864 
865 } /* end of cuddBddIteRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define Cudd_Regular(node)
Definition: cudd.h:384
static int bddVarToCanonicalSimple(DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
Definition: cuddBddIte.c:1381
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define ddMin(x, y)
Definition: cuddInt.h:771
#define DD_BDD_ITE_TAG
Definition: cuddInt.h:176
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:347
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:217
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:742

◆ cuddBddLICompaction()

DdNode* cuddBddLICompaction ( DdManager dd,
DdNode f,
DdNode c 
)

◆ cuddBddLiteralSetIntersectionRecur()

DdNode* cuddBddLiteralSetIntersectionRecur ( DdManager dd,
DdNode f,
DdNode g 
)

◆ cuddBddMakePrime()

DdNode* cuddBddMakePrime ( DdManager dd,
DdNode cube,
DdNode f 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_bddMakePrime.]

Description [Performs the recursive step of Cudd_bddMakePrime. Returns the prime if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 995 of file cuddSat.c.

999 {
1000  DdNode *scan;
1001  DdNode *t, *e;
1002  DdNode *res = cube;
1003  DdNode *zero = Cudd_Not(DD_ONE(dd));
1004 
1005  Cudd_Ref(res);
1006  scan = cube;
1007  while (!Cudd_IsConstant(scan)) {
1008  DdNode *reg = Cudd_Regular(scan);
1009  DdNode *var = dd->vars[reg->index];
1010  DdNode *expanded = Cudd_bddExistAbstract(dd,res,var);
1011  if (expanded == NULL) {
1012  Cudd_RecursiveDeref(dd,res);
1013  return(NULL);
1014  }
1015  Cudd_Ref(expanded);
1016  if (Cudd_bddLeq(dd,expanded,f)) {
1017  Cudd_RecursiveDeref(dd,res);
1018  res = expanded;
1019  } else {
1020  Cudd_RecursiveDeref(dd,expanded);
1021  }
1022  cuddGetBranches(scan,&t,&e);
1023  if (t == zero) {
1024  scan = e;
1025  } else if (e == zero) {
1026  scan = t;
1027  } else {
1028  Cudd_RecursiveDeref(dd,res);
1029  return(NULL); /* cube is not a cube */
1030  }
1031  }
1032 
1033  if (scan == DD_ONE(dd)) {
1034  Cudd_Deref(res);
1035  return(res);
1036  } else {
1037  Cudd_RecursiveDeref(dd,res);
1038  return(NULL);
1039  }
1040 
1041 } /* end of cuddBddMakePrime */
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
#define Cudd_IsConstant(node)
Definition: cudd.h:339
#define Cudd_Regular(node)
Definition: cudd.h:384
DdNode * Cudd_bddExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:127
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:645
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
Definition: cuddCof.c:196
DdHalfWord index
Definition: cudd.h:271
DdNode ** vars
Definition: cuddInt.h:373
static DdNode * zero
Definition: cuddSat.c:105
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ cuddBddNPAndRecur()

DdNode* cuddBddNPAndRecur ( DdManager dd,
DdNode f,
DdNode c 
)

◆ cuddBddRestrictRecur()

DdNode* cuddBddRestrictRecur ( DdManager dd,
DdNode f,
DdNode c 
)

◆ cuddBddTransfer()

DdNode* cuddBddTransfer ( DdManager ddS,
DdManager ddD,
DdNode f 
)

◆ cuddBddXorExistAbstractRecur()

DdNode* cuddBddXorExistAbstractRecur ( DdManager manager,
DdNode f,
DdNode g,
DdNode cube 
)

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_bddAndAbstract]

Definition at line 503 of file cuddBddAbs.c.

508 {
509  DdNode *F, *fv, *fnv, *G, *gv, *gnv;
510  DdNode *one, *zero, *r, *t, *e, *Cube;
511  unsigned int topf, topg, topcube, top, index;
512 
513  statLine(manager);
514  one = DD_ONE(manager);
515  zero = Cudd_Not(one);
516 
517  /* Terminal cases. */
518  if (f == g) {
519  return(zero);
520  }
521  if (f == Cudd_Not(g)) {
522  return(one);
523  }
524  if (cube == one) {
525  return(cuddBddXorRecur(manager, f, g));
526  }
527  if (f == one) {
528  return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube));
529  }
530  if (g == one) {
531  return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube));
532  }
533  if (f == zero) {
534  return(cuddBddExistAbstractRecur(manager, g, cube));
535  }
536  if (g == zero) {
537  return(cuddBddExistAbstractRecur(manager, f, cube));
538  }
539 
540  /* At this point f, g, and cube are not constant. */
541 
542  if (f > g) { /* Try to increase cache efficiency. */
543  DdNode *tmp = f;
544  f = g;
545  g = tmp;
546  }
547 
548  /* Check cache. */
549  r = cuddCacheLookup(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube);
550  if (r != NULL) {
551  return(r);
552  }
553 
554  /* Here we can skip the use of cuddI, because the operands are known
555  ** to be non-constant.
556  */
557  F = Cudd_Regular(f);
558  topf = manager->perm[F->index];
559  G = Cudd_Regular(g);
560  topg = manager->perm[G->index];
561  top = ddMin(topf, topg);
562  topcube = manager->perm[cube->index];
563 
564  if (topcube < top) {
565  return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube)));
566  }
567  /* Now, topcube >= top. */
568 
569  if (topf == top) {
570  index = F->index;
571  fv = cuddT(F);
572  fnv = cuddE(F);
573  if (Cudd_IsComplement(f)) {
574  fv = Cudd_Not(fv);
575  fnv = Cudd_Not(fnv);
576  }
577  } else {
578  index = G->index;
579  fv = fnv = f;
580  }
581 
582  if (topg == top) {
583  gv = cuddT(G);
584  gnv = cuddE(G);
585  if (Cudd_IsComplement(g)) {
586  gv = Cudd_Not(gv);
587  gnv = Cudd_Not(gnv);
588  }
589  } else {
590  gv = gnv = g;
591  }
592 
593  if (topcube == top) {
594  Cube = cuddT(cube);
595  } else {
596  Cube = cube;
597  }
598 
599  t = cuddBddXorExistAbstractRecur(manager, fv, gv, Cube);
600  if (t == NULL) return(NULL);
601 
602  /* Special case: 1 OR anything = 1. Hence, no need to compute
603  ** the else branch if t is 1.
604  */
605  if (t == one && topcube == top) {
606  cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, one);
607  return(one);
608  }
609  cuddRef(t);
610 
611  e = cuddBddXorExistAbstractRecur(manager, fnv, gnv, Cube);
612  if (e == NULL) {
613  Cudd_IterDerefBdd(manager, t);
614  return(NULL);
615  }
616  cuddRef(e);
617 
618  if (topcube == top) { /* abstract */
619  r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e));
620  if (r == NULL) {
621  Cudd_IterDerefBdd(manager, t);
622  Cudd_IterDerefBdd(manager, e);
623  return(NULL);
624  }
625  r = Cudd_Not(r);
626  cuddRef(r);
627  Cudd_IterDerefBdd(manager, t);
628  Cudd_IterDerefBdd(manager, e);
629  cuddDeref(r);
630  } else if (t == e) {
631  r = t;
632  cuddDeref(t);
633  cuddDeref(e);
634  } else {
635  if (Cudd_IsComplement(t)) {
636  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
637  if (r == NULL) {
638  Cudd_IterDerefBdd(manager, t);
639  Cudd_IterDerefBdd(manager, e);
640  return(NULL);
641  }
642  r = Cudd_Not(r);
643  } else {
644  r = cuddUniqueInter(manager,(int)index,t,e);
645  if (r == NULL) {
646  Cudd_IterDerefBdd(manager, t);
647  Cudd_IterDerefBdd(manager, e);
648  return(NULL);
649  }
650  }
651  cuddDeref(e);
652  cuddDeref(t);
653  }
654  cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, r);
655  return (r);
656 
657 } /* end of cuddBddXorExistAbstractRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:393
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define DD_BDD_XOR_EXIST_ABSTRACT_TAG
Definition: cuddInt.h:175
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:347
DdNode * cuddBddXorExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
Definition: cuddBddAbs.c:503
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:217
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137

◆ cuddBddXorRecur()

DdNode* cuddBddXorRecur ( DdManager manager,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Implements the recursive step of Cudd_bddXor.]

Description [Implements the recursive step of Cudd_bddXor by taking the exclusive OR of two BDDs. Returns a pointer to the result is successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddXor]

Definition at line 1123 of file cuddBddIte.c.

1127 {
1128  DdNode *fv, *fnv, *G, *gv, *gnv;
1129  DdNode *one, *zero, *r, *t, *e;
1130  unsigned int topf, topg, index;
1131 
1132  statLine(manager);
1133  one = DD_ONE(manager);
1134  zero = Cudd_Not(one);
1135 
1136  /* Terminal cases. */
1137  if (f == g) return(zero);
1138  if (f == Cudd_Not(g)) return(one);
1139  if (f > g) { /* Try to increase cache efficiency and simplify tests. */
1140  DdNode *tmp = f;
1141  f = g;
1142  g = tmp;
1143  }
1144  if (g == zero) return(f);
1145  if (g == one) return(Cudd_Not(f));
1146  if (Cudd_IsComplement(f)) {
1147  f = Cudd_Not(f);
1148  g = Cudd_Not(g);
1149  }
1150  /* Now the first argument is regular. */
1151  if (f == one) return(Cudd_Not(g));
1152 
1153  /* At this point f and g are not constant. */
1154 
1155  /* Check cache. */
1156  r = cuddCacheLookup2(manager, Cudd_bddXor, f, g);
1157  if (r != NULL) return(r);
1158 
1159  /* Here we can skip the use of cuddI, because the operands are known
1160  ** to be non-constant.
1161  */
1162  topf = manager->perm[f->index];
1163  G = Cudd_Regular(g);
1164  topg = manager->perm[G->index];
1165 
1166  /* Compute cofactors. */
1167  if (topf <= topg) {
1168  index = f->index;
1169  fv = cuddT(f);
1170  fnv = cuddE(f);
1171  } else {
1172  index = G->index;
1173  fv = fnv = f;
1174  }
1175 
1176  if (topg <= topf) {
1177  gv = cuddT(G);
1178  gnv = cuddE(G);
1179  if (Cudd_IsComplement(g)) {
1180  gv = Cudd_Not(gv);
1181  gnv = Cudd_Not(gnv);
1182  }
1183  } else {
1184  gv = gnv = g;
1185  }
1186 
1187  t = cuddBddXorRecur(manager, fv, gv);
1188  if (t == NULL) return(NULL);
1189  cuddRef(t);
1190 
1191  e = cuddBddXorRecur(manager, fnv, gnv);
1192  if (e == NULL) {
1193  Cudd_IterDerefBdd(manager, t);
1194  return(NULL);
1195  }
1196  cuddRef(e);
1197 
1198  if (t == e) {
1199  r = t;
1200  } else {
1201  if (Cudd_IsComplement(t)) {
1202  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
1203  if (r == NULL) {
1204  Cudd_IterDerefBdd(manager, t);
1205  Cudd_IterDerefBdd(manager, e);
1206  return(NULL);
1207  }
1208  r = Cudd_Not(r);
1209  } else {
1210  r = cuddUniqueInter(manager,(int)index,t,e);
1211  if (r == NULL) {
1212  Cudd_IterDerefBdd(manager, t);
1213  Cudd_IterDerefBdd(manager, e);
1214  return(NULL);
1215  }
1216  }
1217  }
1218  cuddDeref(e);
1219  cuddDeref(t);
1220  cuddCacheInsert2(manager, Cudd_bddXor, f, g, r);
1221  return(r);
1222 
1223 } /* end of cuddBddXorRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode * Cudd_bddXor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:549
#define cuddT(node)
Definition: cuddInt.h:609
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1123
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137

◆ cuddBiasedUnderApprox()

DdNode* cuddBiasedUnderApprox ( DdManager dd,
DdNode f,
DdNode b,
int  numVars,
int  threshold,
double  quality1,
double  quality0 
)

◆ cuddCacheFlush()

void cuddCacheFlush ( DdManager table)

Function********************************************************************

Synopsis [Flushes the cache.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1004 of file cuddCache.c.

1006 {
1007  int i, slots;
1008  DdCache *cache;
1009 
1010  slots = table->cacheSlots;
1011  cache = table->cache;
1012  for (i = 0; i < slots; i++) {
1013  table->cachedeletions += cache[i].data != NULL;
1014  cache[i].data = NULL;
1015  }
1016  table->cacheLastInserts = table->cacheinserts;
1017 
1018  return;
1019 
1020 } /* end of cuddCacheFlush */
DdNode * data
Definition: cuddInt.h:304
double cacheinserts
Definition: cuddInt.h:438
unsigned int cacheSlots
Definition: cuddInt.h:337
DdCache * cache
Definition: cuddInt.h:336
double cacheLastInserts
Definition: cuddInt.h:439
double cachedeletions
Definition: cuddInt.h:440

◆ cuddCacheInsert()

void cuddCacheInsert ( DdManager table,
ptruint  op,
DdNode f,
DdNode g,
DdNode h,
DdNode data 
)

Function********************************************************************

Synopsis [Inserts a result in the cache for a function with three operands.]

Description [Inserts a result in the cache for a function with three operands. The operator tag (see CUDD/cuddInt.h for details) is split and stored into unused bits of the first two pointers.]

SideEffects [None]

SeeAlso [cuddCacheInsert2 cuddCacheInsert1]

Definition at line 217 of file cuddCache.c.

224 {
225  int posn;
226  register DdCache *entry;
227  ptruint uf, ug, uh;
228 
229  uf = (ptruint) f | (op & 0xe);
230  ug = (ptruint) g | (op >> 4);
231  uh = (ptruint) h;
232 
233  posn = ddCHash2(uh,uf,ug,table->cacheShift);
234  entry = &table->cache[posn];
235 
236  table->cachecollisions += entry->data != NULL;
237  table->cacheinserts++;
238 
239  entry->f = (DdNode *) uf;
240  entry->g = (DdNode *) ug;
241  entry->h = uh;
242  entry->data = data;
243 #ifdef DD_CACHE_PROFILE
244  entry->count++;
245 #endif
246 
247 } /* end of cuddCacheInsert */
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:270
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
DdNode * g
Definition: cuddInt.h:302
double cachecollisions
Definition: cuddInt.h:437
double cacheinserts
Definition: cuddInt.h:438
static int * entry
Definition: cuddGroup.c:119
DdCache * cache
Definition: cuddInt.h:336
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
int cacheShift
Definition: cuddInt.h:338

◆ cuddCacheInsert1()

void cuddCacheInsert1 ( DdManager table,
DdNode *)(DdManager *, DdNode *,
DdNode f,
DdNode data 
)

◆ cuddCacheInsert2()

void cuddCacheInsert2 ( DdManager table,
DdNode *)(DdManager *, DdNode *, DdNode *,
DdNode f,
DdNode g,
DdNode data 
)

◆ cuddCacheLookup()

DdNode* cuddCacheLookup ( DdManager table,
ptruint  op,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Looks up in the cache for the result of op applied to f, g, and h.]

Description [Returns the result if found; it returns NULL if no result is found.]

SideEffects [None]

SeeAlso [cuddCacheLookup2 cuddCacheLookup1]

Definition at line 347 of file cuddCache.c.

353 {
354  int posn;
355  DdCache *en,*cache;
356  DdNode *data;
357  ptruint uf, ug, uh;
358 
359  uf = (ptruint) f | (op & 0xe);
360  ug = (ptruint) g | (op >> 4);
361  uh = (ptruint) h;
362 
363  cache = table->cache;
364 #ifdef DD_DEBUG
365  if (cache == NULL) {
366  return(NULL);
367  }
368 #endif
369 
370  posn = ddCHash2(uh,uf,ug,table->cacheShift);
371  en = &cache[posn];
372  if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug &&
373  en->h==uh) {
374  data = Cudd_Regular(en->data);
375  table->cacheHits++;
376  if (data->ref == 0) {
377  cuddReclaim(table,data);
378  }
379  return(en->data);
380  }
381 
382  /* Cache miss: decide whether to resize. */
383  table->cacheMisses++;
384 
385  if (table->cacheSlack >= 0 &&
386  table->cacheHits > table->cacheMisses * table->minHit) {
387  cuddCacheResize(table);
388  }
389 
390  return(NULL);
391 
392 } /* end of cuddCacheLookup */
DdHalfWord ref
Definition: cudd.h:272
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:270
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
#define Cudd_Regular(node)
Definition: cudd.h:384
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddRef.c:580
DdNode * g
Definition: cuddInt.h:302
DdCache * cache
Definition: cuddInt.h:336
double cacheHits
Definition: cuddInt.h:340
int cacheSlack
Definition: cuddInt.h:342
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338
void cuddCacheResize(DdManager *table)
Definition: cuddCache.c:889

◆ cuddCacheLookup1()

DdNode* cuddCacheLookup1 ( DdManager table,
DdNode *)(DdManager *, DdNode *,
DdNode f 
)

◆ cuddCacheLookup1Zdd()

DdNode* cuddCacheLookup1Zdd ( DdManager table,
DdNode *)(DdManager *, DdNode *,
DdNode f 
)

◆ cuddCacheLookup2()

DdNode* cuddCacheLookup2 ( DdManager table,
DdNode *)(DdManager *, DdNode *, DdNode *,
DdNode f,
DdNode g 
)

◆ cuddCacheLookup2Zdd()

DdNode* cuddCacheLookup2Zdd ( DdManager table,
DdNode *)(DdManager *, DdNode *, DdNode *,
DdNode f,
DdNode g 
)

◆ cuddCacheLookupZdd()

DdNode* cuddCacheLookupZdd ( DdManager table,
ptruint  op,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Looks up in the cache for the result of op applied to f, g, and h.]

Description [Returns the result if found; it returns NULL if no result is found.]

SideEffects [None]

SeeAlso [cuddCacheLookup2Zdd cuddCacheLookup1Zdd]

Definition at line 409 of file cuddCache.c.

415 {
416  int posn;
417  DdCache *en,*cache;
418  DdNode *data;
419  ptruint uf, ug, uh;
420 
421  uf = (ptruint) f | (op & 0xe);
422  ug = (ptruint) g | (op >> 4);
423  uh = (ptruint) h;
424 
425  cache = table->cache;
426 #ifdef DD_DEBUG
427  if (cache == NULL) {
428  return(NULL);
429  }
430 #endif
431 
432  posn = ddCHash2(uh,uf,ug,table->cacheShift);
433  en = &cache[posn];
434  if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug &&
435  en->h==uh) {
436  data = Cudd_Regular(en->data);
437  table->cacheHits++;
438  if (data->ref == 0) {
439  cuddReclaimZdd(table,data);
440  }
441  return(en->data);
442  }
443 
444  /* Cache miss: decide whether to resize. */
445  table->cacheMisses++;
446 
447  if (table->cacheSlack >= 0 &&
448  table->cacheHits > table->cacheMisses * table->minHit) {
449  cuddCacheResize(table);
450  }
451 
452  return(NULL);
453 
454 } /* end of cuddCacheLookupZdd */
DdHalfWord ref
Definition: cudd.h:272
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:270
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
#define Cudd_Regular(node)
Definition: cudd.h:384
DdNode * g
Definition: cuddInt.h:302
DdCache * cache
Definition: cuddInt.h:336
double cacheHits
Definition: cuddInt.h:340
int cacheSlack
Definition: cuddInt.h:342
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
void cuddReclaimZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:634
unsigned int ptruint
Definition: cuddInt.h:250
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338
void cuddCacheResize(DdManager *table)
Definition: cuddCache.c:889

◆ cuddCacheProfile()

int cuddCacheProfile ( DdManager table,
FILE *  fp 
)

Function********************************************************************

Synopsis [Computes and prints a profile of the cache usage.]

Description [Computes and prints a profile of the cache usage. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 749 of file cuddCache.c.

752 {
753  DdCache *cache = table->cache;
754  int slots = table->cacheSlots;
755  int nzeroes = 0;
756  int i, retval;
757  double exUsed;
758 
759 #ifdef DD_CACHE_PROFILE
760  double count, mean, meansq, stddev, expected;
761  long max, min;
762  int imax, imin;
763  double *hystogramQ, *hystogramR; /* histograms by quotient and remainder */
764  int nbins = DD_HYSTO_BINS;
765  int bin;
766  long thiscount;
767  double totalcount, exStddev;
768 
769  meansq = mean = expected = 0.0;
770  max = min = (long) cache[0].count;
771  imax = imin = 0;
772  totalcount = 0.0;
773 
774  hystogramQ = ALLOC(double, nbins);
775  if (hystogramQ == NULL) {
776  table->errorCode = CUDD_MEMORY_OUT;
777  return(0);
778  }
779  hystogramR = ALLOC(double, nbins);
780  if (hystogramR == NULL) {
781  FREE(hystogramQ);
782  table->errorCode = CUDD_MEMORY_OUT;
783  return(0);
784  }
785  for (i = 0; i < nbins; i++) {
786  hystogramQ[i] = 0;
787  hystogramR[i] = 0;
788  }
789 
790  for (i = 0; i < slots; i++) {
791  thiscount = (long) cache[i].count;
792  if (thiscount > max) {
793  max = thiscount;
794  imax = i;
795  }
796  if (thiscount < min) {
797  min = thiscount;
798  imin = i;
799  }
800  if (thiscount == 0) {
801  nzeroes++;
802  }
803  count = (double) thiscount;
804  mean += count;
805  meansq += count * count;
806  totalcount += count;
807  expected += count * (double) i;
808  bin = (i * nbins) / slots;
809  hystogramQ[bin] += (double) thiscount;
810  bin = i % nbins;
811  hystogramR[bin] += (double) thiscount;
812  }
813  mean /= (double) slots;
814  meansq /= (double) slots;
815 
816  /* Compute the standard deviation from both the data and the
817  ** theoretical model for a random distribution. */
818  stddev = sqrt(meansq - mean*mean);
819  exStddev = sqrt((1 - 1/(double) slots) * totalcount / (double) slots);
820 
821  retval = fprintf(fp,"Cache average accesses = %g\n", mean);
822  if (retval == EOF) return(0);
823  retval = fprintf(fp,"Cache access standard deviation = %g ", stddev);
824  if (retval == EOF) return(0);
825  retval = fprintf(fp,"(expected = %g)\n", exStddev);
826  if (retval == EOF) return(0);
827  retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax);
828  if (retval == EOF) return(0);
829  retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin);
830  if (retval == EOF) return(0);
831  exUsed = 100.0 * (1.0 - exp(-totalcount / (double) slots));
832  retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n",
833  100.0 - (double) nzeroes * 100.0 / (double) slots,
834  exUsed);
835  if (retval == EOF) return(0);
836 
837  if (totalcount > 0) {
838  expected /= totalcount;
839  retval = fprintf(fp,"Cache access hystogram for %d bins", nbins);
840  if (retval == EOF) return(0);
841  retval = fprintf(fp," (expected bin value = %g)\nBy quotient:",
842  expected);
843  if (retval == EOF) return(0);
844  for (i = nbins - 1; i>=0; i--) {
845  retval = fprintf(fp," %.0f", hystogramQ[i]);
846  if (retval == EOF) return(0);
847  }
848  retval = fprintf(fp,"\nBy residue: ");
849  if (retval == EOF) return(0);
850  for (i = nbins - 1; i>=0; i--) {
851  retval = fprintf(fp," %.0f", hystogramR[i]);
852  if (retval == EOF) return(0);
853  }
854  retval = fprintf(fp,"\n");
855  if (retval == EOF) return(0);
856  }
857 
858  FREE(hystogramQ);
859  FREE(hystogramR);
860 #else
861  for (i = 0; i < slots; i++) {
862  nzeroes += cache[i].h == 0;
863  }
864  exUsed = 100.0 *
865  (1.0 - exp(-(table->cacheinserts - table->cacheLastInserts) /
866  (double) slots));
867  retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n",
868  100.0 - (double) nzeroes * 100.0 / (double) slots,
869  exUsed);
870  if (retval == EOF) return(0);
871 #endif
872  return(1);
873 
874 } /* end of cuddCacheProfile */
#define FREE(obj)
Definition: util.h:80
ptruint h
Definition: cuddInt.h:303
double cacheinserts
Definition: cuddInt.h:438
unsigned int cacheSlots
Definition: cuddInt.h:337
#define ALLOC(type, num)
Definition: util.h:76
DdCache * cache
Definition: cuddInt.h:336
double cacheLastInserts
Definition: cuddInt.h:439
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddCacheResize()

void cuddCacheResize ( DdManager table)

Function********************************************************************

Synopsis [Resizes the cache.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 889 of file cuddCache.c.

891 {
892  DdCache *cache, *oldcache, *oldacache, *entry, *old;
893  int i;
894  int posn, shift;
895  unsigned int slots, oldslots;
896  double offset;
897  int moved = 0;
898  extern DD_OOMFP MMoutOfMemory;
899  DD_OOMFP saveHandler;
900 #ifndef DD_CACHE_PROFILE
901  ptruint misalignment;
902  DdNodePtr *mem;
903 #endif
904 
905  oldcache = table->cache;
906  oldacache = table->acache;
907  oldslots = table->cacheSlots;
908  slots = table->cacheSlots = oldslots << 1;
909 
910 #ifdef DD_VERBOSE
911  (void) fprintf(table->err,"Resizing the cache from %d to %d entries\n",
912  oldslots, slots);
913  (void) fprintf(table->err,
914  "\thits = %g\tmisses = %g\thit ratio = %5.3f\n",
915  table->cacheHits, table->cacheMisses,
916  table->cacheHits / (table->cacheHits + table->cacheMisses));
917 #endif
918 
919  saveHandler = MMoutOfMemory;
920  MMoutOfMemory = Cudd_OutOfMem;
921  table->acache = cache = ALLOC(DdCache,slots+1);
922  MMoutOfMemory = saveHandler;
923  /* If we fail to allocate the new table we just give up. */
924  if (cache == NULL) {
925 #ifdef DD_VERBOSE
926  (void) fprintf(table->err,"Resizing failed. Giving up.\n");
927 #endif
928  table->cacheSlots = oldslots;
929  table->acache = oldacache;
930  /* Do not try to resize again. */
931  table->maxCacheHard = oldslots - 1;
932  table->cacheSlack = - (int) (oldslots + 1);
933  return;
934  }
935  /* If the size of the cache entry is a power of 2, we want to
936  ** enforce alignment to that power of two. This happens when
937  ** DD_CACHE_PROFILE is not defined. */
938 #ifdef DD_CACHE_PROFILE
939  table->cache = cache;
940 #else
941  mem = (DdNodePtr *) cache;
942  misalignment = (ptruint) mem & (sizeof(DdCache) - 1);
943  mem += (sizeof(DdCache) - misalignment) / sizeof(DdNodePtr);
944  table->cache = cache = (DdCache *) mem;
945  assert(((ptruint) table->cache & (sizeof(DdCache) - 1)) == 0);
946 #endif
947  shift = --(table->cacheShift);
948  table->memused += (slots - oldslots) * sizeof(DdCache);
949  table->cacheSlack -= slots; /* need these many slots to double again */
950 
951  /* Clear new cache. */
952  for (i = 0; (unsigned) i < slots; i++) {
953  cache[i].data = NULL;
954  cache[i].h = 0;
955 #ifdef DD_CACHE_PROFILE
956  cache[i].count = 0;
957 #endif
958  }
959 
960  /* Copy from old cache to new one. */
961  for (i = 0; (unsigned) i < oldslots; i++) {
962  old = &oldcache[i];
963  if (old->data != NULL) {
964  posn = ddCHash2(old->h,old->f,old->g,shift);
965  entry = &cache[posn];
966  entry->f = old->f;
967  entry->g = old->g;
968  entry->h = old->h;
969  entry->data = old->data;
970 #ifdef DD_CACHE_PROFILE
971  entry->count = 1;
972 #endif
973  moved++;
974  }
975  }
976 
977  FREE(oldacache);
978 
979  /* Reinitialize measurements so as to avoid division by 0 and
980  ** immediate resizing.
981  */
982  offset = (double) (int) (slots * table->minHit + 1);
983  table->totCacheMisses += table->cacheMisses - offset;
984  table->cacheMisses = offset;
985  table->totCachehits += table->cacheHits;
986  table->cacheHits = 0;
987  table->cacheLastInserts = table->cacheinserts - (double) moved;
988 
989 } /* end of cuddCacheResize */
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2845
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
DdNode * data
Definition: cuddInt.h:304
#define assert(ex)
Definition: util.h:141
unsigned int maxCacheHard
Definition: cuddInt.h:343
ptruint h
Definition: cuddInt.h:303
FILE * err
Definition: cuddInt.h:424
DdNode * g
Definition: cuddInt.h:302
DdNode * DdNodePtr
Definition: cuddInt.h:253
double cacheinserts
Definition: cuddInt.h:438
void(* DD_OOMFP)(long)
Definition: cudd.h:311
static int * entry
Definition: cuddGroup.c:119
unsigned int cacheSlots
Definition: cuddInt.h:337
#define ALLOC(type, num)
Definition: util.h:76
DdCache * cache
Definition: cuddInt.h:336
double totCacheMisses
Definition: cuddInt.h:436
double cacheLastInserts
Definition: cuddInt.h:439
double cacheHits
Definition: cuddInt.h:340
int cacheSlack
Definition: cuddInt.h:342
void(* MMoutOfMemory)(long)
Definition: safe_mem.c:32
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned long memused
Definition: cuddInt.h:429
unsigned int ptruint
Definition: cuddInt.h:250
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338
DdCache * acache
Definition: cuddInt.h:335
struct DdCache DdCache
double totCachehits
Definition: cuddInt.h:435

◆ cuddClearDeathRow()

void cuddClearDeathRow ( DdManager table)

Function********************************************************************

Synopsis [Clears the death row.]

Description []

SideEffects [None]

SeeAlso [Cudd_DelayedDerefBdd Cudd_IterDerefBdd Cudd_CheckZeroRef cuddGarbageCollect]

Definition at line 722 of file cuddRef.c.

724 {
725 #ifndef DD_NO_DEATH_ROW
726  int i;
727 
728  for (i = 0; i < table->deathRowDepth; i++) {
729  if (table->deathRow[i] == NULL) break;
730  Cudd_IterDerefBdd(table,table->deathRow[i]);
731  table->deathRow[i] = NULL;
732  }
733 #ifdef DD_DEBUG
734  for (; i < table->deathRowDepth; i++) {
735  assert(table->deathRow[i] == NULL);
736  }
737 #endif
738  table->nextDead = 0;
739 #endif
740 
741 } /* end of cuddClearDeathRow */
#define assert(ex)
Definition: util.h:141
DdNode ** deathRow
Definition: cuddInt.h:384
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
int nextDead
Definition: cuddInt.h:386
int deathRowDepth
Definition: cuddInt.h:385

◆ cuddCofactorRecur()

DdNode* cuddCofactorRecur ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_Cofactor.]

Description [Performs the recursive step of Cudd_Cofactor. Returns a pointer to the cofactor if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_Cofactor]

Definition at line 226 of file cuddCof.c.

230 {
231  DdNode *one,*zero,*F,*G,*g1,*g0,*f1,*f0,*t,*e,*r;
232  unsigned int topf,topg;
233  int comple;
234 
235  statLine(dd);
236  F = Cudd_Regular(f);
237  if (cuddIsConstant(F)) return(f);
238 
239  one = DD_ONE(dd);
240 
241  /* The invariant g != 0 is true on entry to this procedure and is
242  ** recursively maintained by it. Therefore it suffices to test g
243  ** against one to make sure it is not constant.
244  */
245  if (g == one) return(f);
246  /* From now on, f and g are known not to be constants. */
247 
248  comple = f != F;
249  r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g);
250  if (r != NULL) {
251  return(Cudd_NotCond(r,comple));
252  }
253 
254  topf = dd->perm[F->index];
255  G = Cudd_Regular(g);
256  topg = dd->perm[G->index];
257 
258  /* We take the cofactors of F because we are going to rely on
259  ** the fact that the cofactors of the complement are the complements
260  ** of the cofactors to better utilize the cache. Variable comple
261  ** remembers whether we have to complement the result or not.
262  */
263  if (topf <= topg) {
264  f1 = cuddT(F); f0 = cuddE(F);
265  } else {
266  f1 = f0 = F;
267  }
268  if (topg <= topf) {
269  g1 = cuddT(G); g0 = cuddE(G);
270  if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); }
271  } else {
272  g1 = g0 = g;
273  }
274 
275  zero = Cudd_Not(one);
276  if (topf >= topg) {
277  if (g0 == zero || g0 == DD_ZERO(dd)) {
278  r = cuddCofactorRecur(dd, f1, g1);
279  } else if (g1 == zero || g1 == DD_ZERO(dd)) {
280  r = cuddCofactorRecur(dd, f0, g0);
281  } else {
282  (void) fprintf(dd->out,
283  "Cudd_Cofactor: Invalid restriction 2\n");
285  return(NULL);
286  }
287  if (r == NULL) return(NULL);
288  } else /* if (topf < topg) */ {
289  t = cuddCofactorRecur(dd, f1, g);
290  if (t == NULL) return(NULL);
291  cuddRef(t);
292  e = cuddCofactorRecur(dd, f0, g);
293  if (e == NULL) {
294  Cudd_RecursiveDeref(dd, t);
295  return(NULL);
296  }
297  cuddRef(e);
298 
299  if (t == e) {
300  r = t;
301  } else if (Cudd_IsComplement(t)) {
302  r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e));
303  if (r != NULL)
304  r = Cudd_Not(r);
305  } else {
306  r = cuddUniqueInter(dd,(int)F->index,t,e);
307  }
308  if (r == NULL) {
309  Cudd_RecursiveDeref(dd ,e);
310  Cudd_RecursiveDeref(dd ,t);
311  return(NULL);
312  }
313  cuddDeref(t);
314  cuddDeref(e);
315  }
316 
318 
319  return(Cudd_NotCond(r,comple));
320 
321 } /* end of cuddCofactorRecur */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_Regular(node)
Definition: cudd.h:384
DdNode * Cudd_Cofactor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddCof.c:119
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
FILE * out
Definition: cuddInt.h:423
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddCofactorRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddCof.c:226
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddCollectNodes()

int cuddCollectNodes ( DdNode f,
st_table visited 
)

Function********************************************************************

Synopsis [Recursively collects all the nodes of a DD in a symbol table.]

Description [Traverses the DD f and collects all its nodes in a symbol table. f is assumed to be a regular pointer and cuddCollectNodes guarantees this assumption in the recursive calls. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 2933 of file cuddUtil.c.

2936 {
2937  DdNode *T, *E;
2938  int retval;
2939 
2940 #ifdef DD_DEBUG
2942 #endif
2943 
2944  /* If already visited, nothing to do. */
2945  if (st_is_member(visited, (char *) f) == 1)
2946  return(1);
2947 
2948  /* Check for abnormal condition that should never happen. */
2949  if (f == NULL)
2950  return(0);
2951 
2952  /* Mark node as visited. */
2953  if (st_add_direct(visited, (char *) f, NULL) == ST_OUT_OF_MEM)
2954  return(0);
2955 
2956  /* Check terminal case. */
2957  if (cuddIsConstant(f))
2958  return(1);
2959 
2960  /* Recursive calls. */
2961  T = cuddT(f);
2962  retval = cuddCollectNodes(T,visited);
2963  if (retval != 1) return(retval);
2964  E = Cudd_Regular(cuddE(f));
2965  retval = cuddCollectNodes(E,visited);
2966  return(retval);
2967 
2968 } /* end of cuddCollectNodes */
int cuddCollectNodes(DdNode *f, st_table *visited)
Definition: cuddUtil.c:2933
Definition: cudd.h:270
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:384
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define ST_OUT_OF_MEM
Definition: st.h:41
int st_add_direct(st_table *, void *, void *)
Definition: st.c:410
#define st_is_member(table, key)
Definition: st.h:107
#define cuddE(node)
Definition: cuddInt.h:625

◆ cuddComputeFloorLog2()

int cuddComputeFloorLog2 ( unsigned int  value)

Function********************************************************************

Synopsis [Returns the floor of the logarithm to the base 2.]

Description [Returns the floor of the logarithm to the base 2. The input value is assumed to be greater than 0.]

SideEffects [None]

SeeAlso []

Definition at line 1036 of file cuddCache.c.

1038 {
1039  int floorLog = 0;
1040 #ifdef DD_DEBUG
1041  assert(value > 0);
1042 #endif
1043  while (value > 1) {
1044  floorLog++;
1045  value >>= 1;
1046  }
1047  return(floorLog);
1048 
1049 } /* end of cuddComputeFloorLog2 */
#define assert(ex)
Definition: util.h:141

◆ cuddConstantLookup()

DdNode* cuddConstantLookup ( DdManager table,
ptruint  op,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Looks up in the cache for the result of op applied to f, g, and h.]

Description [Looks up in the cache for the result of op applied to f, g, and h. Assumes that the calling procedure (e.g., Cudd_bddIteConstant) is only interested in whether the result is constant or not. Returns the result if found (possibly DD_NON_CONSTANT); otherwise it returns NULL.]

SideEffects [None]

SeeAlso [cuddCacheLookup]

Definition at line 690 of file cuddCache.c.

696 {
697  int posn;
698  DdCache *en,*cache;
699  ptruint uf, ug, uh;
700 
701  uf = (ptruint) f | (op & 0xe);
702  ug = (ptruint) g | (op >> 4);
703  uh = (ptruint) h;
704 
705  cache = table->cache;
706 #ifdef DD_DEBUG
707  if (cache == NULL) {
708  return(NULL);
709  }
710 #endif
711  posn = ddCHash2(uh,uf,ug,table->cacheShift);
712  en = &cache[posn];
713 
714  /* We do not reclaim here because the result should not be
715  * referenced, but only tested for being a constant.
716  */
717  if (en->data != NULL &&
718  en->f == (DdNodePtr)uf && en->g == (DdNodePtr)ug && en->h == uh) {
719  table->cacheHits++;
720  return(en->data);
721  }
722 
723  /* Cache miss: decide whether to resize. */
724  table->cacheMisses++;
725 
726  if (table->cacheSlack >= 0 &&
727  table->cacheHits > table->cacheMisses * table->minHit) {
728  cuddCacheResize(table);
729  }
730 
731  return(NULL);
732 
733 } /* end of cuddConstantLookup */
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:270
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
DdNode * g
Definition: cuddInt.h:302
DdCache * cache
Definition: cuddInt.h:336
double cacheHits
Definition: cuddInt.h:340
int cacheSlack
Definition: cuddInt.h:342
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338
void cuddCacheResize(DdManager *table)
Definition: cuddCache.c:889

◆ cuddCProjectionRecur()

DdNode* cuddCProjectionRecur ( DdManager dd,
DdNode R,
DdNode Y,
DdNode Ysupp 
)

◆ cuddDestroySubtables()

int cuddDestroySubtables ( DdManager unique,
int  n 
)

Function********************************************************************

Synopsis [Destroys the n most recently created subtables in a unique table.]

Description [Destroys the n most recently created subtables in a unique table. n should be positive. The subtables should not contain any live nodes, except the (isolated) projection function. The projection functions are freed. Returns 1 if successful; 0 otherwise.]

SideEffects [The variable map used for fast variable substitution is destroyed if it exists. In this case the cache is also cleared.]

SeeAlso [cuddInsertSubtables Cudd_SetVarMap]

Definition at line 2137 of file cuddTable.c.

2140 {
2141  DdSubtable *subtables;
2142  DdNodePtr *nodelist;
2143  DdNodePtr *vars;
2144  int firstIndex, lastIndex;
2145  int index, level, newlevel;
2146  int lowestLevel;
2147  int shift;
2148  int found;
2149 
2150  /* Sanity check and set up. */
2151  if (n <= 0) return(0);
2152  if (n > unique->size) n = unique->size;
2153 
2154  subtables = unique->subtables;
2155  vars = unique->vars;
2156  firstIndex = unique->size - n;
2157  lastIndex = unique->size;
2158 
2159  /* Check for nodes labeled by the variables being destroyed
2160  ** that may still be in use. It is allowed to destroy a variable
2161  ** only if there are no such nodes. Also, find the lowest level
2162  ** among the variables being destroyed. This will make further
2163  ** processing more efficient.
2164  */
2165  lowestLevel = unique->size;
2166  for (index = firstIndex; index < lastIndex; index++) {
2167  level = unique->perm[index];
2168  if (level < lowestLevel) lowestLevel = level;
2169  nodelist = subtables[level].nodelist;
2170  if (subtables[level].keys - subtables[level].dead != 1) return(0);
2171  /* The projection function should be isolated. If the ref count
2172  ** is 1, everything is OK. If the ref count is saturated, then
2173  ** we need to make sure that there are no nodes pointing to it.
2174  ** As for the external references, we assume the application is
2175  ** responsible for them.
2176  */
2177  if (vars[index]->ref != 1) {
2178  if (vars[index]->ref != DD_MAXREF) return(0);
2179  found = cuddFindParent(unique,vars[index]);
2180  if (found) {
2181  return(0);
2182  } else {
2183  vars[index]->ref = 1;
2184  }
2185  }
2186  Cudd_RecursiveDeref(unique,vars[index]);
2187  }
2188 
2189  /* Collect garbage, because we cannot afford having dead nodes pointing
2190  ** to the dead nodes in the subtables being destroyed.
2191  */
2192  (void) cuddGarbageCollect(unique,1);
2193 
2194  /* Here we know we can destroy our subtables. */
2195  for (index = firstIndex; index < lastIndex; index++) {
2196  level = unique->perm[index];
2197  nodelist = subtables[level].nodelist;
2198 #ifdef DD_DEBUG
2199  assert(subtables[level].keys == 0);
2200 #endif
2201  FREE(nodelist);
2202  unique->memused -= sizeof(DdNodePtr) * subtables[level].slots;
2203  unique->slots -= subtables[level].slots;
2204  unique->dead -= subtables[level].dead;
2205  }
2206 
2207  /* Here all subtables to be destroyed have their keys field == 0 and
2208  ** their hash tables have been freed.
2209  ** We now scan the subtables from level lowestLevel + 1 to level size - 1,
2210  ** shifting the subtables as required. We keep a running count of
2211  ** how many subtables have been moved, so that we know by how many
2212  ** positions each subtable should be shifted.
2213  */
2214  shift = 1;
2215  for (level = lowestLevel + 1; level < unique->size; level++) {
2216  if (subtables[level].keys == 0) {
2217  shift++;
2218  continue;
2219  }
2220  newlevel = level - shift;
2221  subtables[newlevel].slots = subtables[level].slots;
2222  subtables[newlevel].shift = subtables[level].shift;
2223  subtables[newlevel].keys = subtables[level].keys;
2224  subtables[newlevel].maxKeys = subtables[level].maxKeys;
2225  subtables[newlevel].dead = subtables[level].dead;
2226  subtables[newlevel].nodelist = subtables[level].nodelist;
2227  index = unique->invperm[level];
2228  unique->perm[index] = newlevel;
2229  unique->invperm[newlevel] = index;
2230  subtables[newlevel].bindVar = subtables[level].bindVar;
2231  subtables[newlevel].varType = subtables[level].varType;
2232  subtables[newlevel].pairIndex = subtables[level].pairIndex;
2233  subtables[newlevel].varHandled = subtables[level].varHandled;
2234  subtables[newlevel].varToBeGrouped = subtables[level].varToBeGrouped;
2235  }
2236  /* Destroy the map. If a surviving variable is
2237  ** mapped to a dying variable, and the map were used again,
2238  ** an out-of-bounds access to unique->vars would result. */
2239  if (unique->map != NULL) {
2240  cuddCacheFlush(unique);
2241  FREE(unique->map);
2242  unique->map = NULL;
2243  }
2244 
2245  unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots);
2246  unique->size -= n;
2247 
2248  return(1);
2249 
2250 } /* end of cuddDestroySubtables */
DdHalfWord ref
Definition: cudd.h:272
#define DD_MAXREF
Definition: cuddInt.h:101
unsigned int keys
Definition: cuddInt.h:314
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
int * map
Definition: cuddInt.h:374
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
double gcFrac
Definition: cuddInt.h:359
unsigned int slots
Definition: cuddInt.h:352
int bindVar
Definition: cuddInt.h:318
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode * DdNodePtr
Definition: cuddInt.h:253
Cudd_VariableType varType
Definition: cuddInt.h:320
unsigned int dead
Definition: cuddInt.h:355
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:762
unsigned int dead
Definition: cuddInt.h:316
Cudd_LazyGroupType varToBeGrouped
Definition: cuddInt.h:323
static int cuddFindParent(DdManager *table, DdNode *node)
Definition: cuddTable.c:2796
unsigned int maxKeys
Definition: cuddInt.h:315
DdNode ** nodelist
Definition: cuddInt.h:311
int varHandled
Definition: cuddInt.h:322
unsigned long memused
Definition: cuddInt.h:429
void cuddCacheFlush(DdManager *table)
Definition: cuddCache.c:1004
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
int pairIndex
Definition: cuddInt.h:321
int * invperm
Definition: cuddInt.h:371
int shift
Definition: cuddInt.h:312
int * perm
Definition: cuddInt.h:369
unsigned int minDead
Definition: cuddInt.h:358

◆ cuddDynamicAllocNode()

DdNode* cuddDynamicAllocNode ( DdManager table)

Function********************************************************************

Synopsis [Dynamically allocates a Node.]

Description [Dynamically allocates a Node. This procedure is similar to cuddAllocNode in Cudd_Table.c, but it does not attempt garbage collection, because during reordering there are no dead nodes. Returns a pointer to a new node if successful; NULL is memory is full.]

SideEffects [None]

SeeAlso [cuddAllocNode]

Definition at line 405 of file cuddReorder.c.

407 {
408  int i;
409  DdNodePtr *mem;
410  DdNode *list, *node;
411  extern DD_OOMFP MMoutOfMemory;
412  DD_OOMFP saveHandler;
413 
414  if (table->nextFree == NULL) { /* free list is empty */
415  /* Try to allocate a new block. */
416  saveHandler = MMoutOfMemory;
417  MMoutOfMemory = Cudd_OutOfMem;
418  mem = (DdNodePtr *) ALLOC(DdNode, DD_MEM_CHUNK + 1);
419  MMoutOfMemory = saveHandler;
420  if (mem == NULL && table->stash != NULL) {
421  FREE(table->stash);
422  table->stash = NULL;
423  /* Inhibit resizing of tables. */
424  table->maxCacheHard = table->cacheSlots - 1;
425  table->cacheSlack = - (int) (table->cacheSlots + 1);
426  for (i = 0; i < table->size; i++) {
427  table->subtables[i].maxKeys <<= 2;
428  }
429  mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1);
430  }
431  if (mem == NULL) {
432  /* Out of luck. Call the default handler to do
433  ** whatever it specifies for a failed malloc. If this
434  ** handler returns, then set error code, print
435  ** warning, and return. */
436  (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1));
437  table->errorCode = CUDD_MEMORY_OUT;
438 #ifdef DD_VERBOSE
439  (void) fprintf(table->err,
440  "cuddDynamicAllocNode: out of memory");
441  (void) fprintf(table->err,"Memory in use = %lu\n",
442  table->memused);
443 #endif
444  return(NULL);
445  } else { /* successful allocation; slice memory */
446  unsigned long offset;
447  table->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode);
448  mem[0] = (DdNode *) table->memoryList;
449  table->memoryList = mem;
450 
451  /* Here we rely on the fact that the size of a DdNode is a
452  ** power of 2 and a multiple of the size of a pointer.
453  ** If we align one node, all the others will be aligned
454  ** as well. */
455  offset = (unsigned long) mem & (sizeof(DdNode) - 1);
456  mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr);
457 #ifdef DD_DEBUG
458  assert(((unsigned long) mem & (sizeof(DdNode) - 1)) == 0);
459 #endif
460  list = (DdNode *) mem;
461 
462  i = 1;
463  do {
464  list[i - 1].ref = 0;
465  list[i - 1].next = &list[i];
466  } while (++i < DD_MEM_CHUNK);
467 
468  list[DD_MEM_CHUNK-1].ref = 0;
469  list[DD_MEM_CHUNK - 1].next = NULL;
470 
471  table->nextFree = &list[0];
472  }
473  } /* if free list empty */
474 
475  node = table->nextFree;
476  table->nextFree = node->next;
477  return (node);
478 
479 } /* end of cuddDynamicAllocNode */
DdHalfWord ref
Definition: cudd.h:272
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2845
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
unsigned int maxCacheHard
Definition: cuddInt.h:343
FILE * err
Definition: cuddInt.h:424
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode * DdNodePtr
Definition: cuddInt.h:253
void(* DD_OOMFP)(long)
Definition: cudd.h:311
struct DdNode DdNode
Definition: cudd.h:262
unsigned int cacheSlots
Definition: cuddInt.h:337
char * stash
Definition: cuddInt.h:382
#define ALLOC(type, num)
Definition: util.h:76
DdNode * next
Definition: cudd.h:273
unsigned int maxKeys
Definition: cuddInt.h:315
int cacheSlack
Definition: cuddInt.h:342
void(* MMoutOfMemory)(long)
Definition: safe_mem.c:32
DdNode ** memoryList
Definition: cuddInt.h:380
unsigned long memused
Definition: cuddInt.h:429
DdNode * nextFree
Definition: cuddInt.h:381
#define DD_MEM_CHUNK
Definition: cuddInt.h:105
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddExact()

int cuddExact ( DdManager table,
int  lower,
int  upper 
)

AutomaticEnd Function********************************************************************

Synopsis [Exact variable ordering algorithm.]

Description [Exact variable ordering algorithm. Finds an optimum order for the variables between lower and upper. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 149 of file cuddExact.c.

153 {
154  int k, i, j;
155  int maxBinomial, oldSubsets, newSubsets;
156  int subsetCost;
157  int size; /* number of variables to be reordered */
158  int unused, nvars, level, result;
159  int upperBound, lowerBound, cost;
160  int roots;
161  char *mask = NULL;
162  DdHalfWord *symmInfo = NULL;
163  DdHalfWord **newOrder = NULL;
164  DdHalfWord **oldOrder = NULL;
165  int *newCost = NULL;
166  int *oldCost = NULL;
167  DdHalfWord **tmpOrder;
168  int *tmpCost;
169  DdHalfWord *bestOrder = NULL;
170  DdHalfWord *order;
171 #ifdef DD_STATS
172  int ddTotalSubsets;
173 #endif
174 
175  /* Restrict the range to be reordered by excluding unused variables
176  ** at the two ends. */
177  while (table->subtables[lower].keys == 1 &&
178  table->vars[table->invperm[lower]]->ref == 1 &&
179  lower < upper)
180  lower++;
181  while (table->subtables[upper].keys == 1 &&
182  table->vars[table->invperm[upper]]->ref == 1 &&
183  lower < upper)
184  upper--;
185  if (lower == upper) return(1); /* trivial problem */
186 
187  /* Apply symmetric sifting to get a good upper bound and to extract
188  ** symmetry information. */
189  result = cuddSymmSiftingConv(table,lower,upper);
190  if (result == 0) goto cuddExactOutOfMem;
191 
192 #ifdef DD_STATS
193  (void) fprintf(table->out,"\n");
194  ddTotalShuffles = 0;
195  ddTotalSubsets = 0;
196 #endif
197 
198  /* Initialization. */
199  nvars = table->size;
200  size = upper - lower + 1;
201  /* Count unused variable among those to be reordered. This is only
202  ** used to compute maxBinomial. */
203  unused = 0;
204  for (i = lower + 1; i < upper; i++) {
205  if (table->subtables[i].keys == 1 &&
206  table->vars[table->invperm[i]]->ref == 1)
207  unused++;
208  }
209 
210  /* Find the maximum number of subsets we may have to store. */
211  maxBinomial = getMaxBinomial(size - unused);
212  if (maxBinomial == -1) goto cuddExactOutOfMem;
213 
214  newOrder = getMatrix(maxBinomial, size);
215  if (newOrder == NULL) goto cuddExactOutOfMem;
216 
217  newCost = ALLOC(int, maxBinomial);
218  if (newCost == NULL) goto cuddExactOutOfMem;
219 
220  oldOrder = getMatrix(maxBinomial, size);
221  if (oldOrder == NULL) goto cuddExactOutOfMem;
222 
223  oldCost = ALLOC(int, maxBinomial);
224  if (oldCost == NULL) goto cuddExactOutOfMem;
225 
226  bestOrder = ALLOC(DdHalfWord, size);
227  if (bestOrder == NULL) goto cuddExactOutOfMem;
228 
229  mask = ALLOC(char, nvars);
230  if (mask == NULL) goto cuddExactOutOfMem;
231 
232  symmInfo = initSymmInfo(table, lower, upper);
233  if (symmInfo == NULL) goto cuddExactOutOfMem;
234 
235  roots = ddCountRoots(table, lower, upper);
236 
237  /* Initialize the old order matrix for the empty subset and the best
238  ** order to the current order. The cost for the empty subset includes
239  ** the cost of the levels between upper and the constants. These levels
240  ** are not going to change. Hence, we count them only once.
241  */
242  oldSubsets = 1;
243  for (i = 0; i < size; i++) {
244  oldOrder[0][i] = bestOrder[i] = (DdHalfWord) table->invperm[i+lower];
245  }
246  subsetCost = table->constants.keys;
247  for (i = upper + 1; i < nvars; i++)
248  subsetCost += getLevelKeys(table,i);
249  oldCost[0] = subsetCost;
250  /* The upper bound is initialized to the current size of the BDDs. */
251  upperBound = table->keys - table->isolated;
252 
253  /* Now consider subsets of increasing size. */
254  for (k = 1; k <= size; k++) {
255 #ifdef DD_STATS
256  (void) fprintf(table->out,"Processing subsets of size %d\n", k);
257  fflush(table->out);
258 #endif
259  newSubsets = 0;
260  level = size - k; /* offset of first bottom variable */
261 
262  for (i = 0; i < oldSubsets; i++) { /* for each subset of size k-1 */
263  order = oldOrder[i];
264  cost = oldCost[i];
265  lowerBound = computeLB(table, order, roots, cost, lower, upper,
266  level);
267  if (lowerBound >= upperBound)
268  continue;
269  /* Impose new order. */
270  result = ddShuffle(table, order, lower, upper);
271  if (result == 0) goto cuddExactOutOfMem;
272  upperBound = updateUB(table,upperBound,bestOrder,lower,upper);
273  /* For each top bottom variable. */
274  for (j = level; j >= 0; j--) {
275  /* Skip unused variables. */
276  if (table->subtables[j+lower-1].keys == 1 &&
277  table->vars[table->invperm[j+lower-1]]->ref == 1) continue;
278  /* Find cost under this order. */
279  subsetCost = cost + getLevelKeys(table, lower + level);
280  newSubsets = updateEntry(table, order, level, subsetCost,
281  newOrder, newCost, newSubsets, mask,
282  lower, upper);
283  if (j == 0)
284  break;
285  if (checkSymmInfo(table, symmInfo, order[j-1], level) == 0)
286  continue;
287  pushDown(order,j-1,level);
288  /* Impose new order. */
289  result = ddShuffle(table, order, lower, upper);
290  if (result == 0) goto cuddExactOutOfMem;
291  upperBound = updateUB(table,upperBound,bestOrder,lower,upper);
292  } /* for each bottom variable */
293  } /* for each subset of size k */
294 
295  /* New orders become old orders in preparation for next iteration. */
296  tmpOrder = oldOrder; tmpCost = oldCost;
297  oldOrder = newOrder; oldCost = newCost;
298  newOrder = tmpOrder; newCost = tmpCost;
299 #ifdef DD_STATS
300  ddTotalSubsets += newSubsets;
301 #endif
302  oldSubsets = newSubsets;
303  }
304  result = ddShuffle(table, bestOrder, lower, upper);
305  if (result == 0) goto cuddExactOutOfMem;
306 #ifdef DD_STATS
307 #ifdef DD_VERBOSE
308  (void) fprintf(table->out,"\n");
309 #endif
310  (void) fprintf(table->out,"#:S_EXACT %8d: total subsets\n",
311  ddTotalSubsets);
312  (void) fprintf(table->out,"#:H_EXACT %8d: total shuffles",
313  ddTotalShuffles);
314 #endif
315 
316  freeMatrix(newOrder);
317  freeMatrix(oldOrder);
318  FREE(bestOrder);
319  FREE(oldCost);
320  FREE(newCost);
321  FREE(symmInfo);
322  FREE(mask);
323  return(1);
324 
325 cuddExactOutOfMem:
326 
327  if (newOrder != NULL) freeMatrix(newOrder);
328  if (oldOrder != NULL) freeMatrix(oldOrder);
329  if (bestOrder != NULL) FREE(bestOrder);
330  if (oldCost != NULL) FREE(oldCost);
331  if (newCost != NULL) FREE(newCost);
332  if (symmInfo != NULL) FREE(symmInfo);
333  if (mask != NULL) FREE(mask);
334  table->errorCode = CUDD_MEMORY_OUT;
335  return(0);
336 
337 } /* end of cuddExact */
DdHalfWord ref
Definition: cudd.h:272
unsigned int keys
Definition: cuddInt.h:314
unsigned short DdHalfWord
Definition: cudd.h:259
static int ddShuffle(DdManager *table, DdHalfWord *permutation, int lower, int upper)
Definition: cuddExact.c:537
static int computeLB(DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level)
Definition: cuddExact.c:809
#define FREE(obj)
Definition: util.h:80
static void freeMatrix(DdHalfWord **matrix)
Definition: cuddExact.c:482
static int getMaxBinomial(int n)
Definition: cuddExact.c:359
int size
Definition: cuddInt.h:345
static int getLevelKeys(DdManager *table, int l)
Definition: cuddExact.c:505
static void pushDown(DdHalfWord *order, int j, int level)
Definition: cuddExact.c:930
DdSubtable * subtables
Definition: cuddInt.h:349
static int updateUB(DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper)
Definition: cuddExact.c:654
int cuddSymmSiftingConv(DdManager *table, int lower, int upper)
Definition: cuddSymmetry.c:439
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static DdHalfWord ** getMatrix(int rows, int cols)
Definition: cuddExact.c:447
static int checkSymmInfo(DdManager *table, DdHalfWord *symmInfo, int index, int level)
Definition: cuddExact.c:1004
static int ddCountRoots(DdManager *table, int lower, int upper)
Definition: cuddExact.c:696
static DdHalfWord * initSymmInfo(DdManager *table, int lower, int upper)
Definition: cuddExact.c:968
static int updateEntry(DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper)
Definition: cuddExact.c:876
DdNode ** vars
Definition: cuddInt.h:373
int * invperm
Definition: cuddInt.h:371
DdSubtable constants
Definition: cuddInt.h:351
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddFreeTable()

void cuddFreeTable ( DdManager unique)

Function********************************************************************

Synopsis [Frees the resources associated to a unique table.]

Description []

SideEffects [None]

SeeAlso [cuddInitTable]

Definition at line 692 of file cuddTable.c.

694 {
695  DdNodePtr *next;
696  DdNodePtr *memlist = unique->memoryList;
697  int i;
698 
699  if (unique->univ != NULL) cuddZddFreeUniv(unique);
700  while (memlist != NULL) {
701  next = (DdNodePtr *) memlist[0]; /* link to next block */
702  FREE(memlist);
703  memlist = next;
704  }
705  unique->nextFree = NULL;
706  unique->memoryList = NULL;
707 
708  for (i = 0; i < unique->size; i++) {
709  FREE(unique->subtables[i].nodelist);
710  }
711  for (i = 0; i < unique->sizeZ; i++) {
712  FREE(unique->subtableZ[i].nodelist);
713  }
714  FREE(unique->constants.nodelist);
715  FREE(unique->subtables);
716  FREE(unique->subtableZ);
717  FREE(unique->acache);
718  FREE(unique->perm);
719  FREE(unique->permZ);
720  FREE(unique->invperm);
721  FREE(unique->invpermZ);
722  FREE(unique->vars);
723  if (unique->map != NULL) FREE(unique->map);
724  FREE(unique->stack);
725 #ifndef DD_NO_DEATH_ROW
726  FREE(unique->deathRow);
727 #endif
728  if (unique->tree != NULL) Mtr_FreeTree(unique->tree);
729  if (unique->treeZ != NULL) Mtr_FreeTree(unique->treeZ);
730  if (unique->linear != NULL) FREE(unique->linear);
731  while (unique->preGCHook != NULL)
732  Cudd_RemoveHook(unique,unique->preGCHook->f,CUDD_PRE_GC_HOOK);
733  while (unique->postGCHook != NULL)
735  while (unique->preReorderingHook != NULL)
736  Cudd_RemoveHook(unique,unique->preReorderingHook->f,
738  while (unique->postReorderingHook != NULL)
739  Cudd_RemoveHook(unique,unique->postReorderingHook->f,
741  FREE(unique);
742 
743 } /* end of cuddFreeTable */
void cuddZddFreeUniv(DdManager *zdd)
Definition: cuddInit.c:294
int * map
Definition: cuddInt.h:374
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
DdHook * preReorderingHook
Definition: cuddInt.h:421
int * invpermZ
Definition: cuddInt.h:372
int size
Definition: cuddInt.h:345
void Mtr_FreeTree(MtrNode *node)
Definition: mtrBasic.c:187
DdSubtable * subtables
Definition: cuddInt.h:349
int * permZ
Definition: cuddInt.h:370
MtrNode * tree
Definition: cuddInt.h:408
DD_HFP f
Definition: cuddInt.h:241
DdNode ** deathRow
Definition: cuddInt.h:384
DdNode ** stack
Definition: cuddInt.h:364
DdHook * postReorderingHook
Definition: cuddInt.h:422
long * linear
Definition: cuddInt.h:378
DdNode ** nodelist
Definition: cuddInt.h:311
int Cudd_RemoveHook(DdManager *dd, DD_HFP f, Cudd_HookType where)
Definition: cuddAPI.c:3631
DdNode ** memoryList
Definition: cuddInt.h:380
DdNode * nextFree
Definition: cuddInt.h:381
int sizeZ
Definition: cuddInt.h:346
DdNode ** vars
Definition: cuddInt.h:373
DdHook * postGCHook
Definition: cuddInt.h:420
MtrNode * treeZ
Definition: cuddInt.h:409
int * invperm
Definition: cuddInt.h:371
DdSubtable constants
Definition: cuddInt.h:351
DdCache * acache
Definition: cuddInt.h:335
DdHook * preGCHook
Definition: cuddInt.h:419
int * perm
Definition: cuddInt.h:369
DdSubtable * subtableZ
Definition: cuddInt.h:350
DdNode ** univ
Definition: cuddInt.h:375

◆ cuddGa()

int cuddGa ( DdManager table,
int  lower,
int  upper 
)

AutomaticEnd Function********************************************************************

Synopsis [Genetic algorithm for DD reordering.]

Description [Genetic algorithm for DD reordering. The two children of a crossover will be stored in storedd[popsize] and storedd[popsize+1] — the last two slots in the storedd array. (This will make comparisons and replacement easy.) Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 188 of file cuddGenetic.c.

192 {
193  int i,n,m; /* dummy/loop vars */
194  int index;
195 #ifdef DD_STATS
196  double average_fitness;
197 #endif
198  int small; /* index of smallest DD in population */
199 
200  /* Do an initial sifting to produce at least one reasonable individual. */
201  if (!cuddSifting(table,lower,upper)) return(0);
202 
203  /* Get the initial values. */
204  numvars = upper - lower + 1; /* number of variables to be reordered */
205  if (table->populationSize == 0) {
206  popsize = 3 * numvars; /* population size is 3 times # of vars */
207  if (popsize > 120) {
208  popsize = 120; /* Maximum population size is 120 */
209  }
210  } else {
211  popsize = table->populationSize; /* user specified value */
212  }
213  if (popsize < 4) popsize = 4; /* enforce minimum population size */
214 
215  /* Allocate population table. */
216  storedd = ALLOC(int,(popsize+2)*(numvars+1));
217  if (storedd == NULL) {
218  table->errorCode = CUDD_MEMORY_OUT;
219  return(0);
220  }
221 
222  /* Initialize the computed table. This table is made up of two data
223  ** structures: A hash table with the key given by the order, which says
224  ** if a given order is present in the population; and the repeat
225  ** vector, which says how many copies of a given order are stored in
226  ** the population table. If there are multiple copies of an order, only
227  ** one has a repeat count greater than 1. This copy is the one pointed
228  ** by the computed table.
229  */
230  repeat = ALLOC(int,popsize);
231  if (repeat == NULL) {
232  table->errorCode = CUDD_MEMORY_OUT;
233  FREE(storedd);
234  return(0);
235  }
236  for (i = 0; i < popsize; i++) {
237  repeat[i] = 0;
238  }
240  if (computed == NULL) {
241  table->errorCode = CUDD_MEMORY_OUT;
242  FREE(storedd);
243  FREE(repeat);
244  return(0);
245  }
246 
247  /* Copy the current DD and its size to the population table. */
248  for (i = 0; i < numvars; i++) {
249  STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */
250  }
251  STOREDD(0,numvars) = table->keys - table->isolated; /* size of initial DD */
252 
253  /* Store the initial order in the computed table. */
254  if (st_insert(computed,(char *)storedd,(char *) 0) == ST_OUT_OF_MEM) {
255  FREE(storedd);
256  FREE(repeat);
258  return(0);
259  }
260  repeat[0]++;
261 
262  /* Insert the reverse order as second element of the population. */
263  for (i = 0; i < numvars; i++) {
264  STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */
265  }
266 
267  /* Now create the random orders. make_random fills the population
268  ** table with random permutations. The successive loop builds and sifts
269  ** the DDs for the reverse order and each random permutation, and stores
270  ** the results in the computed table.
271  */
272  if (!make_random(table,lower)) {
273  table->errorCode = CUDD_MEMORY_OUT;
274  FREE(storedd);
275  FREE(repeat);
277  return(0);
278  }
279  for (i = 1; i < popsize; i++) {
280  result = build_dd(table,i,lower,upper); /* build and sift order */
281  if (!result) {
282  FREE(storedd);
283  FREE(repeat);
285  return(0);
286  }
287  if (st_lookup_int(computed,(char *)&STOREDD(i,0),&index)) {
288  repeat[index]++;
289  } else {
290  if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) ==
291  ST_OUT_OF_MEM) {
292  FREE(storedd);
293  FREE(repeat);
295  return(0);
296  }
297  repeat[i]++;
298  }
299  }
300 
301 #if 0
302 #ifdef DD_STATS
303  /* Print the initial population. */
304  (void) fprintf(table->out,"Initial population after sifting\n");
305  for (m = 0; m < popsize; m++) {
306  for (i = 0; i < numvars; i++) {
307  (void) fprintf(table->out," %2d",STOREDD(m,i));
308  }
309  (void) fprintf(table->out," : %3d (%d)\n",
310  STOREDD(m,numvars),repeat[m]);
311  }
312 #endif
313 #endif
314 
315  small = find_best();
316 #ifdef DD_STATS
317  average_fitness = find_average_fitness();
318  (void) fprintf(table->out,"\nInitial population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness);
319 #endif
320 
321  /* Decide how many crossovers should be tried. */
322  if (table->numberXovers == 0) {
323  cross = 3*numvars;
324  if (cross > 60) { /* do a maximum of 50 crossovers */
325  cross = 60;
326  }
327  } else {
328  cross = table->numberXovers; /* use user specified value */
329  }
330  if (cross >= popsize) {
331  cross = popsize;
332  }
333 
334  /* Perform the crossovers to get the best order. */
335  for (m = 0; m < cross; m++) {
336  if (!PMX(table->size)) { /* perform one crossover */
337  table->errorCode = CUDD_MEMORY_OUT;
338  FREE(storedd);
339  FREE(repeat);
341  return(0);
342  }
343  /* The offsprings are left in the last two entries of the
344  ** population table. These are now considered in turn.
345  */
346  for (i = popsize; i <= popsize+1; i++) {
347  result = build_dd(table,i,lower,upper); /* build and sift child */
348  if (!result) {
349  FREE(storedd);
350  FREE(repeat);
352  return(0);
353  }
354  large = largest(); /* find the largest DD in population */
355 
356  /* If the new child is smaller than the largest DD in the current
357  ** population, enter it into the population in place of the
358  ** largest DD.
359  */
360  if (STOREDD(i,numvars) < STOREDD(large,numvars)) {
361  /* Look up the largest DD in the computed table.
362  ** Decrease its repetition count. If the repetition count
363  ** goes to 0, remove the largest DD from the computed table.
364  */
365  result = st_lookup_int(computed,(char *)&STOREDD(large,0),
366  &index);
367  if (!result) {
368  FREE(storedd);
369  FREE(repeat);
371  return(0);
372  }
373  repeat[index]--;
374  if (repeat[index] == 0) {
375  int *pointer = &STOREDD(index,0);
376  result = st_delete(computed, &pointer, NULL);
377  if (!result) {
378  FREE(storedd);
379  FREE(repeat);
381  return(0);
382  }
383  }
384  /* Copy the new individual to the entry of the
385  ** population table just made available and update the
386  ** computed table.
387  */
388  for (n = 0; n <= numvars; n++) {
389  STOREDD(large,n) = STOREDD(i,n);
390  }
391  if (st_lookup_int(computed,(char *)&STOREDD(large,0),
392  &index)) {
393  repeat[index]++;
394  } else {
395  if (st_insert(computed,(char *)&STOREDD(large,0),
396  (char *)(long)large) == ST_OUT_OF_MEM) {
397  FREE(storedd);
398  FREE(repeat);
400  return(0);
401  }
402  repeat[large]++;
403  }
404  }
405  }
406  }
407 
408  /* Find the smallest DD in the population and build it;
409  ** that will be the result.
410  */
411  small = find_best();
412 
413  /* Print stats on the final population. */
414 #ifdef DD_STATS
415  average_fitness = find_average_fitness();
416  (void) fprintf(table->out,"\nFinal population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness);
417 #endif
418 
419  /* Clean up, build the result DD, and return. */
421  computed = NULL;
422  result = build_dd(table,small,lower,upper);
423  FREE(storedd);
424  FREE(repeat);
425  return(result);
426 
427 } /* end of cuddGa */
static int large
Definition: cuddGenetic.c:119
int st_lookup_int(st_table *, void *, int *)
Definition: st.c:322
#define FREE(obj)
Definition: util.h:80
static int * storedd
Definition: cuddGenetic.c:116
int size
Definition: cuddInt.h:345
void st_free_table(st_table *)
Definition: st.c:252
int cuddSifting(DdManager *table, int lower, int upper)
Definition: cuddReorder.c:502
int populationSize
Definition: cuddInt.h:414
static st_table * computed
Definition: cuddGenetic.c:117
int st_insert(st_table *, void *, void *)
Definition: st.c:358
static int array_hash(char *array, int modulus)
Definition: cuddGenetic.c:673
static int cross
Definition: cuddGenetic.c:122
static int find_best(void)
Definition: cuddGenetic.c:735
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
static int build_dd(DdManager *table, int num, int lower, int upper)
Definition: cuddGenetic.c:552
FILE * out
Definition: cuddInt.h:423
static int numvars
Definition: cuddGenetic.c:107
static int array_compare(const char *array1, const char *array2)
Definition: cuddGenetic.c:705
int numberXovers
Definition: cuddInt.h:415
static int popsize
Definition: cuddGenetic.c:106
st_table * st_init_table(ST_PFICPCP, ST_PFICPI)
Definition: st.c:163
static int largest(void)
Definition: cuddGenetic.c:623
#define ST_OUT_OF_MEM
Definition: st.h:41
int st_delete(st_table *, void *, void *)
Definition: st.c:634
static int * repeat
Definition: cuddGenetic.c:118
int * invperm
Definition: cuddInt.h:371
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368
#define STOREDD(i, j)
Definition: cuddGenetic.c:131
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
static int make_random(DdManager *table, int lower)
Definition: cuddGenetic.c:448
static int PMX(int maxvar)
Definition: cuddGenetic.c:793

◆ cuddGarbageCollect()

int cuddGarbageCollect ( DdManager unique,
int  clearCache 
)

Function********************************************************************

Synopsis [Performs garbage collection on the unique tables.]

Description [Performs garbage collection on the BDD and ZDD unique tables. If clearCache is 0, the cache is not cleared. This should only be specified if the cache has been cleared right before calling cuddGarbageCollect. (As in the case of dynamic reordering.) Returns the total number of deleted nodes.]

SideEffects [None]

SeeAlso []

Definition at line 762 of file cuddTable.c.

765 {
766  DdHook *hook;
767  DdCache *cache = unique->cache;
768  DdNode *sentinel = &(unique->sentinel);
769  DdNodePtr *nodelist;
770  int i, j, deleted, totalDeleted, totalDeletedZ;
771  DdCache *c;
772  DdNode *node,*next;
773  DdNodePtr *lastP;
774  int slots;
775  unsigned long localTime;
776 #ifndef DD_UNSORTED_FREE_LIST
777 #ifdef DD_RED_BLACK_FREE_LIST
778  DdNodePtr tree;
779 #else
780  DdNodePtr *memListTrav, *nxtNode;
781  DdNode *downTrav, *sentry;
782  int k;
783 #endif
784 #endif
785 
786 #ifndef DD_NO_DEATH_ROW
787  cuddClearDeathRow(unique);
788 #endif
789 
790  hook = unique->preGCHook;
791  while (hook != NULL) {
792  int res = (hook->f)(unique,"DD",NULL);
793  if (res == 0) return(0);
794  hook = hook->next;
795  }
796 
797  if (unique->dead + unique->deadZ == 0) {
798  hook = unique->postGCHook;
799  while (hook != NULL) {
800  int res = (hook->f)(unique,"DD",NULL);
801  if (res == 0) return(0);
802  hook = hook->next;
803  }
804  return(0);
805  }
806 
807  /* If many nodes are being reclaimed, we want to resize the tables
808  ** more aggressively, to reduce the frequency of garbage collection.
809  */
810  if (clearCache && unique->gcFrac == DD_GC_FRAC_LO &&
811  unique->slots <= unique->looseUpTo && unique->stash != NULL) {
812  unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots);
813 #ifdef DD_VERBOSE
814  (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_HI);
815  (void) fprintf(unique->err,"minDead = %d\n", unique->minDead);
816 #endif
817  unique->gcFrac = DD_GC_FRAC_HI;
818  return(0);
819  }
820 
821  localTime = util_cpu_time();
822 
823  unique->garbageCollections++;
824 #ifdef DD_VERBOSE
825  (void) fprintf(unique->err,
826  "garbage collecting (%d dead BDD nodes out of %d, min %d)...",
827  unique->dead, unique->keys, unique->minDead);
828  (void) fprintf(unique->err,
829  " (%d dead ZDD nodes out of %d)...",
830  unique->deadZ, unique->keysZ);
831 #endif
832 
833  /* Remove references to garbage collected nodes from the cache. */
834  if (clearCache) {
835  slots = unique->cacheSlots;
836  for (i = 0; i < slots; i++) {
837  c = &cache[i];
838  if (c->data != NULL) {
839  if (cuddClean(c->f)->ref == 0 ||
840  cuddClean(c->g)->ref == 0 ||
841  (((ptruint)c->f & 0x2) && Cudd_Regular(c->h)->ref == 0) ||
842  (c->data != DD_NON_CONSTANT &&
843  Cudd_Regular(c->data)->ref == 0)) {
844  c->data = NULL;
845  unique->cachedeletions++;
846  }
847  }
848  }
849  cuddLocalCacheClearDead(unique);
850  }
851 
852  /* Now return dead nodes to free list. Count them for sanity check. */
853  totalDeleted = 0;
854 #ifndef DD_UNSORTED_FREE_LIST
855 #ifdef DD_RED_BLACK_FREE_LIST
856  tree = NULL;
857 #endif
858 #endif
859 
860  for (i = 0; i < unique->size; i++) {
861  if (unique->subtables[i].dead == 0) continue;
862  nodelist = unique->subtables[i].nodelist;
863 
864  deleted = 0;
865  slots = unique->subtables[i].slots;
866  for (j = 0; j < slots; j++) {
867  lastP = &(nodelist[j]);
868  node = *lastP;
869  while (node != sentinel) {
870  next = node->next;
871  if (node->ref == 0) {
872  deleted++;
873 #ifndef DD_UNSORTED_FREE_LIST
874 #ifdef DD_RED_BLACK_FREE_LIST
875  cuddOrderedInsert(&tree,node);
876 #endif
877 #else
878  cuddDeallocNode(unique,node);
879 #endif
880  } else {
881  *lastP = node;
882  lastP = &(node->next);
883  }
884  node = next;
885  }
886  *lastP = sentinel;
887  }
888  if ((unsigned) deleted != unique->subtables[i].dead) {
889  ddReportRefMess(unique, i, "cuddGarbageCollect");
890  }
891  totalDeleted += deleted;
892  unique->subtables[i].keys -= deleted;
893  unique->subtables[i].dead = 0;
894  }
895  if (unique->constants.dead != 0) {
896  nodelist = unique->constants.nodelist;
897  deleted = 0;
898  slots = unique->constants.slots;
899  for (j = 0; j < slots; j++) {
900  lastP = &(nodelist[j]);
901  node = *lastP;
902  while (node != NULL) {
903  next = node->next;
904  if (node->ref == 0) {
905  deleted++;
906 #ifndef DD_UNSORTED_FREE_LIST
907 #ifdef DD_RED_BLACK_FREE_LIST
908  cuddOrderedInsert(&tree,node);
909 #endif
910 #else
911  cuddDeallocNode(unique,node);
912 #endif
913  } else {
914  *lastP = node;
915  lastP = &(node->next);
916  }
917  node = next;
918  }
919  *lastP = NULL;
920  }
921  if ((unsigned) deleted != unique->constants.dead) {
922  ddReportRefMess(unique, CUDD_CONST_INDEX, "cuddGarbageCollect");
923  }
924  totalDeleted += deleted;
925  unique->constants.keys -= deleted;
926  unique->constants.dead = 0;
927  }
928  if ((unsigned) totalDeleted != unique->dead) {
929  ddReportRefMess(unique, -1, "cuddGarbageCollect");
930  }
931  unique->keys -= totalDeleted;
932  unique->dead = 0;
933 #ifdef DD_STATS
934  unique->nodesFreed += (double) totalDeleted;
935 #endif
936 
937  totalDeletedZ = 0;
938 
939  for (i = 0; i < unique->sizeZ; i++) {
940  if (unique->subtableZ[i].dead == 0) continue;
941  nodelist = unique->subtableZ[i].nodelist;
942 
943  deleted = 0;
944  slots = unique->subtableZ[i].slots;
945  for (j = 0; j < slots; j++) {
946  lastP = &(nodelist[j]);
947  node = *lastP;
948  while (node != NULL) {
949  next = node->next;
950  if (node->ref == 0) {
951  deleted++;
952 #ifndef DD_UNSORTED_FREE_LIST
953 #ifdef DD_RED_BLACK_FREE_LIST
954  cuddOrderedInsert(&tree,node);
955 #endif
956 #else
957  cuddDeallocNode(unique,node);
958 #endif
959  } else {
960  *lastP = node;
961  lastP = &(node->next);
962  }
963  node = next;
964  }
965  *lastP = NULL;
966  }
967  if ((unsigned) deleted != unique->subtableZ[i].dead) {
968  ddReportRefMess(unique, i, "cuddGarbageCollect");
969  }
970  totalDeletedZ += deleted;
971  unique->subtableZ[i].keys -= deleted;
972  unique->subtableZ[i].dead = 0;
973  }
974 
975  /* No need to examine the constant table for ZDDs.
976  ** If we did we should be careful not to count whatever dead
977  ** nodes we found there among the dead ZDD nodes. */
978  if ((unsigned) totalDeletedZ != unique->deadZ) {
979  ddReportRefMess(unique, -1, "cuddGarbageCollect");
980  }
981  unique->keysZ -= totalDeletedZ;
982  unique->deadZ = 0;
983 #ifdef DD_STATS
984  unique->nodesFreed += (double) totalDeletedZ;
985 #endif
986 
987 
988 #ifndef DD_UNSORTED_FREE_LIST
989 #ifdef DD_RED_BLACK_FREE_LIST
990  unique->nextFree = cuddOrderedThread(tree,unique->nextFree);
991 #else
992  memListTrav = unique->memoryList;
993  sentry = NULL;
994  while (memListTrav != NULL) {
995  ptruint offset;
996  nxtNode = (DdNodePtr *)memListTrav[0];
997  offset = (ptruint) memListTrav & (sizeof(DdNode) - 1);
998  memListTrav += (sizeof(DdNode) - offset) / sizeof(DdNodePtr);
999  downTrav = (DdNode *)memListTrav;
1000  k = 0;
1001  do {
1002  if (downTrav[k].ref == 0) {
1003  if (sentry == NULL) {
1004  unique->nextFree = sentry = &downTrav[k];
1005  } else {
1006  /* First hook sentry->next to the dead node and then
1007  ** reassign sentry to the dead node. */
1008  sentry = (sentry->next = &downTrav[k]);
1009  }
1010  }
1011  } while (++k < DD_MEM_CHUNK);
1012  memListTrav = nxtNode;
1013  }
1014  sentry->next = NULL;
1015 #endif
1016 #endif
1017 
1018  unique->GCTime += util_cpu_time() - localTime;
1019 
1020  hook = unique->postGCHook;
1021  while (hook != NULL) {
1022  int res = (hook->f)(unique,"DD",NULL);
1023  if (res == 0) return(0);
1024  hook = hook->next;
1025  }
1026 
1027 #ifdef DD_VERBOSE
1028  (void) fprintf(unique->err," done\n");
1029 #endif
1030 
1031  return(totalDeleted+totalDeletedZ);
1032 
1033 } /* end of cuddGarbageCollect */
static void ddReportRefMess(DdManager *unique, int i, const char *caller)
Definition: cuddTable.c:3195
DdHalfWord ref
Definition: cudd.h:272
unsigned int keys
Definition: cuddInt.h:314
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:270
unsigned int deadZ
Definition: cuddInt.h:356
DdNode * data
Definition: cuddInt.h:304
int size
Definition: cuddInt.h:345
double gcFrac
Definition: cuddInt.h:359
unsigned int slots
Definition: cuddInt.h:352
ptruint h
Definition: cuddInt.h:303
#define Cudd_Regular(node)
Definition: cudd.h:384
FILE * err
Definition: cuddInt.h:424
DdNode * g
Definition: cuddInt.h:302
int garbageCollections
Definition: cuddInt.h:432
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode * DdNodePtr
Definition: cuddInt.h:253
DD_HFP f
Definition: cuddInt.h:241
struct DdNode DdNode
Definition: cudd.h:262
#define DD_GC_FRAC_HI
Definition: cuddInt.h:135
unsigned int dead
Definition: cuddInt.h:355
unsigned int cacheSlots
Definition: cuddInt.h:337
DdNode sentinel
Definition: cuddInt.h:328
char * stash
Definition: cuddInt.h:382
unsigned int keys
Definition: cuddInt.h:353
unsigned int dead
Definition: cuddInt.h:316
DdCache * cache
Definition: cuddInt.h:336
DdNode * next
Definition: cudd.h:273
#define DD_GC_FRAC_LO
Definition: cuddInt.h:134
#define CUDD_CONST_INDEX
Definition: cudd.h:113
DdNode ** nodelist
Definition: cuddInt.h:311
long util_cpu_time(void)
Definition: cpu_time.c:34
void cuddLocalCacheClearDead(DdManager *manager)
Definition: cuddLCache.c:371
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:520
unsigned long GCTime
Definition: cuddInt.h:433
DdNode ** memoryList
Definition: cuddInt.h:380
unsigned int ptruint
Definition: cuddInt.h:250
DdNode * nextFree
Definition: cuddInt.h:381
struct DdHook * next
Definition: cuddInt.h:242
void cuddClearDeathRow(DdManager *table)
Definition: cuddRef.c:722
int sizeZ
Definition: cuddInt.h:346
unsigned int looseUpTo
Definition: cuddInt.h:361
unsigned int slots
Definition: cuddInt.h:313
DdHook * postGCHook
Definition: cuddInt.h:420
#define cuddClean(p)
Definition: cuddInt.h:757
DdSubtable constants
Definition: cuddInt.h:351
double cachedeletions
Definition: cuddInt.h:440
#define DD_MEM_CHUNK
Definition: cuddInt.h:105
unsigned int keysZ
Definition: cuddInt.h:354
DdHook * preGCHook
Definition: cuddInt.h:419
unsigned int minDead
Definition: cuddInt.h:358
DdSubtable * subtableZ
Definition: cuddInt.h:350
#define DD_NON_CONSTANT
Definition: cuddInt.h:124

◆ cuddGetBranches()

void cuddGetBranches ( DdNode g,
DdNode **  g1,
DdNode **  g0 
)

Function********************************************************************

Synopsis [Computes the children of g.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 196 of file cuddCof.c.

200 {
201  DdNode *G = Cudd_Regular(g);
202 
203  *g1 = cuddT(G);
204  *g0 = cuddE(G);
205  if (Cudd_IsComplement(g)) {
206  *g1 = Cudd_Not(*g1);
207  *g0 = Cudd_Not(*g0);
208  }
209 
210 } /* end of cuddGetBranches */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define Cudd_Regular(node)
Definition: cudd.h:384
#define Cudd_IsComplement(node)
Definition: cudd.h:412
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddE(node)
Definition: cuddInt.h:625

◆ cuddHashTableGenericInsert()

int cuddHashTableGenericInsert ( DdHashTable hash,
DdNode f,
void *  value 
)

Function********************************************************************

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key is one pointer and the value is not a DdNode pointer. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert1 cuddHashTableGenericLookup]

Definition at line 919 of file cuddLCache.c.

923 {
924  int result;
925  unsigned int posn;
926  DdHashItem *item;
927 
928 #ifdef DD_DEBUG
929  assert(hash->keysize == 1);
930 #endif
931 
932  if (hash->size > hash->maxsize) {
933  result = cuddHashTableResize(hash);
934  if (result == 0) return(0);
935  }
936  item = cuddHashTableAlloc(hash);
937  if (item == NULL) return(0);
938  hash->size++;
939  item->value = (DdNode *) value;
940  item->count = 0;
941  item->key[0] = f;
942  posn = ddLCHash1(f,hash->shift);
943  item->next = hash->bucket[posn];
944  hash->bucket[posn] = item;
945 
946  return(1);
947 
948 } /* end of cuddHashTableGenericInsert */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
Definition: cudd.h:270
#define assert(ex)
Definition: util.h:141
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddLCache.c:1503
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
#define ddLCHash1(f, shift)
Definition: cuddLCache.c:124
unsigned int maxsize
Definition: cuddInt.h:297
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295
static int result
Definition: cuddGenetic.c:121
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddLCache.c:1401

◆ cuddHashTableGenericLookup()

void* cuddHashTableGenericLookup ( DdHashTable hash,
DdNode f 
)

Function********************************************************************

Synopsis [Looks up a key consisting of one pointer in a hash table.]

Description [Looks up a key consisting of one pointer in a hash table when the value is not a DdNode pointer. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableLookup1 cuddHashTableGenericInsert]

Definition at line 966 of file cuddLCache.c.

969 {
970  unsigned int posn;
971  DdHashItem *item;
972 
973 #ifdef DD_DEBUG
974  assert(hash->keysize == 1);
975 #endif
976 
977  posn = ddLCHash1(f,hash->shift);
978  item = hash->bucket[posn];
979 
980  while (item != NULL) {
981  if (f == item->key[0]) {
982  return ((void *) item->value);
983  }
984  item = item->next;
985  }
986  return(NULL);
987 
988 } /* end of cuddHashTableGenericLookup */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
#define assert(ex)
Definition: util.h:141
struct DdHashItem * next
Definition: cuddInt.h:281
#define ddLCHash1(f, shift)
Definition: cuddLCache.c:124
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295

◆ cuddHashTableGenericQuit()

void cuddHashTableGenericQuit ( DdHashTable hash)

Function********************************************************************

Synopsis [Shuts down a hash table.]

Description [Shuts down a hash table, when the values are not DdNode pointers.]

SideEffects [None]

SeeAlso [cuddHashTableInit]

Definition at line 652 of file cuddLCache.c.

654 {
655 #ifdef __osf__
656 #pragma pointer_size save
657 #pragma pointer_size short
658 #endif
659  DdHashItem **memlist, **nextmem;
660 
661  memlist = hash->memoryList;
662  while (memlist != NULL) {
663  nextmem = (DdHashItem **) memlist[0];
664  FREE(memlist);
665  memlist = nextmem;
666  }
667 
668  FREE(hash->bucket);
669  FREE(hash);
670 #ifdef __osf__
671 #pragma pointer_size restore
672 #endif
673 
674  return;
675 
676 } /* end of cuddHashTableGenericQuit */
DdHashItem ** bucket
Definition: cuddInt.h:291
#define FREE(obj)
Definition: util.h:80
DdHashItem ** memoryList
Definition: cuddInt.h:293

◆ cuddHashTableInit()

DdHashTable* cuddHashTableInit ( DdManager manager,
unsigned int  keySize,
unsigned int  initSize 
)

Function********************************************************************

Synopsis [Initializes a hash table.]

Description [Initializes a hash table. Returns a pointer to the new table if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableQuit]

Definition at line 557 of file cuddLCache.c.

561 {
562  DdHashTable *hash;
563  int logSize;
564 
565  hash = ALLOC(DdHashTable, 1);
566  if (hash == NULL) {
567  manager->errorCode = CUDD_MEMORY_OUT;
568  return(NULL);
569  }
570  hash->keysize = keySize;
571  hash->manager = manager;
572  hash->memoryList = NULL;
573  hash->nextFree = NULL;
574  hash->itemsize = (keySize + 1) * sizeof(DdNode *) +
575  sizeof(ptrint) + sizeof(DdHashItem *);
576  /* We have to guarantee that the shift be < 32. */
577  if (initSize < 2) initSize = 2;
578  logSize = cuddComputeFloorLog2(initSize);
579  hash->numBuckets = 1 << logSize;
580  hash->shift = sizeof(int) * 8 - logSize;
581  hash->bucket = ALLOC(DdHashItem *, hash->numBuckets);
582  if (hash->bucket == NULL) {
583  manager->errorCode = CUDD_MEMORY_OUT;
584  FREE(hash);
585  return(NULL);
586  }
587  memset(hash->bucket, 0, hash->numBuckets * sizeof(DdHashItem *));
588  hash->size = 0;
590  return(hash);
591 
592 } /* end of cuddHashTableInit */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
int ptrint
Definition: cuddInt.h:249
unsigned int size
Definition: cuddInt.h:296
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
DdManager * manager
Definition: cuddInt.h:298
char * memset()
#define ALLOC(type, num)
Definition: util.h:76
unsigned int numBuckets
Definition: cuddInt.h:294
unsigned int maxsize
Definition: cuddInt.h:297
unsigned int itemsize
Definition: cuddInt.h:290
DdHashItem * nextFree
Definition: cuddInt.h:292
int shift
Definition: cuddInt.h:295
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1036
DdHashItem ** memoryList
Definition: cuddInt.h:293
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
#define DD_MAX_HASHTABLE_DENSITY
Definition: cuddLCache.c:85

◆ cuddHashTableInsert()

int cuddHashTableInsert ( DdHashTable hash,
DdNodePtr key,
DdNode value,
ptrint  count 
)

Function********************************************************************

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key has more than three pointers. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [[cuddHashTableInsert1 cuddHashTableInsert2 cuddHashTableInsert3 cuddHashTableLookup]

Definition at line 693 of file cuddLCache.c.

698 {
699  int result;
700  unsigned int posn;
701  DdHashItem *item;
702  unsigned int i;
703 
704 #ifdef DD_DEBUG
705  assert(hash->keysize > 3);
706 #endif
707 
708  if (hash->size > hash->maxsize) {
709  result = cuddHashTableResize(hash);
710  if (result == 0) return(0);
711  }
712  item = cuddHashTableAlloc(hash);
713  if (item == NULL) return(0);
714  hash->size++;
715  item->value = value;
716  cuddRef(value);
717  item->count = count;
718  for (i = 0; i < hash->keysize; i++) {
719  item->key[i] = key[i];
720  }
721  posn = ddLCHash(key,hash->keysize,hash->shift);
722  item->next = hash->bucket[posn];
723  hash->bucket[posn] = item;
724 
725  return(1);
726 
727 } /* end of cuddHashTableInsert */
unsigned int keysize
Definition: cuddInt.h:289
#define cuddRef(n)
Definition: cuddInt.h:557
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
#define assert(ex)
Definition: util.h:141
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddLCache.c:1503
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddLCache.c:1313
unsigned int maxsize
Definition: cuddInt.h:297
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295
static int result
Definition: cuddGenetic.c:121
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddLCache.c:1401

◆ cuddHashTableInsert1()

int cuddHashTableInsert1 ( DdHashTable hash,
DdNode f,
DdNode value,
ptrint  count 
)

Function********************************************************************

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key is one pointer. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert cuddHashTableInsert2 cuddHashTableInsert3 cuddHashTableLookup1]

Definition at line 812 of file cuddLCache.c.

817 {
818  int result;
819  unsigned int posn;
820  DdHashItem *item;
821 
822 #ifdef DD_DEBUG
823  assert(hash->keysize == 1);
824 #endif
825 
826  if (hash->size > hash->maxsize) {
827  result = cuddHashTableResize(hash);
828  if (result == 0) return(0);
829  }
830  item = cuddHashTableAlloc(hash);
831  if (item == NULL) return(0);
832  hash->size++;
833  item->value = value;
834  cuddRef(value);
835  item->count = count;
836  item->key[0] = f;
837  posn = ddLCHash1(f,hash->shift);
838  item->next = hash->bucket[posn];
839  hash->bucket[posn] = item;
840 
841  return(1);
842 
843 } /* end of cuddHashTableInsert1 */
unsigned int keysize
Definition: cuddInt.h:289
#define cuddRef(n)
Definition: cuddInt.h:557
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
#define assert(ex)
Definition: util.h:141
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddLCache.c:1503
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
#define ddLCHash1(f, shift)
Definition: cuddLCache.c:124
unsigned int maxsize
Definition: cuddInt.h:297
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295
static int result
Definition: cuddGenetic.c:121
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddLCache.c:1401

◆ cuddHashTableInsert2()

int cuddHashTableInsert2 ( DdHashTable hash,
DdNode f,
DdNode g,
DdNode value,
ptrint  count 
)

Function********************************************************************

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key is composed of two pointers. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert3 cuddHashTableLookup2]

Definition at line 1005 of file cuddLCache.c.

1011 {
1012  int result;
1013  unsigned int posn;
1014  DdHashItem *item;
1015 
1016 #ifdef DD_DEBUG
1017  assert(hash->keysize == 2);
1018 #endif
1019 
1020  if (hash->size > hash->maxsize) {
1021  result = cuddHashTableResize(hash);
1022  if (result == 0) return(0);
1023  }
1024  item = cuddHashTableAlloc(hash);
1025  if (item == NULL) return(0);
1026  hash->size++;
1027  item->value = value;
1028  cuddRef(value);
1029  item->count = count;
1030  item->key[0] = f;
1031  item->key[1] = g;
1032  posn = ddLCHash2(f,g,hash->shift);
1033  item->next = hash->bucket[posn];
1034  hash->bucket[posn] = item;
1035 
1036  return(1);
1037 
1038 } /* end of cuddHashTableInsert2 */
unsigned int keysize
Definition: cuddInt.h:289
#define cuddRef(n)
Definition: cuddInt.h:557
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
#define assert(ex)
Definition: util.h:141
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddLCache.c:1503
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
unsigned int maxsize
Definition: cuddInt.h:297
DdNode * key[1]
Definition: cuddInt.h:284
#define ddLCHash2(f, g, shift)
Definition: cuddLCache.c:145
int shift
Definition: cuddInt.h:295
static int result
Definition: cuddGenetic.c:121
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddLCache.c:1401

◆ cuddHashTableInsert3()

int cuddHashTableInsert3 ( DdHashTable hash,
DdNode f,
DdNode g,
DdNode h,
DdNode value,
ptrint  count 
)

Function********************************************************************

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key is composed of three pointers. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert2 cuddHashTableLookup3]

Definition at line 1115 of file cuddLCache.c.

1122 {
1123  int result;
1124  unsigned int posn;
1125  DdHashItem *item;
1126 
1127 #ifdef DD_DEBUG
1128  assert(hash->keysize == 3);
1129 #endif
1130 
1131  if (hash->size > hash->maxsize) {
1132  result = cuddHashTableResize(hash);
1133  if (result == 0) return(0);
1134  }
1135  item = cuddHashTableAlloc(hash);
1136  if (item == NULL) return(0);
1137  hash->size++;
1138  item->value = value;
1139  cuddRef(value);
1140  item->count = count;
1141  item->key[0] = f;
1142  item->key[1] = g;
1143  item->key[2] = h;
1144  posn = ddLCHash3(f,g,h,hash->shift);
1145  item->next = hash->bucket[posn];
1146  hash->bucket[posn] = item;
1147 
1148  return(1);
1149 
1150 } /* end of cuddHashTableInsert3 */
unsigned int keysize
Definition: cuddInt.h:289
#define cuddRef(n)
Definition: cuddInt.h:557
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
#define assert(ex)
Definition: util.h:141
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddLCache.c:1503
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
unsigned int maxsize
Definition: cuddInt.h:297
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295
static int result
Definition: cuddGenetic.c:121
#define ddLCHash3(f, g, h, shift)
Definition: cuddLCache.c:161
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddLCache.c:1401

◆ cuddHashTableLookup()

DdNode* cuddHashTableLookup ( DdHashTable hash,
DdNodePtr key 
)

Function********************************************************************

Synopsis [Looks up a key in a hash table.]

Description [Looks up a key consisting of more than three pointers in a hash table. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the value of the entry is dereferenced, and the entry is returned to the free list.]

SideEffects [None]

SeeAlso [cuddHashTableLookup1 cuddHashTableLookup2 cuddHashTableLookup3 cuddHashTableInsert]

Definition at line 748 of file cuddLCache.c.

751 {
752  unsigned int posn;
753  DdHashItem *item, *prev;
754  unsigned int i, keysize;
755 
756 #ifdef DD_DEBUG
757  assert(hash->keysize > 3);
758 #endif
759 
760  posn = ddLCHash(key,hash->keysize,hash->shift);
761  item = hash->bucket[posn];
762  prev = NULL;
763 
764  keysize = hash->keysize;
765  while (item != NULL) {
766  DdNodePtr *key2 = item->key;
767  int equal = 1;
768  for (i = 0; i < keysize; i++) {
769  if (key[i] != key2[i]) {
770  equal = 0;
771  break;
772  }
773  }
774  if (equal) {
775  DdNode *value = item->value;
776  cuddSatDec(item->count);
777  if (item->count == 0) {
778  cuddDeref(value);
779  if (prev == NULL) {
780  hash->bucket[posn] = item->next;
781  } else {
782  prev->next = item->next;
783  }
784  item->next = hash->nextFree;
785  hash->nextFree = item;
786  hash->size--;
787  }
788  return(value);
789  }
790  prev = item;
791  item = item->next;
792  }
793  return(NULL);
794 
795 } /* end of cuddHashTableLookup */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddLCache.c:1313
DdHashItem * nextFree
Definition: cuddInt.h:292
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295

◆ cuddHashTableLookup1()

DdNode* cuddHashTableLookup1 ( DdHashTable hash,
DdNode f 
)

Function********************************************************************

Synopsis [Looks up a key consisting of one pointer in a hash table.]

Description [Looks up a key consisting of one pointer in a hash table. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the value of the entry is dereferenced, and the entry is returned to the free list.]

SideEffects [None]

SeeAlso [cuddHashTableLookup cuddHashTableLookup2 cuddHashTableLookup3 cuddHashTableInsert1]

Definition at line 864 of file cuddLCache.c.

867 {
868  unsigned int posn;
869  DdHashItem *item, *prev;
870 
871 #ifdef DD_DEBUG
872  assert(hash->keysize == 1);
873 #endif
874 
875  posn = ddLCHash1(f,hash->shift);
876  item = hash->bucket[posn];
877  prev = NULL;
878 
879  while (item != NULL) {
880  DdNodePtr *key = item->key;
881  if (f == key[0]) {
882  DdNode *value = item->value;
883  cuddSatDec(item->count);
884  if (item->count == 0) {
885  cuddDeref(value);
886  if (prev == NULL) {
887  hash->bucket[posn] = item->next;
888  } else {
889  prev->next = item->next;
890  }
891  item->next = hash->nextFree;
892  hash->nextFree = item;
893  hash->size--;
894  }
895  return(value);
896  }
897  prev = item;
898  item = item->next;
899  }
900  return(NULL);
901 
902 } /* end of cuddHashTableLookup1 */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
#define ddLCHash1(f, shift)
Definition: cuddLCache.c:124
DdHashItem * nextFree
Definition: cuddInt.h:292
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295

◆ cuddHashTableLookup2()

DdNode* cuddHashTableLookup2 ( DdHashTable hash,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Looks up a key consisting of two pointers in a hash table.]

Description [Looks up a key consisting of two pointer in a hash table. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the value of the entry is dereferenced, and the entry is returned to the free list.]

SideEffects [None]

SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup3 cuddHashTableInsert2]

Definition at line 1059 of file cuddLCache.c.

1063 {
1064  unsigned int posn;
1065  DdHashItem *item, *prev;
1066 
1067 #ifdef DD_DEBUG
1068  assert(hash->keysize == 2);
1069 #endif
1070 
1071  posn = ddLCHash2(f,g,hash->shift);
1072  item = hash->bucket[posn];
1073  prev = NULL;
1074 
1075  while (item != NULL) {
1076  DdNodePtr *key = item->key;
1077  if ((f == key[0]) && (g == key[1])) {
1078  DdNode *value = item->value;
1079  cuddSatDec(item->count);
1080  if (item->count == 0) {
1081  cuddDeref(value);
1082  if (prev == NULL) {
1083  hash->bucket[posn] = item->next;
1084  } else {
1085  prev->next = item->next;
1086  }
1087  item->next = hash->nextFree;
1088  hash->nextFree = item;
1089  hash->size--;
1090  }
1091  return(value);
1092  }
1093  prev = item;
1094  item = item->next;
1095  }
1096  return(NULL);
1097 
1098 } /* end of cuddHashTableLookup2 */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
DdHashItem * nextFree
Definition: cuddInt.h:292
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdNode * key[1]
Definition: cuddInt.h:284
#define ddLCHash2(f, g, shift)
Definition: cuddLCache.c:145
int shift
Definition: cuddInt.h:295

◆ cuddHashTableLookup3()

DdNode* cuddHashTableLookup3 ( DdHashTable hash,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Looks up a key consisting of three pointers in a hash table.]

Description [Looks up a key consisting of three pointers in a hash table. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the value of the entry is dereferenced, and the entry is returned to the free list.]

SideEffects [None]

SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup2 cuddHashTableInsert3]

Definition at line 1171 of file cuddLCache.c.

1176 {
1177  unsigned int posn;
1178  DdHashItem *item, *prev;
1179 
1180 #ifdef DD_DEBUG
1181  assert(hash->keysize == 3);
1182 #endif
1183 
1184  posn = ddLCHash3(f,g,h,hash->shift);
1185  item = hash->bucket[posn];
1186  prev = NULL;
1187 
1188  while (item != NULL) {
1189  DdNodePtr *key = item->key;
1190  if ((f == key[0]) && (g == key[1]) && (h == key[2])) {
1191  DdNode *value = item->value;
1192  cuddSatDec(item->count);
1193  if (item->count == 0) {
1194  cuddDeref(value);
1195  if (prev == NULL) {
1196  hash->bucket[posn] = item->next;
1197  } else {
1198  prev->next = item->next;
1199  }
1200  item->next = hash->nextFree;
1201  hash->nextFree = item;
1202  hash->size--;
1203  }
1204  return(value);
1205  }
1206  prev = item;
1207  item = item->next;
1208  }
1209  return(NULL);
1210 
1211 } /* end of cuddHashTableLookup3 */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
DdHashItem * nextFree
Definition: cuddInt.h:292
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295
#define ddLCHash3(f, g, h, shift)
Definition: cuddLCache.c:161

◆ cuddHashTableQuit()

void cuddHashTableQuit ( DdHashTable hash)

Function********************************************************************

Synopsis [Shuts down a hash table.]

Description [Shuts down a hash table, dereferencing all the values.]

SideEffects [None]

SeeAlso [cuddHashTableInit]

Definition at line 607 of file cuddLCache.c.

609 {
610  unsigned int i;
611  DdManager *dd = hash->manager;
612  DdHashItem *bucket;
613  DdHashItem **memlist, **nextmem;
614  unsigned int numBuckets = hash->numBuckets;
615 
616  for (i = 0; i < numBuckets; i++) {
617  bucket = hash->bucket[i];
618  while (bucket != NULL) {
619  Cudd_RecursiveDeref(dd, bucket->value);
620  bucket = bucket->next;
621  }
622  }
623 
624  memlist = hash->memoryList;
625  while (memlist != NULL) {
626  nextmem = (DdHashItem **) memlist[0];
627  FREE(memlist);
628  memlist = nextmem;
629  }
630 
631  FREE(hash->bucket);
632  FREE(hash);
633 
634  return;
635 
636 } /* end of cuddHashTableQuit */
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
#define FREE(obj)
Definition: util.h:80
DdManager * manager
Definition: cuddInt.h:298
struct DdHashItem * next
Definition: cuddInt.h:281
unsigned int numBuckets
Definition: cuddInt.h:294
DdHashItem ** memoryList
Definition: cuddInt.h:293

◆ cuddHeapProfile()

int cuddHeapProfile ( DdManager dd)

Function********************************************************************

Synopsis [Prints information about the heap.]

Description [Prints to the manager's stdout the number of live nodes for each level of the DD heap that contains at least one live node. It also prints a summary containing:

  • total number of tables;
  • number of tables with live nodes;
  • table with the largest number of live nodes;
  • number of nodes in that table.

If more than one table contains the maximum number of live nodes, only the one of lowest index is reported. Returns 1 in case of success and 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 641 of file cuddCheck.c.

643 {
644  int ntables = dd->size;
645  DdSubtable *subtables = dd->subtables;
646  int i, /* loop index */
647  nodes, /* live nodes in i-th layer */
648  retval, /* return value of fprintf */
649  largest = -1, /* index of the table with most live nodes */
650  maxnodes = -1, /* maximum number of live nodes in a table */
651  nonempty = 0; /* number of tables with live nodes */
652 
653  /* Print header. */
654 #if SIZEOF_VOID_P == 8
655  retval = fprintf(dd->out,"*** DD heap profile for 0x%lx ***\n",
656  (ptruint) dd);
657 #else
658  retval = fprintf(dd->out,"*** DD heap profile for 0x%x ***\n",
659  (ptruint) dd);
660 #endif
661  if (retval == EOF) return 0;
662 
663  /* Print number of live nodes for each nonempty table. */
664  for (i=0; i<ntables; i++) {
665  nodes = subtables[i].keys - subtables[i].dead;
666  if (nodes) {
667  nonempty++;
668  retval = fprintf(dd->out,"%5d: %5d nodes\n", i, nodes);
669  if (retval == EOF) return 0;
670  if (nodes > maxnodes) {
671  maxnodes = nodes;
672  largest = i;
673  }
674  }
675  }
676 
677  nodes = dd->constants.keys - dd->constants.dead;
678  if (nodes) {
679  nonempty++;
680  retval = fprintf(dd->out,"const: %5d nodes\n", nodes);
681  if (retval == EOF) return 0;
682  if (nodes > maxnodes) {
683  maxnodes = nodes;
684  largest = CUDD_CONST_INDEX;
685  }
686  }
687 
688  /* Print summary. */
689  retval = fprintf(dd->out,"Summary: %d tables, %d non-empty, largest: %d ",
690  ntables+1, nonempty, largest);
691  if (retval == EOF) return 0;
692  retval = fprintf(dd->out,"(with %d nodes)\n", maxnodes);
693  if (retval == EOF) return 0;
694 
695  return(1);
696 
697 } /* end of cuddHeapProfile */
unsigned int keys
Definition: cuddInt.h:314
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int dead
Definition: cuddInt.h:316
FILE * out
Definition: cuddInt.h:423
#define CUDD_CONST_INDEX
Definition: cudd.h:113
static int largest(void)
Definition: cuddGenetic.c:623
unsigned int ptruint
Definition: cuddInt.h:250
DdSubtable constants
Definition: cuddInt.h:351

◆ cuddInitCache()

int cuddInitCache ( DdManager unique,
unsigned int  cacheSize,
unsigned int  maxCacheSize 
)

AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Initializes the computed table.]

Description [Initializes the computed table. It is called by Cudd_Init. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_Init]

Definition at line 132 of file cuddCache.c.

136 {
137  int i;
138  unsigned int logSize;
139 #ifndef DD_CACHE_PROFILE
140  DdNodePtr *mem;
141  ptruint offset;
142 #endif
143 
144  /* Round cacheSize to largest power of 2 not greater than the requested
145  ** initial cache size. */
146  logSize = cuddComputeFloorLog2(ddMax(cacheSize,unique->slots/2));
147  cacheSize = 1 << logSize;
148  unique->acache = ALLOC(DdCache,cacheSize+1);
149  if (unique->acache == NULL) {
150  unique->errorCode = CUDD_MEMORY_OUT;
151  return(0);
152  }
153  /* If the size of the cache entry is a power of 2, we want to
154  ** enforce alignment to that power of two. This happens when
155  ** DD_CACHE_PROFILE is not defined. */
156 #ifdef DD_CACHE_PROFILE
157  unique->cache = unique->acache;
158  unique->memused += (cacheSize) * sizeof(DdCache);
159 #else
160  mem = (DdNodePtr *) unique->acache;
161  offset = (ptruint) mem & (sizeof(DdCache) - 1);
162  mem += (sizeof(DdCache) - offset) / sizeof(DdNodePtr);
163  unique->cache = (DdCache *) mem;
164  assert(((ptruint) unique->cache & (sizeof(DdCache) - 1)) == 0);
165  unique->memused += (cacheSize+1) * sizeof(DdCache);
166 #endif
167  unique->cacheSlots = cacheSize;
168  unique->cacheShift = sizeof(int) * 8 - logSize;
169  unique->maxCacheHard = maxCacheSize;
170  /* If cacheSlack is non-negative, we can resize. */
171  unique->cacheSlack = (int) ddMin(maxCacheSize,
173  2 * (int) cacheSize;
174  Cudd_SetMinHit(unique,DD_MIN_HIT);
175  /* Initialize to avoid division by 0 and immediate resizing. */
176  unique->cacheMisses = (double) (int) (cacheSize * unique->minHit + 1);
177  unique->cacheHits = 0;
178  unique->totCachehits = 0;
179  /* The sum of cacheMisses and totCacheMisses is always correct,
180  ** even though cacheMisses is larger than it should for the reasons
181  ** explained above. */
182  unique->totCacheMisses = -unique->cacheMisses;
183  unique->cachecollisions = 0;
184  unique->cacheinserts = 0;
185  unique->cacheLastInserts = 0;
186  unique->cachedeletions = 0;
187 
188  /* Initialize the cache */
189  for (i = 0; (unsigned) i < cacheSize; i++) {
190  unique->cache[i].h = 0; /* unused slots */
191  unique->cache[i].data = NULL; /* invalid entry */
192 #ifdef DD_CACHE_PROFILE
193  unique->cache[i].count = 0;
194 #endif
195  }
196 
197  return(1);
198 
199 } /* end of cuddInitCache */
Definition: cudd.h:270
DdNode * data
Definition: cuddInt.h:304
#define assert(ex)
Definition: util.h:141
unsigned int maxCacheHard
Definition: cuddInt.h:343
unsigned int slots
Definition: cuddInt.h:352
ptruint h
Definition: cuddInt.h:303
double cachecollisions
Definition: cuddInt.h:437
DdNode * DdNodePtr
Definition: cuddInt.h:253
#define DD_MIN_HIT
Definition: cuddInt.h:137
double cacheinserts
Definition: cuddInt.h:438
unsigned int cacheSlots
Definition: cuddInt.h:337
#define ALLOC(type, num)
Definition: util.h:76
DdCache * cache
Definition: cuddInt.h:336
double totCacheMisses
Definition: cuddInt.h:436
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1036
#define ddMax(x, y)
Definition: cuddInt.h:785
double cacheLastInserts
Definition: cuddInt.h:439
double cacheHits
Definition: cuddInt.h:340
#define ddMin(x, y)
Definition: cuddInt.h:771
#define DD_MAX_CACHE_TO_SLOTS_RATIO
Definition: cuddInt.h:145
void Cudd_SetMinHit(DdManager *dd, unsigned int hr)
Definition: cuddAPI.c:1538
int cacheSlack
Definition: cuddInt.h:342
unsigned long memused
Definition: cuddInt.h:429
unsigned int ptruint
Definition: cuddInt.h:250
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338
double cachedeletions
Definition: cuddInt.h:440
DdCache * acache
Definition: cuddInt.h:335
struct DdCache DdCache
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
double totCachehits
Definition: cuddInt.h:435

◆ cuddInitInteract()

int cuddInitInteract ( DdManager table)

Function********************************************************************

Synopsis [Initializes the interaction matrix.]

Description [Initializes the interaction matrix. The interaction matrix is implemented as a bit vector storing the upper triangle of the symmetric interaction matrix. The bit vector is kept in an array of long integers. The computation is based on a series of depth-first searches, one for each root of the DAG. Two flags are needed: The local visited flag uses the LSB of the then pointer. The global visited flag uses the LSB of the next pointer. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 234 of file cuddInteract.c.

236 {
237  int i,j;
238  unsigned long words;
239  long *interact;
240  char *support;
241  DdNode *f;
242  DdNode *sentinel = &(table->sentinel);
243  DdNodePtr *nodelist;
244  int slots;
245  unsigned long n = (unsigned long) table->size;
246 
247  words = ((n * (n-1)) >> (1 + LOGBPL)) + 1;
248  table->interact = interact = ALLOC(long,words);
249  if (interact == NULL) {
250  table->errorCode = CUDD_MEMORY_OUT;
251  return(0);
252  }
253  for (i = 0; i < words; i++) {
254  interact[i] = 0;
255  }
256 
257  support = ALLOC(char,n);
258  if (support == NULL) {
259  table->errorCode = CUDD_MEMORY_OUT;
260  FREE(interact);
261  return(0);
262  }
263  for (i = 0; i < n; i++) {
264  support[i] = 0;
265  }
266 
267  for (i = 0; i < n; i++) {
268  nodelist = table->subtables[i].nodelist;
269  slots = table->subtables[i].slots;
270  for (j = 0; j < slots; j++) {
271  f = nodelist[j];
272  while (f != sentinel) {
273  /* A node is a root of the DAG if it cannot be
274  ** reached by nodes above it. If a node was never
275  ** reached during the previous depth-first searches,
276  ** then it is a root, and we start a new depth-first
277  ** search from it.
278  */
279  if (!Cudd_IsComplement(f->next)) {
280  ddSuppInteract(f,support);
281  ddClearLocal(f);
282  ddUpdateInteract(table,support);
283  }
284  f = Cudd_Regular(f->next);
285  }
286  }
287  }
288  ddClearGlobal(table);
289 
290  FREE(support);
291  return(1);
292 
293 } /* end of cuddInitInteract */
static void ddUpdateInteract(DdManager *table, char *support)
Definition: cuddInteract.c:374
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
int size
Definition: cuddInt.h:345
#define Cudd_Regular(node)
Definition: cudd.h:384
DdSubtable * subtables
Definition: cuddInt.h:349
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode sentinel
Definition: cuddInt.h:328
#define ALLOC(type, num)
Definition: util.h:76
DdNode * next
Definition: cudd.h:273
static void ddSuppInteract(DdNode *f, char *support)
Definition: cuddInteract.c:314
long * interact
Definition: cuddInt.h:377
static void ddClearLocal(DdNode *f)
Definition: cuddInteract.c:345
DdNode ** nodelist
Definition: cuddInt.h:311
static void ddClearGlobal(DdManager *table)
Definition: cuddInteract.c:410
unsigned int slots
Definition: cuddInt.h:313
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
#define LOGBPL
Definition: cuddInteract.c:90

◆ cuddInitLinear()

int cuddInitLinear ( DdManager table)

Function********************************************************************

Synopsis [Initializes the linear transform matrix.]

Description [Initializes the linear transform matrix. Returns 1 if successful; 0 otherwise.]

SideEffects [none]

SeeAlso []

Definition at line 755 of file cuddLinear.c.

757 {
758  int words;
759  int wordsPerRow;
760  int nvars;
761  int word;
762  int bit;
763  int i;
764  long *linear;
765 
766  nvars = table->size;
767  wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
768  words = wordsPerRow * nvars;
769  table->linear = linear = ALLOC(long,words);
770  if (linear == NULL) {
771  table->errorCode = CUDD_MEMORY_OUT;
772  return(0);
773  }
774  table->memused += words * sizeof(long);
775  table->linearSize = nvars;
776  for (i = 0; i < words; i++) linear[i] = 0;
777  for (i = 0; i < nvars; i++) {
778  word = wordsPerRow * i + (i >> LOGBPL);
779  bit = i & (BPL-1);
780  linear[word] = 1 << bit;
781  }
782  return(1);
783 
784 } /* end of cuddInitLinear */
#define BPL
Definition: cuddLinear.c:78
int size
Definition: cuddInt.h:345
#define LOGBPL
Definition: cuddLinear.c:79
#define ALLOC(type, num)
Definition: util.h:76
long * linear
Definition: cuddInt.h:378
int linearSize
Definition: cuddInt.h:376
unsigned long memused
Definition: cuddInt.h:429
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddInitTable()

DdManager* cuddInitTable ( unsigned int  numVars,
unsigned int  numVarsZ,
unsigned int  numSlots,
unsigned int  looseUpTo 
)

Function********************************************************************

Synopsis [Creates and initializes the unique table.]

Description [Creates and initializes the unique table. Returns a pointer to the table if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_Init cuddFreeTable]

Definition at line 380 of file cuddTable.c.

385 {
386  DdManager *unique = ALLOC(DdManager,1);
387  int i, j;
388  DdNodePtr *nodelist;
389  DdNode *sentinel;
390  unsigned int slots;
391  int shift;
392 
393  if (unique == NULL) {
394  return(NULL);
395  }
396  sentinel = &(unique->sentinel);
397  sentinel->ref = 0;
398  sentinel->index = 0;
399  cuddT(sentinel) = NULL;
400  cuddE(sentinel) = NULL;
401  sentinel->next = NULL;
402  unique->epsilon = DD_EPSILON;
403  unique->size = numVars;
404  unique->sizeZ = numVarsZ;
405  unique->maxSize = ddMax(DD_DEFAULT_RESIZE, numVars);
406  unique->maxSizeZ = ddMax(DD_DEFAULT_RESIZE, numVarsZ);
407 
408  /* Adjust the requested number of slots to a power of 2. */
409  slots = 8;
410  while (slots < numSlots) {
411  slots <<= 1;
412  }
413  unique->initSlots = slots;
414  shift = sizeof(int) * 8 - cuddComputeFloorLog2(slots);
415 
416  unique->slots = (numVars + numVarsZ + 1) * slots;
417  unique->keys = 0;
418  unique->maxLive = ~0; /* very large number */
419  unique->keysZ = 0;
420  unique->dead = 0;
421  unique->deadZ = 0;
422  unique->gcFrac = DD_GC_FRAC_HI;
423  unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots);
424  unique->looseUpTo = looseUpTo;
425  unique->gcEnabled = 1;
426  unique->allocated = 0;
427  unique->reclaimed = 0;
428  unique->subtables = ALLOC(DdSubtable,unique->maxSize);
429  if (unique->subtables == NULL) {
430  FREE(unique);
431  return(NULL);
432  }
433  unique->subtableZ = ALLOC(DdSubtable,unique->maxSizeZ);
434  if (unique->subtableZ == NULL) {
435  FREE(unique->subtables);
436  FREE(unique);
437  return(NULL);
438  }
439  unique->perm = ALLOC(int,unique->maxSize);
440  if (unique->perm == NULL) {
441  FREE(unique->subtables);
442  FREE(unique->subtableZ);
443  FREE(unique);
444  return(NULL);
445  }
446  unique->invperm = ALLOC(int,unique->maxSize);
447  if (unique->invperm == NULL) {
448  FREE(unique->subtables);
449  FREE(unique->subtableZ);
450  FREE(unique->perm);
451  FREE(unique);
452  return(NULL);
453  }
454  unique->permZ = ALLOC(int,unique->maxSizeZ);
455  if (unique->permZ == NULL) {
456  FREE(unique->subtables);
457  FREE(unique->subtableZ);
458  FREE(unique->perm);
459  FREE(unique->invperm);
460  FREE(unique);
461  return(NULL);
462  }
463  unique->invpermZ = ALLOC(int,unique->maxSizeZ);
464  if (unique->invpermZ == NULL) {
465  FREE(unique->subtables);
466  FREE(unique->subtableZ);
467  FREE(unique->perm);
468  FREE(unique->invperm);
469  FREE(unique->permZ);
470  FREE(unique);
471  return(NULL);
472  }
473  unique->map = NULL;
474  unique->stack = ALLOC(DdNodePtr,ddMax(unique->maxSize,unique->maxSizeZ)+1);
475  if (unique->stack == NULL) {
476  FREE(unique->subtables);
477  FREE(unique->subtableZ);
478  FREE(unique->perm);
479  FREE(unique->invperm);
480  FREE(unique->permZ);
481  FREE(unique->invpermZ);
482  FREE(unique);
483  return(NULL);
484  }
485  unique->stack[0] = NULL; /* to suppress harmless UMR */
486 
487 #ifndef DD_NO_DEATH_ROW
488  unique->deathRowDepth = 1 << cuddComputeFloorLog2(unique->looseUpTo >> 2);
489  unique->deathRow = ALLOC(DdNodePtr,unique->deathRowDepth);
490  if (unique->deathRow == NULL) {
491  FREE(unique->subtables);
492  FREE(unique->subtableZ);
493  FREE(unique->perm);
494  FREE(unique->invperm);
495  FREE(unique->permZ);
496  FREE(unique->invpermZ);
497  FREE(unique->stack);
498  FREE(unique);
499  return(NULL);
500  }
501  for (i = 0; i < unique->deathRowDepth; i++) {
502  unique->deathRow[i] = NULL;
503  }
504  unique->nextDead = 0;
505  unique->deadMask = unique->deathRowDepth - 1;
506 #endif
507 
508  for (i = 0; (unsigned) i < numVars; i++) {
509  unique->subtables[i].slots = slots;
510  unique->subtables[i].shift = shift;
511  unique->subtables[i].keys = 0;
512  unique->subtables[i].dead = 0;
513  unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
514  unique->subtables[i].bindVar = 0;
516  unique->subtables[i].pairIndex = 0;
517  unique->subtables[i].varHandled = 0;
519 
520  nodelist = unique->subtables[i].nodelist = ALLOC(DdNodePtr,slots);
521  if (nodelist == NULL) {
522  for (j = 0; j < i; j++) {
523  FREE(unique->subtables[j].nodelist);
524  }
525  FREE(unique->subtables);
526  FREE(unique->subtableZ);
527  FREE(unique->perm);
528  FREE(unique->invperm);
529  FREE(unique->permZ);
530  FREE(unique->invpermZ);
531  FREE(unique->stack);
532  FREE(unique);
533  return(NULL);
534  }
535  for (j = 0; (unsigned) j < slots; j++) {
536  nodelist[j] = sentinel;
537  }
538  unique->perm[i] = i;
539  unique->invperm[i] = i;
540  }
541  for (i = 0; (unsigned) i < numVarsZ; i++) {
542  unique->subtableZ[i].slots = slots;
543  unique->subtableZ[i].shift = shift;
544  unique->subtableZ[i].keys = 0;
545  unique->subtableZ[i].dead = 0;
546  unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
547  nodelist = unique->subtableZ[i].nodelist = ALLOC(DdNodePtr,slots);
548  if (nodelist == NULL) {
549  for (j = 0; (unsigned) j < numVars; j++) {
550  FREE(unique->subtables[j].nodelist);
551  }
552  FREE(unique->subtables);
553  for (j = 0; j < i; j++) {
554  FREE(unique->subtableZ[j].nodelist);
555  }
556  FREE(unique->subtableZ);
557  FREE(unique->perm);
558  FREE(unique->invperm);
559  FREE(unique->permZ);
560  FREE(unique->invpermZ);
561  FREE(unique->stack);
562  FREE(unique);
563  return(NULL);
564  }
565  for (j = 0; (unsigned) j < slots; j++) {
566  nodelist[j] = NULL;
567  }
568  unique->permZ[i] = i;
569  unique->invpermZ[i] = i;
570  }
571  unique->constants.slots = slots;
572  unique->constants.shift = shift;
573  unique->constants.keys = 0;
574  unique->constants.dead = 0;
575  unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
576  nodelist = unique->constants.nodelist = ALLOC(DdNodePtr,slots);
577  if (nodelist == NULL) {
578  for (j = 0; (unsigned) j < numVars; j++) {
579  FREE(unique->subtables[j].nodelist);
580  }
581  FREE(unique->subtables);
582  for (j = 0; (unsigned) j < numVarsZ; j++) {
583  FREE(unique->subtableZ[j].nodelist);
584  }
585  FREE(unique->subtableZ);
586  FREE(unique->perm);
587  FREE(unique->invperm);
588  FREE(unique->permZ);
589  FREE(unique->invpermZ);
590  FREE(unique->stack);
591  FREE(unique);
592  return(NULL);
593  }
594  for (j = 0; (unsigned) j < slots; j++) {
595  nodelist[j] = NULL;
596  }
597 
598  unique->memoryList = NULL;
599  unique->nextFree = NULL;
600 
601  unique->memused = sizeof(DdManager) + (unique->maxSize + unique->maxSizeZ)
602  * (sizeof(DdSubtable) + 2 * sizeof(int)) + (numVars + 1) *
603  slots * sizeof(DdNodePtr) +
604  (ddMax(unique->maxSize,unique->maxSizeZ) + 1) * sizeof(DdNodePtr);
605 #ifndef DD_NO_DEATH_ROW
606  unique->memused += unique->deathRowDepth * sizeof(DdNodePtr);
607 #endif
608 
609  /* Initialize fields concerned with automatic dynamic reordering. */
610  unique->reordered = 0;
611  unique->reorderings = 0;
612  unique->maxReorderings = ~0;
613  unique->siftMaxVar = DD_SIFT_MAX_VAR;
614  unique->siftMaxSwap = DD_SIFT_MAX_SWAPS;
616  unique->maxGrowthAlt = 2.0 * DD_MAX_REORDER_GROWTH;
617  unique->reordCycle = 0; /* do not use alternate threshold */
618  unique->autoDyn = 0; /* initially disabled */
619  unique->autoDynZ = 0; /* initially disabled */
620  unique->autoMethod = CUDD_REORDER_SIFT;
621  unique->autoMethodZ = CUDD_REORDER_SIFT;
622  unique->realign = 0; /* initially disabled */
623  unique->realignZ = 0; /* initially disabled */
624  unique->nextDyn = DD_FIRST_REORDER;
625  unique->countDead = ~0;
626  unique->tree = NULL;
627  unique->treeZ = NULL;
628  unique->groupcheck = CUDD_GROUP_CHECK7;
629  unique->recomb = DD_DEFAULT_RECOMB;
630  unique->symmviolation = 0;
631  unique->arcviolation = 0;
632  unique->populationSize = 0;
633  unique->numberXovers = 0;
634  unique->randomizeOrder = 0;
635  unique->linear = NULL;
636  unique->linearSize = 0;
637 
638  /* Initialize ZDD universe. */
639  unique->univ = (DdNodePtr *)NULL;
640 
641  /* Initialize auxiliary fields. */
642  unique->localCaches = NULL;
643  unique->preGCHook = NULL;
644  unique->postGCHook = NULL;
645  unique->preReorderingHook = NULL;
646  unique->postReorderingHook = NULL;
647  unique->out = stdout;
648  unique->err = stderr;
649  unique->errorCode = CUDD_NO_ERROR;
650  unique->startTime = util_cpu_time();
651  unique->timeLimit = ~0UL;
652 
653  /* Initialize statistical counters. */
654  unique->maxmemhard = ~ 0UL;
655  unique->garbageCollections = 0;
656  unique->GCTime = 0;
657  unique->reordTime = 0;
658 #ifdef DD_STATS
659  unique->nodesDropped = 0;
660  unique->nodesFreed = 0;
661 #endif
662  unique->peakLiveNodes = 0;
663 #ifdef DD_UNIQUE_PROFILE
664  unique->uniqueLookUps = 0;
665  unique->uniqueLinks = 0;
666 #endif
667 #ifdef DD_COUNT
668  unique->recursiveCalls = 0;
669  unique->swapSteps = 0;
670 #ifdef DD_STATS
671  unique->nextSample = 250000;
672 #endif
673 #endif
674 
675  return(unique);
676 
677 } /* end of cuddInitTable */
DdHalfWord ref
Definition: cudd.h:272
Cudd_AggregationType groupcheck
Definition: cuddInt.h:410
unsigned int keys
Definition: cuddInt.h:314
unsigned long reordTime
Definition: cuddInt.h:434
Cudd_ReorderingType autoMethod
Definition: cuddInt.h:402
#define DD_SIFT_MAX_VAR
Definition: cuddInt.h:148
unsigned int peakLiveNodes
Definition: cuddInt.h:445
int maxSizeZ
Definition: cuddInt.h:348
double allocated
Definition: cuddInt.h:365
int * map
Definition: cuddInt.h:374
Definition: cudd.h:270
unsigned int deadZ
Definition: cuddInt.h:356
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
DdHook * preReorderingHook
Definition: cuddInt.h:421
unsigned deadMask
Definition: cuddInt.h:387
unsigned long startTime
Definition: cuddInt.h:426
int * invpermZ
Definition: cuddInt.h:372
int reordCycle
Definition: cuddInt.h:399
int size
Definition: cuddInt.h:345
double gcFrac
Definition: cuddInt.h:359
struct DdManager DdManager
Definition: cudd.h:280
unsigned int slots
Definition: cuddInt.h:352
double maxGrowthAlt
Definition: cuddInt.h:398
int realign
Definition: cuddInt.h:404
double maxGrowth
Definition: cuddInt.h:397
FILE * err
Definition: cuddInt.h:424
int garbageCollections
Definition: cuddInt.h:432
int populationSize
Definition: cuddInt.h:414
#define DD_FIRST_REORDER
Definition: cuddInt.h:152
Cudd_ReorderingType autoMethodZ
Definition: cuddInt.h:403
int bindVar
Definition: cuddInt.h:318
DdSubtable * subtables
Definition: cuddInt.h:349
int * permZ
Definition: cuddInt.h:370
DdNode * DdNodePtr
Definition: cuddInt.h:253
#define DD_EPSILON
Definition: cuddInt.h:110
MtrNode * tree
Definition: cuddInt.h:408
struct DdSubtable DdSubtable
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
#define DD_DEFAULT_RECOMB
Definition: cuddInt.h:150
DdNode ** deathRow
Definition: cuddInt.h:384
DdNode ** stack
Definition: cuddInt.h:364
unsigned int countDead
Definition: cuddInt.h:407
unsigned int initSlots
Definition: cuddInt.h:363
unsigned int randomizeOrder
Definition: cuddInt.h:416
Cudd_VariableType varType
Definition: cuddInt.h:320
int reordered
Definition: cuddInt.h:392
unsigned int nextDyn
Definition: cuddInt.h:406
#define DD_GC_FRAC_HI
Definition: cuddInt.h:135
unsigned int dead
Definition: cuddInt.h:355
unsigned int maxLive
Definition: cuddInt.h:357
int recomb
Definition: cuddInt.h:411
DdNode sentinel
Definition: cuddInt.h:328
DdHook * postReorderingHook
Definition: cuddInt.h:422
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
unsigned int dead
Definition: cuddInt.h:316
FILE * out
Definition: cuddInt.h:423
#define DD_SIFT_MAX_SWAPS
Definition: cuddInt.h:149
int realignZ
Definition: cuddInt.h:405
DdNode * next
Definition: cudd.h:273
Cudd_LazyGroupType varToBeGrouped
Definition: cuddInt.h:323
int maxSize
Definition: cuddInt.h:347
unsigned int maxKeys
Definition: cuddInt.h:315
long * linear
Definition: cuddInt.h:378
int gcEnabled
Definition: cuddInt.h:360
#define ddMax(x, y)
Definition: cuddInt.h:785
int symmviolation
Definition: cuddInt.h:412
int numberXovers
Definition: cuddInt.h:415
DdNode ** nodelist
Definition: cuddInt.h:311
int linearSize
Definition: cuddInt.h:376
DdLocalCache * localCaches
Definition: cuddInt.h:417
long util_cpu_time(void)
Definition: cpu_time.c:34
#define cuddT(node)
Definition: cuddInt.h:609
int nextDead
Definition: cuddInt.h:386
int varHandled
Definition: cuddInt.h:322
unsigned long GCTime
Definition: cuddInt.h:433
DdNode ** memoryList
Definition: cuddInt.h:380
unsigned int maxReorderings
Definition: cuddInt.h:394
unsigned long memused
Definition: cuddInt.h:429
int siftMaxVar
Definition: cuddInt.h:395
int deathRowDepth
Definition: cuddInt.h:385
DdNode * nextFree
Definition: cuddInt.h:381
#define DD_DEFAULT_RESIZE
Definition: cuddInt.h:103
int sizeZ
Definition: cuddInt.h:346
DdHalfWord index
Definition: cudd.h:271
unsigned int looseUpTo
Definition: cuddInt.h:361
unsigned int slots
Definition: cuddInt.h:313
unsigned int reorderings
Definition: cuddInt.h:393
unsigned long maxmemhard
Definition: cuddInt.h:431
DdHook * postGCHook
Definition: cuddInt.h:420
int pairIndex
Definition: cuddInt.h:321
#define DD_MAX_REORDER_GROWTH
Definition: cuddInt.h:151
CUDD_VALUE_TYPE epsilon
Definition: cuddInt.h:390
MtrNode * treeZ
Definition: cuddInt.h:409
int autoDynZ
Definition: cuddInt.h:401
#define cuddE(node)
Definition: cuddInt.h:625
int arcviolation
Definition: cuddInt.h:413
int * invperm
Definition: cuddInt.h:371
DdSubtable constants
Definition: cuddInt.h:351
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1036
int autoDyn
Definition: cuddInt.h:400
int shift
Definition: cuddInt.h:312
unsigned int keysZ
Definition: cuddInt.h:354
DdHook * preGCHook
Definition: cuddInt.h:419
int * perm
Definition: cuddInt.h:369
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
unsigned int minDead
Definition: cuddInt.h:358
double reclaimed
Definition: cuddInt.h:367
DdSubtable * subtableZ
Definition: cuddInt.h:350
DdNode ** univ
Definition: cuddInt.h:375

◆ cuddInsertSubtables()

int cuddInsertSubtables ( DdManager unique,
int  n,
int  level 
)

Function********************************************************************

Synopsis [Inserts n new subtables in a unique table at level.]

Description [Inserts n new subtables in a unique table at level. The number n should be positive, and level should be an existing level. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddDestroySubtables]

Definition at line 1824 of file cuddTable.c.

1828 {
1829  DdSubtable *newsubtables;
1830  DdNodePtr *newnodelist;
1831  DdNodePtr *newvars;
1832  DdNode *sentinel = &(unique->sentinel);
1833  int oldsize,newsize;
1834  int i,j,index,reorderSave;
1835  unsigned int numSlots = unique->initSlots;
1836  int *newperm, *newinvperm, *newmap;
1837  DdNode *one, *zero;
1838 
1839 #ifdef DD_DEBUG
1840  assert(n > 0 && level < unique->size);
1841 #endif
1842 
1843  oldsize = unique->size;
1844  /* Easy case: there is still room in the current table. */
1845  if (oldsize + n <= unique->maxSize) {
1846  /* Shift the tables at and below level. */
1847  for (i = oldsize - 1; i >= level; i--) {
1848  unique->subtables[i+n].slots = unique->subtables[i].slots;
1849  unique->subtables[i+n].shift = unique->subtables[i].shift;
1850  unique->subtables[i+n].keys = unique->subtables[i].keys;
1851  unique->subtables[i+n].maxKeys = unique->subtables[i].maxKeys;
1852  unique->subtables[i+n].dead = unique->subtables[i].dead;
1853  unique->subtables[i+n].nodelist = unique->subtables[i].nodelist;
1854  unique->subtables[i+n].bindVar = unique->subtables[i].bindVar;
1855  unique->subtables[i+n].varType = unique->subtables[i].varType;
1856  unique->subtables[i+n].pairIndex = unique->subtables[i].pairIndex;
1857  unique->subtables[i+n].varHandled = unique->subtables[i].varHandled;
1858  unique->subtables[i+n].varToBeGrouped =
1859  unique->subtables[i].varToBeGrouped;
1860 
1861  index = unique->invperm[i];
1862  unique->invperm[i+n] = index;
1863  unique->perm[index] += n;
1864  }
1865  /* Create new subtables. */
1866  for (i = 0; i < n; i++) {
1867  unique->subtables[level+i].slots = numSlots;
1868  unique->subtables[level+i].shift = sizeof(int) * 8 -
1869  cuddComputeFloorLog2(numSlots);
1870  unique->subtables[level+i].keys = 0;
1871  unique->subtables[level+i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY;
1872  unique->subtables[level+i].dead = 0;
1873  unique->subtables[level+i].bindVar = 0;
1874  unique->subtables[level+i].varType = CUDD_VAR_PRIMARY_INPUT;
1875  unique->subtables[level+i].pairIndex = 0;
1876  unique->subtables[level+i].varHandled = 0;
1877  unique->subtables[level+i].varToBeGrouped = CUDD_LAZY_NONE;
1878 
1879  unique->perm[oldsize+i] = level + i;
1880  unique->invperm[level+i] = oldsize + i;
1881  newnodelist = unique->subtables[level+i].nodelist =
1882  ALLOC(DdNodePtr, numSlots);
1883  if (newnodelist == NULL) {
1884  unique->errorCode = CUDD_MEMORY_OUT;
1885  return(0);
1886  }
1887  for (j = 0; (unsigned) j < numSlots; j++) {
1888  newnodelist[j] = sentinel;
1889  }
1890  }
1891  if (unique->map != NULL) {
1892  for (i = 0; i < n; i++) {
1893  unique->map[oldsize+i] = oldsize + i;
1894  }
1895  }
1896  } else {
1897  /* The current table is too small: we need to allocate a new,
1898  ** larger one; move all old subtables, and initialize the new
1899  ** subtables.
1900  */
1901  newsize = oldsize + n + DD_DEFAULT_RESIZE;
1902 #ifdef DD_VERBOSE
1903  (void) fprintf(unique->err,
1904  "Increasing the table size from %d to %d\n",
1905  unique->maxSize, newsize);
1906 #endif
1907  /* Allocate memory for new arrays (except nodelists). */
1908  newsubtables = ALLOC(DdSubtable,newsize);
1909  if (newsubtables == NULL) {
1910  unique->errorCode = CUDD_MEMORY_OUT;
1911  return(0);
1912  }
1913  newvars = ALLOC(DdNodePtr,newsize);
1914  if (newvars == NULL) {
1915  unique->errorCode = CUDD_MEMORY_OUT;
1916  FREE(newsubtables);
1917  return(0);
1918  }
1919  newperm = ALLOC(int,newsize);
1920  if (newperm == NULL) {
1921  unique->errorCode = CUDD_MEMORY_OUT;
1922  FREE(newsubtables);
1923  FREE(newvars);
1924  return(0);
1925  }
1926  newinvperm = ALLOC(int,newsize);
1927  if (newinvperm == NULL) {
1928  unique->errorCode = CUDD_MEMORY_OUT;
1929  FREE(newsubtables);
1930  FREE(newvars);
1931  FREE(newperm);
1932  return(0);
1933  }
1934  if (unique->map != NULL) {
1935  newmap = ALLOC(int,newsize);
1936  if (newmap == NULL) {
1937  unique->errorCode = CUDD_MEMORY_OUT;
1938  FREE(newsubtables);
1939  FREE(newvars);
1940  FREE(newperm);
1941  FREE(newinvperm);
1942  return(0);
1943  }
1944  unique->memused += (newsize - unique->maxSize) * sizeof(int);
1945  }
1946  unique->memused += (newsize - unique->maxSize) * ((numSlots+1) *
1947  sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable));
1948  /* Copy levels before insertion points from old tables. */
1949  for (i = 0; i < level; i++) {
1950  newsubtables[i].slots = unique->subtables[i].slots;
1951  newsubtables[i].shift = unique->subtables[i].shift;
1952  newsubtables[i].keys = unique->subtables[i].keys;
1953  newsubtables[i].maxKeys = unique->subtables[i].maxKeys;
1954  newsubtables[i].dead = unique->subtables[i].dead;
1955  newsubtables[i].nodelist = unique->subtables[i].nodelist;
1956  newsubtables[i].bindVar = unique->subtables[i].bindVar;
1957  newsubtables[i].varType = unique->subtables[i].varType;
1958  newsubtables[i].pairIndex = unique->subtables[i].pairIndex;
1959  newsubtables[i].varHandled = unique->subtables[i].varHandled;
1960  newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped;
1961 
1962  newvars[i] = unique->vars[i];
1963  newperm[i] = unique->perm[i];
1964  newinvperm[i] = unique->invperm[i];
1965  }
1966  /* Finish initializing permutation for new table to old one. */
1967  for (i = level; i < oldsize; i++) {
1968  newperm[i] = unique->perm[i];
1969  }
1970  /* Initialize new levels. */
1971  for (i = level; i < level + n; i++) {
1972  newsubtables[i].slots = numSlots;
1973  newsubtables[i].shift = sizeof(int) * 8 -
1974  cuddComputeFloorLog2(numSlots);
1975  newsubtables[i].keys = 0;
1976  newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY;
1977  newsubtables[i].dead = 0;
1978  newsubtables[i].bindVar = 0;
1979  newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT;
1980  newsubtables[i].pairIndex = 0;
1981  newsubtables[i].varHandled = 0;
1982  newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE;
1983 
1984  newperm[oldsize + i - level] = i;
1985  newinvperm[i] = oldsize + i - level;
1986  newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots);
1987  if (newnodelist == NULL) {
1988  /* We are going to leak some memory. We should clean up. */
1989  unique->errorCode = CUDD_MEMORY_OUT;
1990  return(0);
1991  }
1992  for (j = 0; (unsigned) j < numSlots; j++) {
1993  newnodelist[j] = sentinel;
1994  }
1995  }
1996  /* Copy the old tables for levels past the insertion point. */
1997  for (i = level; i < oldsize; i++) {
1998  newsubtables[i+n].slots = unique->subtables[i].slots;
1999  newsubtables[i+n].shift = unique->subtables[i].shift;
2000  newsubtables[i+n].keys = unique->subtables[i].keys;
2001  newsubtables[i+n].maxKeys = unique->subtables[i].maxKeys;
2002  newsubtables[i+n].dead = unique->subtables[i].dead;
2003  newsubtables[i+n].nodelist = unique->subtables[i].nodelist;
2004  newsubtables[i+n].bindVar = unique->subtables[i].bindVar;
2005  newsubtables[i+n].varType = unique->subtables[i].varType;
2006  newsubtables[i+n].pairIndex = unique->subtables[i].pairIndex;
2007  newsubtables[i+n].varHandled = unique->subtables[i].varHandled;
2008  newsubtables[i+n].varToBeGrouped =
2009  unique->subtables[i].varToBeGrouped;
2010 
2011  newvars[i] = unique->vars[i];
2012  index = unique->invperm[i];
2013  newinvperm[i+n] = index;
2014  newperm[index] += n;
2015  }
2016  /* Update the map. */
2017  if (unique->map != NULL) {
2018  for (i = 0; i < oldsize; i++) {
2019  newmap[i] = unique->map[i];
2020  }
2021  for (i = oldsize; i < oldsize + n; i++) {
2022  newmap[i] = i;
2023  }
2024  FREE(unique->map);
2025  unique->map = newmap;
2026  }
2027  /* Install the new tables and free the old ones. */
2028  FREE(unique->subtables);
2029  unique->subtables = newsubtables;
2030  unique->maxSize = newsize;
2031  FREE(unique->vars);
2032  unique->vars = newvars;
2033  FREE(unique->perm);
2034  unique->perm = newperm;
2035  FREE(unique->invperm);
2036  unique->invperm = newinvperm;
2037  /* Update the stack for iterative procedures. */
2038  if (newsize > unique->maxSizeZ) {
2039  FREE(unique->stack);
2040  unique->stack = ALLOC(DdNodePtr,newsize + 1);
2041  if (unique->stack == NULL) {
2042  unique->errorCode = CUDD_MEMORY_OUT;
2043  return(0);
2044  }
2045  unique->stack[0] = NULL; /* to suppress harmless UMR */
2046  unique->memused +=
2047  (newsize - ddMax(unique->maxSize,unique->maxSizeZ))
2048  * sizeof(DdNode *);
2049  }
2050  }
2051  /* Update manager parameters to account for the new subtables. */
2052  unique->slots += n * numSlots;
2053  ddFixLimits(unique);
2054  unique->size += n;
2055 
2056  /* Now that the table is in a coherent state, create the new
2057  ** projection functions. We need to temporarily disable reordering,
2058  ** because we cannot reorder without projection functions in place.
2059  **/
2060  one = unique->one;
2061  zero = Cudd_Not(one);
2062 
2063  reorderSave = unique->autoDyn;
2064  unique->autoDyn = 0;
2065  for (i = oldsize; i < oldsize + n; i++) {
2066  unique->vars[i] = cuddUniqueInter(unique,i,one,zero);
2067  if (unique->vars[i] == NULL) {
2068  unique->autoDyn = reorderSave;
2069  /* Shift everything back so table remains coherent. */
2070  for (j = oldsize; j < i; j++) {
2071  Cudd_IterDerefBdd(unique,unique->vars[j]);
2072  cuddDeallocNode(unique,unique->vars[j]);
2073  unique->vars[j] = NULL;
2074  }
2075  for (j = level; j < oldsize; j++) {
2076  unique->subtables[j].slots = unique->subtables[j+n].slots;
2077  unique->subtables[j].slots = unique->subtables[j+n].slots;
2078  unique->subtables[j].shift = unique->subtables[j+n].shift;
2079  unique->subtables[j].keys = unique->subtables[j+n].keys;
2080  unique->subtables[j].maxKeys =
2081  unique->subtables[j+n].maxKeys;
2082  unique->subtables[j].dead = unique->subtables[j+n].dead;
2083  FREE(unique->subtables[j].nodelist);
2084  unique->subtables[j].nodelist =
2085  unique->subtables[j+n].nodelist;
2086  unique->subtables[j+n].nodelist = NULL;
2087  unique->subtables[j].bindVar =
2088  unique->subtables[j+n].bindVar;
2089  unique->subtables[j].varType =
2090  unique->subtables[j+n].varType;
2091  unique->subtables[j].pairIndex =
2092  unique->subtables[j+n].pairIndex;
2093  unique->subtables[j].varHandled =
2094  unique->subtables[j+n].varHandled;
2095  unique->subtables[j].varToBeGrouped =
2096  unique->subtables[j+n].varToBeGrouped;
2097  index = unique->invperm[j+n];
2098  unique->invperm[j] = index;
2099  unique->perm[index] -= n;
2100  }
2101  unique->size = oldsize;
2102  unique->slots -= n * numSlots;
2103  ddFixLimits(unique);
2104  (void) Cudd_DebugCheck(unique);
2105  return(0);
2106  }
2107  cuddRef(unique->vars[i]);
2108  }
2109  if (unique->tree != NULL) {
2110  unique->tree->size += n;
2111  unique->tree->index = unique->invperm[0];
2112  ddPatchTree(unique,unique->tree);
2113  }
2114  unique->autoDyn = reorderSave;
2115 
2116  return(1);
2117 
2118 } /* end of cuddInsertSubtables */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
#define cuddRef(n)
Definition: cuddInt.h:557
unsigned int keys
Definition: cuddInt.h:314
int maxSizeZ
Definition: cuddInt.h:348
int * map
Definition: cuddInt.h:374
Definition: cudd.h:270
static void ddPatchTree(DdManager *dd, MtrNode *treenode)
Definition: cuddTable.c:3118
#define Cudd_Not(node)
Definition: cudd.h:354
MtrHalfWord size
Definition: mtr.h:129
#define FREE(obj)
Definition: util.h:80
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
unsigned int slots
Definition: cuddInt.h:352
FILE * err
Definition: cuddInt.h:424
int bindVar
Definition: cuddInt.h:318
DdSubtable * subtables
Definition: cuddInt.h:349
MtrNode * tree
Definition: cuddInt.h:408
struct DdSubtable DdSubtable
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
DdNode ** stack
Definition: cuddInt.h:364
unsigned int initSlots
Definition: cuddInt.h:363
Cudd_VariableType varType
Definition: cuddInt.h:320
static DdNode * one
Definition: cuddSat.c:105
DdNode sentinel
Definition: cuddInt.h:328
MtrHalfWord index
Definition: mtr.h:130
#define ALLOC(type, num)
Definition: util.h:76
unsigned int dead
Definition: cuddInt.h:316
Cudd_LazyGroupType varToBeGrouped
Definition: cuddInt.h:323
int maxSize
Definition: cuddInt.h:347
unsigned int maxKeys
Definition: cuddInt.h:315
#define ddMax(x, y)
Definition: cuddInt.h:785
DdNode ** nodelist
Definition: cuddInt.h:311
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:138
int varHandled
Definition: cuddInt.h:322
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:520
unsigned long memused
Definition: cuddInt.h:429
#define DD_DEFAULT_RESIZE
Definition: cuddInt.h:103
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
int pairIndex
Definition: cuddInt.h:321
static DdNode * zero
Definition: cuddSat.c:105
DdNode * one
Definition: cuddInt.h:329
static DD_INLINE void ddFixLimits(DdManager *unique)
Definition: cuddTable.c:2843
int * invperm
Definition: cuddInt.h:371
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1036
int autoDyn
Definition: cuddInt.h:400
int shift
Definition: cuddInt.h:312
int * perm
Definition: cuddInt.h:369
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddIsInDeathRow()

int cuddIsInDeathRow ( DdManager dd,
DdNode f 
)

Function********************************************************************

Synopsis [Checks whether a node is in the death row.]

Description [Checks whether a node is in the death row. Returns the position of the first occurrence if the node is present; -1 otherwise.]

SideEffects [None]

SeeAlso [Cudd_DelayedDerefBdd cuddClearDeathRow]

Definition at line 758 of file cuddRef.c.

761 {
762 #ifndef DD_NO_DEATH_ROW
763  int i;
764 
765  for (i = 0; i < dd->deathRowDepth; i++) {
766  if (f == dd->deathRow[i]) {
767  return(i);
768  }
769  }
770 #endif
771 
772  return(-1);
773 
774 } /* end of cuddIsInDeathRow */
DdNode ** deathRow
Definition: cuddInt.h:384
int deathRowDepth
Definition: cuddInt.h:385

◆ cuddLevelQueueDequeue()

void cuddLevelQueueDequeue ( DdLevelQueue queue,
int  level 
)

◆ cuddLevelQueueEnqueue()

void* cuddLevelQueueEnqueue ( DdLevelQueue queue,
void *  key,
int  level 
)

◆ cuddLevelQueueFirst()

void* cuddLevelQueueFirst ( DdLevelQueue queue,
void *  key,
int  level 
)

◆ cuddLevelQueueInit()

DdLevelQueue* cuddLevelQueueInit ( int  levels,
int  itemSize,
int  numBuckets 
)

◆ cuddLevelQueueQuit()

void cuddLevelQueueQuit ( DdLevelQueue queue)

◆ cuddLinearAndSifting()

int cuddLinearAndSifting ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [BDD reduction based on combination of sifting and linear transformations.]

Description [BDD reduction based on combination of sifting and linear transformations. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique table.
  2. Sift the variable up and down, remembering each time the total size of the DD heap. At each position, linear transformation of the two adjacent variables is tried and is accepted if it reduces the size of the DD.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 236 of file cuddLinear.c.

240 {
241  int i;
242  int *var;
243  int size;
244  int x;
245  int result;
246 #ifdef DD_STATS
247  int previousSize;
248 #endif
249 
250 #ifdef DD_STATS
251  ddTotalNumberLinearTr = 0;
252 #endif
253 
254  size = table->size;
255 
256  var = NULL;
257  entry = NULL;
258  if (table->linear == NULL) {
259  result = cuddInitLinear(table);
260  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
261 #if 0
262  (void) fprintf(table->out,"\n");
263  result = Cudd_PrintLinear(table);
264  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
265 #endif
266  } else if (table->size != table->linearSize) {
267  result = cuddResizeLinear(table);
268  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
269 #if 0
270  (void) fprintf(table->out,"\n");
271  result = Cudd_PrintLinear(table);
272  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
273 #endif
274  }
275 
276  /* Find order in which to sift variables. */
277  entry = ALLOC(int,size);
278  if (entry == NULL) {
279  table->errorCode = CUDD_MEMORY_OUT;
280  goto cuddLinearAndSiftingOutOfMem;
281  }
282  var = ALLOC(int,size);
283  if (var == NULL) {
284  table->errorCode = CUDD_MEMORY_OUT;
285  goto cuddLinearAndSiftingOutOfMem;
286  }
287 
288  for (i = 0; i < size; i++) {
289  x = table->perm[i];
290  entry[i] = table->subtables[x].keys;
291  var[i] = i;
292  }
293 
294  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddLinearUniqueCompare);
295 
296  /* Now sift. */
297  for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
298  x = table->perm[var[i]];
299  if (x < lower || x > upper) continue;
300 #ifdef DD_STATS
301  previousSize = table->keys - table->isolated;
302 #endif
303  result = ddLinearAndSiftingAux(table,x,lower,upper);
304  if (!result) goto cuddLinearAndSiftingOutOfMem;
305 #ifdef DD_STATS
306  if (table->keys < (unsigned) previousSize + table->isolated) {
307  (void) fprintf(table->out,"-");
308  } else if (table->keys > (unsigned) previousSize + table->isolated) {
309  (void) fprintf(table->out,"+"); /* should never happen */
310  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]);
311  } else {
312  (void) fprintf(table->out,"=");
313  }
314  fflush(table->out);
315 #endif
316 #ifdef DD_DEBUG
317  (void) Cudd_DebugCheck(table);
318 #endif
319  }
320 
321  FREE(var);
322  FREE(entry);
323 
324 #ifdef DD_STATS
325  (void) fprintf(table->out,"\n#:L_LINSIFT %8d: linear trans.",
326  ddTotalNumberLinearTr);
327 #endif
328 
329  return(1);
330 
331 cuddLinearAndSiftingOutOfMem:
332 
333  if (entry != NULL) FREE(entry);
334  if (var != NULL) FREE(var);
335 
336  return(0);
337 
338 } /* end of cuddLinearAndSifting */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:313
int size
Definition: cuddInt.h:345
int cuddInitLinear(DdManager *table)
Definition: cuddLinear.c:755
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddResizeLinear(DdManager *table)
Definition: cuddLinear.c:800
int Cudd_PrintLinear(DdManager *table)
Definition: cuddLinear.c:149
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
long * linear
Definition: cuddInt.h:378
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:138
int linearSize
Definition: cuddInt.h:376
#define ddMin(x, y)
Definition: cuddInt.h:771
int siftMaxVar
Definition: cuddInt.h:395
static int * entry
Definition: cuddLinear.c:98
static int ddLinearUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddLinear.c:868
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368
int * perm
Definition: cuddInt.h:369
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
static int ddLinearAndSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddLinear.c:896

◆ cuddLinearInPlace()

int cuddLinearInPlace ( DdManager table,
int  x,
int  y 
)

Function********************************************************************

Synopsis [Linearly combines two adjacent variables.]

Description [Linearly combines two adjacent variables. Specifically, replaces the top variable with the exclusive nor of the two variables. It assumes that no dead nodes are present on entry to this procedure. The procedure then guarantees that no dead nodes will be present when it terminates. cuddLinearInPlace assumes that x < y. Returns the number of keys in the table if successful; 0 otherwise.]

SideEffects [The two subtables corrresponding to variables x and y are modified. The global counters of the unique table are also affected.]

SeeAlso [cuddSwapInPlace]

Definition at line 360 of file cuddLinear.c.

364 {
365  DdNodePtr *xlist, *ylist;
366  int xindex, yindex;
367  int xslots, yslots;
368  int xshift, yshift;
369  int oldxkeys, oldykeys;
370  int newxkeys, newykeys;
371  int comple, newcomplement;
372  int i;
373  int posn;
374  int isolated;
375  DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0;
376  DdNode *g,*next,*last;
377  DdNodePtr *previousP;
378  DdNode *tmp;
379  DdNode *sentinel = &(table->sentinel);
380 #ifdef DD_DEBUG
381  int count, idcheck;
382 #endif
383 
384 #ifdef DD_DEBUG
385  assert(x < y);
386  assert(cuddNextHigh(table,x) == y);
387  assert(table->subtables[x].keys != 0);
388  assert(table->subtables[y].keys != 0);
389  assert(table->subtables[x].dead == 0);
390  assert(table->subtables[y].dead == 0);
391 #endif
392 
393  xindex = table->invperm[x];
394  yindex = table->invperm[y];
395 
396  if (cuddTestInteract(table,xindex,yindex)) {
397 #ifdef DD_STATS
398  ddTotalNumberLinearTr++;
399 #endif
400  /* Get parameters of x subtable. */
401  xlist = table->subtables[x].nodelist;
402  oldxkeys = table->subtables[x].keys;
403  xslots = table->subtables[x].slots;
404  xshift = table->subtables[x].shift;
405 
406  /* Get parameters of y subtable. */
407  ylist = table->subtables[y].nodelist;
408  oldykeys = table->subtables[y].keys;
409  yslots = table->subtables[y].slots;
410  yshift = table->subtables[y].shift;
411 
412  newxkeys = 0;
413  newykeys = oldykeys;
414 
415  /* Check whether the two projection functions involved in this
416  ** swap are isolated. At the end, we'll be able to tell how many
417  ** isolated projection functions are there by checking only these
418  ** two functions again. This is done to eliminate the isolated
419  ** projection functions from the node count.
420  */
421  isolated = - ((table->vars[xindex]->ref == 1) +
422  (table->vars[yindex]->ref == 1));
423 
424  /* The nodes in the x layer are put in a chain.
425  ** The chain is handled as a FIFO; g points to the beginning and
426  ** last points to the end.
427  */
428  g = NULL;
429 #ifdef DD_DEBUG
430  last = NULL;
431 #endif
432  for (i = 0; i < xslots; i++) {
433  f = xlist[i];
434  if (f == sentinel) continue;
435  xlist[i] = sentinel;
436  if (g == NULL) {
437  g = f;
438  } else {
439  last->next = f;
440  }
441  while ((next = f->next) != sentinel) {
442  f = next;
443  } /* while there are elements in the collision chain */
444  last = f;
445  } /* for each slot of the x subtable */
446 #ifdef DD_DEBUG
447  /* last is always assigned in the for loop because there is at
448  ** least one key */
449  assert(last != NULL);
450 #endif
451  last->next = NULL;
452 
453 #ifdef DD_COUNT
454  table->swapSteps += oldxkeys;
455 #endif
456  /* Take care of the x nodes that must be re-expressed.
457  ** They form a linked list pointed by g.
458  */
459  f = g;
460  while (f != NULL) {
461  next = f->next;
462  /* Find f1, f0, f11, f10, f01, f00. */
463  f1 = cuddT(f);
464 #ifdef DD_DEBUG
465  assert(!(Cudd_IsComplement(f1)));
466 #endif
467  if ((int) f1->index == yindex) {
468  f11 = cuddT(f1); f10 = cuddE(f1);
469  } else {
470  f11 = f10 = f1;
471  }
472 #ifdef DD_DEBUG
473  assert(!(Cudd_IsComplement(f11)));
474 #endif
475  f0 = cuddE(f);
476  comple = Cudd_IsComplement(f0);
477  f0 = Cudd_Regular(f0);
478  if ((int) f0->index == yindex) {
479  f01 = cuddT(f0); f00 = cuddE(f0);
480  } else {
481  f01 = f00 = f0;
482  }
483  if (comple) {
484  f01 = Cudd_Not(f01);
485  f00 = Cudd_Not(f00);
486  }
487  /* Decrease ref count of f1. */
488  cuddSatDec(f1->ref);
489  /* Create the new T child. */
490  if (f11 == f00) {
491  newf1 = f11;
492  cuddSatInc(newf1->ref);
493  } else {
494  /* Check ylist for triple (yindex,f11,f00). */
495  posn = ddHash(f11, f00, yshift);
496  /* For each element newf1 in collision list ylist[posn]. */
497  previousP = &(ylist[posn]);
498  newf1 = *previousP;
499  while (f11 < cuddT(newf1)) {
500  previousP = &(newf1->next);
501  newf1 = *previousP;
502  }
503  while (f11 == cuddT(newf1) && f00 < cuddE(newf1)) {
504  previousP = &(newf1->next);
505  newf1 = *previousP;
506  }
507  if (cuddT(newf1) == f11 && cuddE(newf1) == f00) {
508  cuddSatInc(newf1->ref);
509  } else { /* no match */
510  newf1 = cuddDynamicAllocNode(table);
511  if (newf1 == NULL)
512  goto cuddLinearOutOfMem;
513  newf1->index = yindex; newf1->ref = 1;
514  cuddT(newf1) = f11;
515  cuddE(newf1) = f00;
516  /* Insert newf1 in the collision list ylist[posn];
517  ** increase the ref counts of f11 and f00.
518  */
519  newykeys++;
520  newf1->next = *previousP;
521  *previousP = newf1;
522  cuddSatInc(f11->ref);
523  tmp = Cudd_Regular(f00);
524  cuddSatInc(tmp->ref);
525  }
526  }
527  cuddT(f) = newf1;
528 #ifdef DD_DEBUG
529  assert(!(Cudd_IsComplement(newf1)));
530 #endif
531 
532  /* Do the same for f0, keeping complement dots into account. */
533  /* decrease ref count of f0 */
534  tmp = Cudd_Regular(f0);
535  cuddSatDec(tmp->ref);
536  /* create the new E child */
537  if (f01 == f10) {
538  newf0 = f01;
539  tmp = Cudd_Regular(newf0);
540  cuddSatInc(tmp->ref);
541  } else {
542  /* make sure f01 is regular */
543  newcomplement = Cudd_IsComplement(f01);
544  if (newcomplement) {
545  f01 = Cudd_Not(f01);
546  f10 = Cudd_Not(f10);
547  }
548  /* Check ylist for triple (yindex,f01,f10). */
549  posn = ddHash(f01, f10, yshift);
550  /* For each element newf0 in collision list ylist[posn]. */
551  previousP = &(ylist[posn]);
552  newf0 = *previousP;
553  while (f01 < cuddT(newf0)) {
554  previousP = &(newf0->next);
555  newf0 = *previousP;
556  }
557  while (f01 == cuddT(newf0) && f10 < cuddE(newf0)) {
558  previousP = &(newf0->next);
559  newf0 = *previousP;
560  }
561  if (cuddT(newf0) == f01 && cuddE(newf0) == f10) {
562  cuddSatInc(newf0->ref);
563  } else { /* no match */
564  newf0 = cuddDynamicAllocNode(table);
565  if (newf0 == NULL)
566  goto cuddLinearOutOfMem;
567  newf0->index = yindex; newf0->ref = 1;
568  cuddT(newf0) = f01;
569  cuddE(newf0) = f10;
570  /* Insert newf0 in the collision list ylist[posn];
571  ** increase the ref counts of f01 and f10.
572  */
573  newykeys++;
574  newf0->next = *previousP;
575  *previousP = newf0;
576  cuddSatInc(f01->ref);
577  tmp = Cudd_Regular(f10);
578  cuddSatInc(tmp->ref);
579  }
580  if (newcomplement) {
581  newf0 = Cudd_Not(newf0);
582  }
583  }
584  cuddE(f) = newf0;
585 
586  /* Re-insert the modified f in xlist.
587  ** The modified f does not already exists in xlist.
588  ** (Because of the uniqueness of the cofactors.)
589  */
590  posn = ddHash(newf1, newf0, xshift);
591  newxkeys++;
592  previousP = &(xlist[posn]);
593  tmp = *previousP;
594  while (newf1 < cuddT(tmp)) {
595  previousP = &(tmp->next);
596  tmp = *previousP;
597  }
598  while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) {
599  previousP = &(tmp->next);
600  tmp = *previousP;
601  }
602  f->next = *previousP;
603  *previousP = f;
604  f = next;
605  } /* while f != NULL */
606 
607  /* GC the y layer. */
608 
609  /* For each node f in ylist. */
610  for (i = 0; i < yslots; i++) {
611  previousP = &(ylist[i]);
612  f = *previousP;
613  while (f != sentinel) {
614  next = f->next;
615  if (f->ref == 0) {
616  tmp = cuddT(f);
617  cuddSatDec(tmp->ref);
618  tmp = Cudd_Regular(cuddE(f));
619  cuddSatDec(tmp->ref);
620  cuddDeallocNode(table,f);
621  newykeys--;
622  } else {
623  *previousP = f;
624  previousP = &(f->next);
625  }
626  f = next;
627  } /* while f */
628  *previousP = sentinel;
629  } /* for every collision list */
630 
631 #ifdef DD_DEBUG
632 #if 0
633  (void) fprintf(table->out,"Linearly combining %d and %d\n",x,y);
634 #endif
635  count = 0;
636  idcheck = 0;
637  for (i = 0; i < yslots; i++) {
638  f = ylist[i];
639  while (f != sentinel) {
640  count++;
641  if (f->index != (DdHalfWord) yindex)
642  idcheck++;
643  f = f->next;
644  }
645  }
646  if (count != newykeys) {
647  fprintf(table->err,"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count);
648  }
649  if (idcheck != 0)
650  fprintf(table->err,"Error in id's of ylist\twrong id's = %d\n",idcheck);
651  count = 0;
652  idcheck = 0;
653  for (i = 0; i < xslots; i++) {
654  f = xlist[i];
655  while (f != sentinel) {
656  count++;
657  if (f->index != (DdHalfWord) xindex)
658  idcheck++;
659  f = f->next;
660  }
661  }
662  if (count != newxkeys || newxkeys != oldxkeys) {
663  fprintf(table->err,"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count);
664  }
665  if (idcheck != 0)
666  fprintf(table->err,"Error in id's of xlist\twrong id's = %d\n",idcheck);
667 #endif
668 
669  isolated += (table->vars[xindex]->ref == 1) +
670  (table->vars[yindex]->ref == 1);
671  table->isolated += isolated;
672 
673  /* Set the appropriate fields in table. */
674  table->subtables[y].keys = newykeys;
675 
676  /* Here we should update the linear combination table
677  ** to record that x <- x EXNOR y. This is done by complementing
678  ** the (x,y) entry of the table.
679  */
680 
681  table->keys += newykeys - oldykeys;
682 
683  cuddXorLinear(table,xindex,yindex);
684  }
685 
686 #ifdef DD_DEBUG
687  if (zero) {
688  (void) Cudd_DebugCheck(table);
689  }
690 #endif
691 
692  return(table->keys - table->isolated);
693 
694 cuddLinearOutOfMem:
695  (void) fprintf(table->err,"Error: cuddLinearInPlace out of memory\n");
696 
697  return (0);
698 
699 } /* end of cuddLinearInPlace */
DdHalfWord ref
Definition: cudd.h:272
unsigned int keys
Definition: cuddInt.h:314
unsigned short DdHalfWord
Definition: cudd.h:259
#define ddHash(f, g, s)
Definition: cuddInt.h:696
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
static void cuddXorLinear(DdManager *table, int x, int y)
Definition: cuddLinear.c:1349
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:384
FILE * err
Definition: cuddInt.h:424
DdSubtable * subtables
Definition: cuddInt.h:349
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode sentinel
Definition: cuddInt.h:328
unsigned int keys
Definition: cuddInt.h:353
unsigned int dead
Definition: cuddInt.h:316
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:273
DdNode ** nodelist
Definition: cuddInt.h:311
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:138
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:520
int cuddNextHigh(DdManager *table, int x)
Definition: cuddReorder.c:715
DdHalfWord index
Definition: cudd.h:271
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:188
int shift
Definition: cuddInt.h:312
#define cuddSatInc(x)
Definition: cuddInt.h:831

◆ cuddLocalCacheClearAll()

void cuddLocalCacheClearAll ( DdManager manager)

Function********************************************************************

Synopsis [Clears the local caches of a manager.]

Description [Clears the local caches of a manager. Used before reordering.]

SideEffects [None]

SeeAlso []

Definition at line 423 of file cuddLCache.c.

425 {
426  DdLocalCache *cache = manager->localCaches;
427 
428  while (cache != NULL) {
429  memset(cache->item, 0, cache->slots * cache->itemsize);
430  cache = cache->next;
431  }
432  return;
433 
434 } /* end of cuddLocalCacheClearAll */
DdLocalCacheItem * item
Definition: cuddInt.h:266
struct DdLocalCache * next
Definition: cuddInt.h:276
char * memset()
unsigned int itemsize
Definition: cuddInt.h:267
unsigned int slots
Definition: cuddInt.h:269
DdLocalCache * localCaches
Definition: cuddInt.h:417

◆ cuddLocalCacheClearDead()

void cuddLocalCacheClearDead ( DdManager manager)

Function********************************************************************

Synopsis [Clears the dead entries of the local caches of a manager.]

Description [Clears the dead entries of the local caches of a manager. Used during garbage collection.]

SideEffects [None]

SeeAlso []

Definition at line 371 of file cuddLCache.c.

373 {
374  DdLocalCache *cache = manager->localCaches;
375  unsigned int keysize;
376  unsigned int itemsize;
377  unsigned int slots;
378  DdLocalCacheItem *item;
379  DdNodePtr *key;
380  unsigned int i, j;
381 
382  while (cache != NULL) {
383  keysize = cache->keysize;
384  itemsize = cache->itemsize;
385  slots = cache->slots;
386  item = cache->item;
387  for (i = 0; i < slots; i++) {
388  if (item->value != NULL) {
389  if (Cudd_Regular(item->value)->ref == 0) {
390  item->value = NULL;
391  } else {
392  key = item->key;
393  for (j = 0; j < keysize; j++) {
394  if (Cudd_Regular(key[j])->ref == 0) {
395  item->value = NULL;
396  break;
397  }
398  }
399  }
400  }
401  item = (DdLocalCacheItem *) ((char *) item + itemsize);
402  }
403  cache = cache->next;
404  }
405  return;
406 
407 } /* end of cuddLocalCacheClearDead */
Definition: cudd.h:270
#define Cudd_Regular(node)
Definition: cudd.h:384
DdNode * value
Definition: cuddInt.h:257
unsigned int keysize
Definition: cuddInt.h:268
DdLocalCacheItem * item
Definition: cuddInt.h:266
struct DdLocalCache * next
Definition: cuddInt.h:276
unsigned int itemsize
Definition: cuddInt.h:267
unsigned int slots
Definition: cuddInt.h:269
DdLocalCache * localCaches
Definition: cuddInt.h:417
DdNode * key[1]
Definition: cuddInt.h:261

◆ cuddLocalCacheInit()

DdLocalCache* cuddLocalCacheInit ( DdManager manager,
unsigned int  keySize,
unsigned int  cacheSize,
unsigned int  maxCacheSize 
)

AutomaticEnd Function********************************************************************

Synopsis [Initializes a local computed table.]

Description [Initializes a computed table. Returns a pointer the the new local cache in case of success; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddInitCache]

Definition at line 202 of file cuddLCache.c.

207 {
208  DdLocalCache *cache;
209  int logSize;
210 
211  cache = ALLOC(DdLocalCache,1);
212  if (cache == NULL) {
213  manager->errorCode = CUDD_MEMORY_OUT;
214  return(NULL);
215  }
216  cache->manager = manager;
217  cache->keysize = keySize;
218  cache->itemsize = (keySize + 1) * sizeof(DdNode *);
219 #ifdef DD_CACHE_PROFILE
220  cache->itemsize += sizeof(ptrint);
221 #endif
222  logSize = cuddComputeFloorLog2(ddMax(cacheSize,manager->slots/2));
223  cacheSize = 1 << logSize;
224  cache->item = (DdLocalCacheItem *)
225  ALLOC(char, cacheSize * cache->itemsize);
226  if (cache->item == NULL) {
227  manager->errorCode = CUDD_MEMORY_OUT;
228  FREE(cache);
229  return(NULL);
230  }
231  cache->slots = cacheSize;
232  cache->shift = sizeof(int) * 8 - logSize;
233  cache->maxslots = ddMin(maxCacheSize,manager->slots);
234  cache->minHit = manager->minHit;
235  /* Initialize to avoid division by 0 and immediate resizing. */
236  cache->lookUps = (double) (int) (cacheSize * cache->minHit + 1);
237  cache->hits = 0;
238  manager->memused += cacheSize * cache->itemsize + sizeof(DdLocalCache);
239 
240  /* Initialize the cache. */
241  memset(cache->item, 0, cacheSize * cache->itemsize);
242 
243  /* Add to manager's list of local caches for GC. */
245 
246  return(cache);
247 
248 } /* end of cuddLocalCacheInit */
int ptrint
Definition: cuddInt.h:249
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
unsigned int slots
Definition: cuddInt.h:352
double minHit
Definition: cuddInt.h:272
unsigned int keysize
Definition: cuddInt.h:268
DdLocalCacheItem * item
Definition: cuddInt.h:266
unsigned int maxslots
Definition: cuddInt.h:274
char * memset()
unsigned int itemsize
Definition: cuddInt.h:267
#define ALLOC(type, num)
Definition: util.h:76
double hits
Definition: cuddInt.h:273
double lookUps
Definition: cuddInt.h:271
unsigned int slots
Definition: cuddInt.h:269
#define ddMax(x, y)
Definition: cuddInt.h:785
#define ddMin(x, y)
Definition: cuddInt.h:771
unsigned long memused
Definition: cuddInt.h:429
double minHit
Definition: cuddInt.h:341
struct DdLocalCache DdLocalCache
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1036
DdManager * manager
Definition: cuddInt.h:275
static void cuddLocalCacheAddToList(DdLocalCache *cache)
Definition: cuddLCache.c:1342
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddLocalCacheInsert()

void cuddLocalCacheInsert ( DdLocalCache cache,
DdNodePtr key,
DdNode value 
)

Function********************************************************************

Synopsis [Inserts a result in a local cache.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 291 of file cuddLCache.c.

295 {
296  unsigned int posn;
298 
299  posn = ddLCHash(key,cache->keysize,cache->shift);
300  entry = (DdLocalCacheItem *) ((char *) cache->item +
301  posn * cache->itemsize);
302  memcpy(entry->key,key,cache->keysize * sizeof(DdNode *));
303  entry->value = value;
304 #ifdef DD_CACHE_PROFILE
305  entry->count++;
306 #endif
307 
308 } /* end of cuddLocalCacheInsert */
Definition: cudd.h:270
char * memcpy()
DdNode * value
Definition: cuddInt.h:257
unsigned int keysize
Definition: cuddInt.h:268
DdLocalCacheItem * item
Definition: cuddInt.h:266
static int * entry
Definition: cuddGroup.c:119
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddLCache.c:1313
unsigned int itemsize
Definition: cuddInt.h:267
DdNode * key[1]
Definition: cuddInt.h:261

◆ cuddLocalCacheLookup()

DdNode* cuddLocalCacheLookup ( DdLocalCache cache,
DdNodePtr key 
)

Function********************************************************************

Synopsis [Looks up in a local cache.]

Description [Looks up in a local cache. Returns the result if found; it returns NULL if no result is found.]

SideEffects [None]

SeeAlso []

Definition at line 324 of file cuddLCache.c.

327 {
328  unsigned int posn;
330  DdNode *value;
331 
332  cache->lookUps++;
333  posn = ddLCHash(key,cache->keysize,cache->shift);
334  entry = (DdLocalCacheItem *) ((char *) cache->item +
335  posn * cache->itemsize);
336  if (entry->value != NULL &&
337  memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) {
338  cache->hits++;
339  value = Cudd_Regular(entry->value);
340  if (value->ref == 0) {
341  cuddReclaim(cache->manager,value);
342  }
343  return(entry->value);
344  }
345 
346  /* Cache miss: decide whether to resize */
347 
348  if (cache->slots < cache->maxslots &&
349  cache->hits > cache->lookUps * cache->minHit) {
350  cuddLocalCacheResize(cache);
351  }
352 
353  return(NULL);
354 
355 } /* end of cuddLocalCacheLookup */
DdHalfWord ref
Definition: cudd.h:272
Definition: cudd.h:270
#define Cudd_Regular(node)
Definition: cudd.h:384
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddRef.c:580
DdNode * value
Definition: cuddInt.h:257
double minHit
Definition: cuddInt.h:272
unsigned int keysize
Definition: cuddInt.h:268
DdLocalCacheItem * item
Definition: cuddInt.h:266
static int * entry
Definition: cuddGroup.c:119
unsigned int maxslots
Definition: cuddInt.h:274
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddLCache.c:1313
unsigned int itemsize
Definition: cuddInt.h:267
double hits
Definition: cuddInt.h:273
double lookUps
Definition: cuddInt.h:271
unsigned int slots
Definition: cuddInt.h:269
static void cuddLocalCacheResize(DdLocalCache *cache)
Definition: cuddLCache.c:1231
int memcmp()
DdNode * key[1]
Definition: cuddInt.h:261
DdManager * manager
Definition: cuddInt.h:275

◆ cuddLocalCacheQuit()

void cuddLocalCacheQuit ( DdLocalCache cache)

Function********************************************************************

Synopsis [Shuts down a local computed table.]

Description [Initializes the computed table. It is called by Cudd_Init. Returns a pointer the the new local cache in case of success; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddLocalCacheInit]

Definition at line 265 of file cuddLCache.c.

267 {
268  cache->manager->memused -=
269  cache->slots * cache->itemsize + sizeof(DdLocalCache);
271  FREE(cache->item);
272  FREE(cache);
273 
274  return;
275 
276 } /* end of cuddLocalCacheQuit */
static void cuddLocalCacheRemoveFromList(DdLocalCache *cache)
Definition: cuddLCache.c:1366
#define FREE(obj)
Definition: util.h:80
DdLocalCacheItem * item
Definition: cuddInt.h:266
unsigned int itemsize
Definition: cuddInt.h:267
unsigned int slots
Definition: cuddInt.h:269
unsigned long memused
Definition: cuddInt.h:429
struct DdLocalCache DdLocalCache
DdManager * manager
Definition: cuddInt.h:275

◆ cuddMakeBddFromZddCover()

DdNode* cuddMakeBddFromZddCover ( DdManager dd,
DdNode node 
)

Function********************************************************************

Synopsis [Converts a ZDD cover to a BDD.]

Description [Converts a ZDD cover to a BDD. If successful, it returns a BDD node, otherwise it returns NULL. It is a recursive algorithm that works as follows. First it computes 3 cofactors of a ZDD cover: f1, f0 and fd. Second, it compute BDDs (b1, b0 and bd) of f1, f0 and fd. Third, it computes T=b1+bd and E=b0+bd. Fourth, it computes ITE(v,T,E) where v is the variable which has the index of the top node of the ZDD cover. In this case, since the index of v can be larger than either the one of T or the one of E, cuddUniqueInterIVO is called, where IVO stands for independent from variable ordering.]

SideEffects []

SeeAlso [Cudd_MakeBddFromZddCover]

Definition at line 797 of file cuddZddIsop.c.

800 {
801  DdNode *neW;
802  int v;
803  DdNode *f1, *f0, *fd;
804  DdNode *b1, *b0, *bd;
805  DdNode *T, *E;
806 
807  statLine(dd);
808  if (node == dd->one)
809  return(dd->one);
810  if (node == dd->zero)
811  return(Cudd_Not(dd->one));
812 
813  /* Check cache */
814  neW = cuddCacheLookup1(dd, cuddMakeBddFromZddCover, node);
815  if (neW)
816  return(neW);
817 
818  v = Cudd_Regular(node)->index; /* either yi or zi */
819  if (cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd)) return(NULL);
820  Cudd_Ref(f1);
821  Cudd_Ref(f0);
822  Cudd_Ref(fd);
823 
824  b1 = cuddMakeBddFromZddCover(dd, f1);
825  if (!b1) {
826  Cudd_RecursiveDerefZdd(dd, f1);
827  Cudd_RecursiveDerefZdd(dd, f0);
828  Cudd_RecursiveDerefZdd(dd, fd);
829  return(NULL);
830  }
831  Cudd_Ref(b1);
832  b0 = cuddMakeBddFromZddCover(dd, f0);
833  if (!b0) {
834  Cudd_RecursiveDerefZdd(dd, f1);
835  Cudd_RecursiveDerefZdd(dd, f0);
836  Cudd_RecursiveDerefZdd(dd, fd);
837  Cudd_RecursiveDeref(dd, b1);
838  return(NULL);
839  }
840  Cudd_Ref(b0);
841  Cudd_RecursiveDerefZdd(dd, f1);
842  Cudd_RecursiveDerefZdd(dd, f0);
843  if (fd != dd->zero) {
844  bd = cuddMakeBddFromZddCover(dd, fd);
845  if (!bd) {
846  Cudd_RecursiveDerefZdd(dd, fd);
847  Cudd_RecursiveDeref(dd, b1);
848  Cudd_RecursiveDeref(dd, b0);
849  return(NULL);
850  }
851  Cudd_Ref(bd);
852  Cudd_RecursiveDerefZdd(dd, fd);
853 
854  T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd));
855  if (!T) {
856  Cudd_RecursiveDeref(dd, b1);
857  Cudd_RecursiveDeref(dd, b0);
858  Cudd_RecursiveDeref(dd, bd);
859  return(NULL);
860  }
861  T = Cudd_NotCond(T, T != NULL);
862  Cudd_Ref(T);
863  Cudd_RecursiveDeref(dd, b1);
864  E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd));
865  if (!E) {
866  Cudd_RecursiveDeref(dd, b0);
867  Cudd_RecursiveDeref(dd, bd);
868  Cudd_RecursiveDeref(dd, T);
869  return(NULL);
870  }
871  E = Cudd_NotCond(E, E != NULL);
872  Cudd_Ref(E);
873  Cudd_RecursiveDeref(dd, b0);
874  Cudd_RecursiveDeref(dd, bd);
875  }
876  else {
877  Cudd_RecursiveDerefZdd(dd, fd);
878  T = b1;
879  E = b0;
880  }
881 
882  if (Cudd_IsComplement(T)) {
883  neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E));
884  if (!neW) {
885  Cudd_RecursiveDeref(dd, T);
886  Cudd_RecursiveDeref(dd, E);
887  return(NULL);
888  }
889  neW = Cudd_Not(neW);
890  }
891  else {
892  neW = cuddUniqueInterIVO(dd, v / 2, T, E);
893  if (!neW) {
894  Cudd_RecursiveDeref(dd, T);
895  Cudd_RecursiveDeref(dd, E);
896  return(NULL);
897  }
898  }
899  Cudd_Ref(neW);
900  Cudd_RecursiveDeref(dd, T);
901  Cudd_RecursiveDeref(dd, E);
902 
904  Cudd_Deref(neW);
905  return(neW);
906 
907 } /* end of cuddMakeBddFromZddCover */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
DdNode * cuddCacheLookup1(DdManager *table, DdNode *(*)(DdManager *, DdNode *), DdNode *f)
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
DdNode * zero
Definition: cuddInt.h:330
#define Cudd_Regular(node)
Definition: cudd.h:384
void cuddCacheInsert1(DdManager *table, DdNode *(*)(DdManager *, DdNode *), DdNode *f, DdNode *data)
DdNode * cuddMakeBddFromZddCover(DdManager *dd, DdNode *node)
Definition: cuddZddIsop.c:797
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode * cuddUniqueInterIVO(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1333
int cuddZddGetCofactors3(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
DdNode * one
Definition: cuddInt.h:329
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125

◆ cuddNextHigh()

int cuddNextHigh ( DdManager table,
int  x 
)

Function********************************************************************

Synopsis [Finds the next subtable with a larger index.]

Description [Finds the next subtable with a larger index. Returns the index.]

SideEffects [None]

SeeAlso [cuddNextLow]

Definition at line 715 of file cuddReorder.c.

718 {
719  return(x+1);
720 
721 } /* end of cuddNextHigh */

◆ cuddNextLow()

int cuddNextLow ( DdManager table,
int  x 
)

Function********************************************************************

Synopsis [Finds the next subtable with a smaller index.]

Description [Finds the next subtable with a smaller index. Returns the index.]

SideEffects [None]

SeeAlso [cuddNextHigh]

Definition at line 737 of file cuddReorder.c.

740 {
741  return(x-1);
742 
743 } /* end of cuddNextLow */

◆ cuddNodeArray()

DdNodePtr* cuddNodeArray ( DdNode f,
int *  n 
)

Function********************************************************************

Synopsis [Recursively collects all the nodes of a DD in an array.]

Description [Traverses the DD f and collects all its nodes in an array. The caller should free the array returned by cuddNodeArray. Returns a pointer to the array of nodes in case of success; NULL otherwise. The nodes are collected in reverse topological order, so that a node is always preceded in the array by all its descendants.]

SideEffects [The number of nodes is returned as a side effect.]

SeeAlso [Cudd_FirstNode]

Definition at line 2987 of file cuddUtil.c.

2990 {
2991  DdNodePtr *table;
2992  int size, retval;
2993 
2994  size = ddDagInt(Cudd_Regular(f));
2995  table = ALLOC(DdNodePtr, size);
2996  if (table == NULL) {
2998  return(NULL);
2999  }
3000 
3001  retval = cuddNodeArrayRecur(f, table, 0);
3002  assert(retval == size);
3003 
3004  *n = size;
3005  return(table);
3006 
3007 } /* cuddNodeArray */
Definition: cudd.h:270
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:384
#define ALLOC(type, num)
Definition: util.h:76
static int ddDagInt(DdNode *n)
Definition: cuddUtil.c:3173
static void ddClearFlag(DdNode *f)
Definition: cuddUtil.c:3741
static int cuddNodeArrayRecur(DdNode *f, DdNodePtr *table, int index)
Definition: cuddUtil.c:3208

◆ cuddP()

int cuddP ( DdManager dd,
DdNode f 
)

Function********************************************************************

Synopsis [Prints a DD to the standard output. One line per node is printed.]

Description [Prints a DD to the standard output. One line per node is printed. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_PrintDebug]

Definition at line 2874 of file cuddUtil.c.

2877 {
2878  int retval;
2880 
2881  if (table == NULL) return(0);
2882 
2883  retval = dp2(dd,f,table);
2884  st_free_table(table);
2885  (void) fputc('\n',dd->out);
2886  return(retval);
2887 
2888 } /* end of cuddP */
Definition: st.h:60
void st_free_table(st_table *)
Definition: st.c:252
static int dp2(DdManager *dd, DdNode *f, st_table *t)
Definition: cuddUtil.c:3026
FILE * out
Definition: cuddInt.h:423
int st_ptrcmp(const char *, const char *)
Definition: st.c:849
st_table * st_init_table(ST_PFICPCP, ST_PFICPI)
Definition: st.c:163
int st_ptrhash(char *, int)
Definition: st.c:811

◆ cuddPrintNode()

void cuddPrintNode ( DdNode f,
FILE *  fp 
)

Function********************************************************************

Synopsis [Prints out information on a node.]

Description [Prints out information on a node.]

SideEffects [None]

SeeAlso []

Definition at line 712 of file cuddCheck.c.

715 {
716  f = Cudd_Regular(f);
717 #if SIZEOF_VOID_P == 8
718  (void) fprintf(fp," node 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f));
719 #else
720  (void) fprintf(fp," node 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f));
721 #endif
722 
723 } /* end of cuddPrintNode */
DdHalfWord ref
Definition: cudd.h:272
#define Cudd_Regular(node)
Definition: cudd.h:384
#define cuddT(node)
Definition: cuddInt.h:609
unsigned int ptruint
Definition: cuddInt.h:250
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625

◆ cuddPrintVarGroups()

void cuddPrintVarGroups ( DdManager dd,
MtrNode root,
int  zdd,
int  silent 
)

Function********************************************************************

Synopsis [Prints the variable groups as a parenthesized list.]

Description [Prints the variable groups as a parenthesized list. For each group the level range that it represents is printed. After each group, the group's flags are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a character is printed.

  • F: MTR_FIXED
  • N: MTR_NEWNODE
  • S: MTR_SOFT

The second argument, silent, if different from 0, causes Cudd_PrintVarGroups to only check the syntax of the group tree.]

SideEffects [None]

SeeAlso []

Definition at line 749 of file cuddCheck.c.

754 {
755  MtrNode *node;
756  int level;
757 
758  assert(root != NULL);
759  assert(root->younger == NULL || root->younger->elder == root);
760  assert(root->elder == NULL || root->elder->younger == root);
761  if (zdd) {
762  level = dd->permZ[root->index];
763  } else {
764  level = dd->perm[root->index];
765  }
766  if (!silent) (void) printf("(%d",level);
767  if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) {
768  if (!silent) (void) printf(",");
769  } else {
770  node = root->child;
771  while (node != NULL) {
772  assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size));
773  assert(node->parent == root);
774  cuddPrintVarGroups(dd,node,zdd,silent);
775  node = node->younger;
776  }
777  }
778  if (!silent) {
779  (void) printf("%d", (int) (level + root->size - 1));
780  if (root->flags != MTR_DEFAULT) {
781  (void) printf("|");
782  if (MTR_TEST(root,MTR_FIXED)) (void) printf("F");
783  if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N");
784  if (MTR_TEST(root,MTR_SOFT)) (void) printf("S");
785  }
786  (void) printf(")");
787  if (root->parent == NULL) (void) printf("\n");
788  }
789  assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0);
790  return;
791 
792 } /* end of cuddPrintVarGroups */
#define MTR_TERMINAL
Definition: mtr.h:95
MtrHalfWord flags
Definition: mtr.h:127
void cuddPrintVarGroups(DdManager *dd, MtrNode *root, int zdd, int silent)
Definition: cuddCheck.c:749
MtrHalfWord size
Definition: mtr.h:129
#define assert(ex)
Definition: util.h:141
#define MTR_FIXED
Definition: mtr.h:97
int * permZ
Definition: cuddInt.h:370
struct MtrNode * parent
Definition: mtr.h:131
#define MTR_DEFAULT
Definition: mtr.h:94
struct MtrNode * elder
Definition: mtr.h:133
#define MTR_TEST(node, flag)
Definition: mtr.h:150
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord index
Definition: mtr.h:130
#define MTR_NEWNODE
Definition: mtr.h:98
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
struct MtrNode * child
Definition: mtr.h:132
int * perm
Definition: cuddInt.h:369
#define MTR_SOFT
Definition: mtr.h:96

◆ cuddReclaim()

void cuddReclaim ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Brings children of a dead node back.]

Description []

SideEffects [None]

SeeAlso [cuddReclaimZdd]

Definition at line 580 of file cuddRef.c.

583 {
584  DdNode *N;
585  int ord;
586  DdNodePtr *stack = table->stack;
587  int SP = 1;
588  double initialDead = table->dead;
589 
590  N = Cudd_Regular(n);
591 
592 #ifdef DD_DEBUG
593  assert(N->ref == 0);
594 #endif
595 
596  do {
597  if (N->ref == 0) {
598  N->ref = 1;
599  table->dead--;
600  if (cuddIsConstant(N)) {
601  table->constants.dead--;
602  N = stack[--SP];
603  } else {
604  ord = table->perm[N->index];
605  stack[SP++] = Cudd_Regular(cuddE(N));
606  table->subtables[ord].dead--;
607  N = cuddT(N);
608  }
609  } else {
610  cuddSatInc(N->ref);
611  N = stack[--SP];
612  }
613  } while (SP != 0);
614 
615  N = Cudd_Regular(n);
616  cuddSatDec(N->ref);
617  table->reclaimed += initialDead - table->dead;
618 
619 } /* end of cuddReclaim */
DdHalfWord ref
Definition: cudd.h:272
Definition: cudd.h:270
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:384
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode ** stack
Definition: cuddInt.h:364
unsigned int dead
Definition: cuddInt.h:355
unsigned int dead
Definition: cuddInt.h:316
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdSubtable constants
Definition: cuddInt.h:351
int * perm
Definition: cuddInt.h:369
#define cuddSatInc(x)
Definition: cuddInt.h:831
double reclaimed
Definition: cuddInt.h:367

◆ cuddReclaimZdd()

void cuddReclaimZdd ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Brings children of a dead ZDD node back.]

Description []

SideEffects [None]

SeeAlso [cuddReclaim]

Definition at line 634 of file cuddRef.c.

637 {
638  DdNode *N;
639  int ord;
640  DdNodePtr *stack = table->stack;
641  int SP = 1;
642 
643  N = n;
644 
645 #ifdef DD_DEBUG
646  assert(N->ref == 0);
647 #endif
648 
649  do {
650  cuddSatInc(N->ref);
651 
652  if (N->ref == 1) {
653  table->deadZ--;
654  table->reclaimed++;
655 #ifdef DD_DEBUG
656  assert(!cuddIsConstant(N));
657 #endif
658  ord = table->permZ[N->index];
659  stack[SP++] = cuddE(N);
660  table->subtableZ[ord].dead--;
661  N = cuddT(N);
662  } else {
663  N = stack[--SP];
664  }
665  } while (SP != 0);
666 
667  cuddSatDec(n->ref);
668 
669 } /* end of cuddReclaimZdd */
DdHalfWord ref
Definition: cudd.h:272
Definition: cudd.h:270
unsigned int deadZ
Definition: cuddInt.h:356
#define assert(ex)
Definition: util.h:141
int * permZ
Definition: cuddInt.h:370
DdNode ** stack
Definition: cuddInt.h:364
unsigned int dead
Definition: cuddInt.h:316
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
#define cuddSatInc(x)
Definition: cuddInt.h:831
double reclaimed
Definition: cuddInt.h:367
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddRehash()

void cuddRehash ( DdManager unique,
int  i 
)

Function********************************************************************

Synopsis [Rehashes a unique subtable.]

Description [Doubles the size of a unique subtable and rehashes its contents.]

SideEffects [None]

SeeAlso []

Definition at line 1559 of file cuddTable.c.

1562 {
1563  unsigned int slots, oldslots;
1564  int shift, oldshift;
1565  int j, pos;
1566  DdNodePtr *nodelist, *oldnodelist;
1567  DdNode *node, *next;
1568  DdNode *sentinel = &(unique->sentinel);
1569  hack split;
1570  extern DD_OOMFP MMoutOfMemory;
1571  DD_OOMFP saveHandler;
1572 
1573  if (unique->gcFrac == DD_GC_FRAC_HI && unique->slots > unique->looseUpTo) {
1574  unique->gcFrac = DD_GC_FRAC_LO;
1575  unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots);
1576 #ifdef DD_VERBOSE
1577  (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_LO);
1578  (void) fprintf(unique->err,"minDead = %d\n", unique->minDead);
1579 #endif
1580  }
1581 
1582  if (unique->gcFrac != DD_GC_FRAC_MIN && unique->memused > unique->maxmem) {
1583  unique->gcFrac = DD_GC_FRAC_MIN;
1584  unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots);
1585 #ifdef DD_VERBOSE
1586  (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_MIN);
1587  (void) fprintf(unique->err,"minDead = %d\n", unique->minDead);
1588 #endif
1589  cuddShrinkDeathRow(unique);
1590  if (cuddGarbageCollect(unique,1) > 0) return;
1591  }
1592 
1593  if (i != CUDD_CONST_INDEX) {
1594  oldslots = unique->subtables[i].slots;
1595  oldshift = unique->subtables[i].shift;
1596  oldnodelist = unique->subtables[i].nodelist;
1597 
1598  /* Compute the new size of the subtable. */
1599  slots = oldslots << 1;
1600  shift = oldshift - 1;
1601 
1602  saveHandler = MMoutOfMemory;
1603  MMoutOfMemory = Cudd_OutOfMem;
1604  nodelist = ALLOC(DdNodePtr, slots);
1605  MMoutOfMemory = saveHandler;
1606  if (nodelist == NULL) {
1607  (void) fprintf(unique->err,
1608  "Unable to resize subtable %d for lack of memory\n",
1609  i);
1610  /* Prevent frequent resizing attempts. */
1611  (void) cuddGarbageCollect(unique,1);
1612  if (unique->stash != NULL) {
1613  FREE(unique->stash);
1614  unique->stash = NULL;
1615  /* Inhibit resizing of tables. */
1616  cuddSlowTableGrowth(unique);
1617  }
1618  return;
1619  }
1620  unique->subtables[i].nodelist = nodelist;
1621  unique->subtables[i].slots = slots;
1622  unique->subtables[i].shift = shift;
1623  unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
1624 
1625  /* Move the nodes from the old table to the new table.
1626  ** This code depends on the type of hash function.
1627  ** It assumes that the effect of doubling the size of the table
1628  ** is to retain one more bit of the 32-bit hash value.
1629  ** The additional bit is the LSB. */
1630  for (j = 0; (unsigned) j < oldslots; j++) {
1631  DdNodePtr *evenP, *oddP;
1632  node = oldnodelist[j];
1633  evenP = &(nodelist[j<<1]);
1634  oddP = &(nodelist[(j<<1)+1]);
1635  while (node != sentinel) {
1636  next = node->next;
1637  pos = ddHash(cuddT(node), cuddE(node), shift);
1638  if (pos & 1) {
1639  *oddP = node;
1640  oddP = &(node->next);
1641  } else {
1642  *evenP = node;
1643  evenP = &(node->next);
1644  }
1645  node = next;
1646  }
1647  *evenP = *oddP = sentinel;
1648  }
1649  FREE(oldnodelist);
1650 
1651 #ifdef DD_VERBOSE
1652  (void) fprintf(unique->err,
1653  "rehashing layer %d: keys %d dead %d new size %d\n",
1654  i, unique->subtables[i].keys,
1655  unique->subtables[i].dead, slots);
1656 #endif
1657  } else {
1658  oldslots = unique->constants.slots;
1659  oldshift = unique->constants.shift;
1660  oldnodelist = unique->constants.nodelist;
1661 
1662  /* The constant subtable is never subjected to reordering.
1663  ** Therefore, when it is resized, it is because it has just
1664  ** reached the maximum load. We can safely just double the size,
1665  ** with no need for the loop we use for the other tables.
1666  */
1667  slots = oldslots << 1;
1668  shift = oldshift - 1;
1669  saveHandler = MMoutOfMemory;
1670  MMoutOfMemory = Cudd_OutOfMem;
1671  nodelist = ALLOC(DdNodePtr, slots);
1672  MMoutOfMemory = saveHandler;
1673  if (nodelist == NULL) {
1674  (void) fprintf(unique->err,
1675  "Unable to resize constant subtable for lack of memory\n");
1676  (void) cuddGarbageCollect(unique,1);
1677  for (j = 0; j < unique->size; j++) {
1678  unique->subtables[j].maxKeys <<= 1;
1679  }
1680  unique->constants.maxKeys <<= 1;
1681  return;
1682  }
1683  unique->constants.slots = slots;
1684  unique->constants.shift = shift;
1685  unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
1686  unique->constants.nodelist = nodelist;
1687  for (j = 0; (unsigned) j < slots; j++) {
1688  nodelist[j] = NULL;
1689  }
1690  for (j = 0; (unsigned) j < oldslots; j++) {
1691  node = oldnodelist[j];
1692  while (node != NULL) {
1693  next = node->next;
1694  split.value = cuddV(node);
1695  pos = ddHash(split.bits[0], split.bits[1], shift);
1696  node->next = nodelist[pos];
1697  nodelist[pos] = node;
1698  node = next;
1699  }
1700  }
1701  FREE(oldnodelist);
1702 
1703 #ifdef DD_VERBOSE
1704  (void) fprintf(unique->err,
1705  "rehashing constants: keys %d dead %d new size %d\n",
1706  unique->constants.keys,unique->constants.dead,slots);
1707 #endif
1708  }
1709 
1710  /* Update global data */
1711 
1712  unique->memused += (slots - oldslots) * sizeof(DdNodePtr);
1713  unique->slots += (slots - oldslots);
1714  ddFixLimits(unique);
1715 
1716 } /* end of cuddRehash */
unsigned int keys
Definition: cuddInt.h:314
#define ddHash(f, g, s)
Definition: cuddInt.h:696
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2845
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
unsigned int bits[2]
Definition: cuddTable.c:109
int size
Definition: cuddInt.h:345
double gcFrac
Definition: cuddInt.h:359
unsigned int slots
Definition: cuddInt.h:352
FILE * err
Definition: cuddInt.h:424
DdSubtable * subtables
Definition: cuddInt.h:349
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
void(* DD_OOMFP)(long)
Definition: cudd.h:311
#define cuddV(node)
Definition: cuddInt.h:641
#define DD_GC_FRAC_HI
Definition: cuddInt.h:135
DdNode sentinel
Definition: cuddInt.h:328
char * stash
Definition: cuddInt.h:382
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:762
#define ALLOC(type, num)
Definition: util.h:76
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:273
#define DD_GC_FRAC_LO
Definition: cuddInt.h:134
unsigned int maxKeys
Definition: cuddInt.h:315
#define CUDD_CONST_INDEX
Definition: cudd.h:113
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
CUDD_VALUE_TYPE value
Definition: cuddTable.c:108
void(* MMoutOfMemory)(long)
Definition: safe_mem.c:32
#define DD_GC_FRAC_MIN
Definition: cuddInt.h:136
void cuddSlowTableGrowth(DdManager *unique)
Definition: cuddTable.c:2414
unsigned long memused
Definition: cuddInt.h:429
unsigned int looseUpTo
Definition: cuddInt.h:361
unsigned int slots
Definition: cuddInt.h:313
#define cuddE(node)
Definition: cuddInt.h:625
static DD_INLINE void ddFixLimits(DdManager *unique)
Definition: cuddTable.c:2843
DdSubtable constants
Definition: cuddInt.h:351
unsigned long maxmem
Definition: cuddInt.h:430
int shift
Definition: cuddInt.h:312
void cuddShrinkDeathRow(DdManager *table)
Definition: cuddRef.c:684
unsigned int minDead
Definition: cuddInt.h:358

◆ cuddRemapUnderApprox()

DdNode* cuddRemapUnderApprox ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
double  quality 
)

◆ cuddResizeLinear()

int cuddResizeLinear ( DdManager table)

Function********************************************************************

Synopsis [Resizes the linear transform matrix.]

Description [Resizes the linear transform matrix. Returns 1 if successful; 0 otherwise.]

SideEffects [none]

SeeAlso []

Definition at line 800 of file cuddLinear.c.

802 {
803  int words,oldWords;
804  int wordsPerRow,oldWordsPerRow;
805  int nvars,oldNvars;
806  int word,oldWord;
807  int bit;
808  int i,j;
809  long *linear,*oldLinear;
810 
811  oldNvars = table->linearSize;
812  oldWordsPerRow = ((oldNvars - 1) >> LOGBPL) + 1;
813  oldWords = oldWordsPerRow * oldNvars;
814  oldLinear = table->linear;
815 
816  nvars = table->size;
817  wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
818  words = wordsPerRow * nvars;
819  table->linear = linear = ALLOC(long,words);
820  if (linear == NULL) {
821  table->errorCode = CUDD_MEMORY_OUT;
822  return(0);
823  }
824  table->memused += (words - oldWords) * sizeof(long);
825  for (i = 0; i < words; i++) linear[i] = 0;
826 
827  /* Copy old matrix. */
828  for (i = 0; i < oldNvars; i++) {
829  for (j = 0; j < oldWordsPerRow; j++) {
830  oldWord = oldWordsPerRow * i + j;
831  word = wordsPerRow * i + j;
832  linear[word] = oldLinear[oldWord];
833  }
834  }
835  FREE(oldLinear);
836 
837  /* Add elements to the diagonal. */
838  for (i = oldNvars; i < nvars; i++) {
839  word = wordsPerRow * i + (i >> LOGBPL);
840  bit = i & (BPL-1);
841  linear[word] = 1 << bit;
842  }
843  table->linearSize = nvars;
844 
845  return(1);
846 
847 } /* end of cuddResizeLinear */
#define FREE(obj)
Definition: util.h:80
#define BPL
Definition: cuddLinear.c:78
int size
Definition: cuddInt.h:345
#define LOGBPL
Definition: cuddLinear.c:79
#define ALLOC(type, num)
Definition: util.h:76
long * linear
Definition: cuddInt.h:378
int linearSize
Definition: cuddInt.h:376
unsigned long memused
Definition: cuddInt.h:429
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddResizeTableZdd()

int cuddResizeTableZdd ( DdManager unique,
int  index 
)

Function********************************************************************

Synopsis [Increases the number of ZDD subtables in a unique table so that it meets or exceeds index.]

Description [Increases the number of ZDD subtables in a unique table so that it meets or exceeds index. When new ZDD variables are created, it is possible to preserve the functions unchanged, or it is possible to preserve the covers unchanged, but not both. cuddResizeTableZdd preserves the covers. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [ddResizeTable]

Definition at line 2270 of file cuddTable.c.

2273 {
2274  DdSubtable *newsubtables;
2275  DdNodePtr *newnodelist;
2276  int oldsize,newsize;
2277  int i,j,reorderSave;
2278  unsigned int numSlots = unique->initSlots;
2279  int *newperm, *newinvperm;
2280 
2281  oldsize = unique->sizeZ;
2282  /* Easy case: there is still room in the current table. */
2283  if (index < unique->maxSizeZ) {
2284  for (i = oldsize; i <= index; i++) {
2285  unique->subtableZ[i].slots = numSlots;
2286  unique->subtableZ[i].shift = sizeof(int) * 8 -
2287  cuddComputeFloorLog2(numSlots);
2288  unique->subtableZ[i].keys = 0;
2289  unique->subtableZ[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY;
2290  unique->subtableZ[i].dead = 0;
2291  unique->permZ[i] = i;
2292  unique->invpermZ[i] = i;
2293  newnodelist = unique->subtableZ[i].nodelist =
2294  ALLOC(DdNodePtr, numSlots);
2295  if (newnodelist == NULL) {
2296  unique->errorCode = CUDD_MEMORY_OUT;
2297  return(0);
2298  }
2299  for (j = 0; (unsigned) j < numSlots; j++) {
2300  newnodelist[j] = NULL;
2301  }
2302  }
2303  } else {
2304  /* The current table is too small: we need to allocate a new,
2305  ** larger one; move all old subtables, and initialize the new
2306  ** subtables up to index included.
2307  */
2308  newsize = index + DD_DEFAULT_RESIZE;
2309 #ifdef DD_VERBOSE
2310  (void) fprintf(unique->err,
2311  "Increasing the ZDD table size from %d to %d\n",
2312  unique->maxSizeZ, newsize);
2313 #endif
2314  newsubtables = ALLOC(DdSubtable,newsize);
2315  if (newsubtables == NULL) {
2316  unique->errorCode = CUDD_MEMORY_OUT;
2317  return(0);
2318  }
2319  newperm = ALLOC(int,newsize);
2320  if (newperm == NULL) {
2321  unique->errorCode = CUDD_MEMORY_OUT;
2322  return(0);
2323  }
2324  newinvperm = ALLOC(int,newsize);
2325  if (newinvperm == NULL) {
2326  unique->errorCode = CUDD_MEMORY_OUT;
2327  return(0);
2328  }
2329  unique->memused += (newsize - unique->maxSizeZ) * ((numSlots+1) *
2330  sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable));
2331  if (newsize > unique->maxSize) {
2332  FREE(unique->stack);
2333  unique->stack = ALLOC(DdNodePtr,newsize + 1);
2334  if (unique->stack == NULL) {
2335  unique->errorCode = CUDD_MEMORY_OUT;
2336  return(0);
2337  }
2338  unique->stack[0] = NULL; /* to suppress harmless UMR */
2339  unique->memused +=
2340  (newsize - ddMax(unique->maxSize,unique->maxSizeZ))
2341  * sizeof(DdNode *);
2342  }
2343  for (i = 0; i < oldsize; i++) {
2344  newsubtables[i].slots = unique->subtableZ[i].slots;
2345  newsubtables[i].shift = unique->subtableZ[i].shift;
2346  newsubtables[i].keys = unique->subtableZ[i].keys;
2347  newsubtables[i].maxKeys = unique->subtableZ[i].maxKeys;
2348  newsubtables[i].dead = unique->subtableZ[i].dead;
2349  newsubtables[i].nodelist = unique->subtableZ[i].nodelist;
2350  newperm[i] = unique->permZ[i];
2351  newinvperm[i] = unique->invpermZ[i];
2352  }
2353  for (i = oldsize; i <= index; i++) {
2354  newsubtables[i].slots = numSlots;
2355  newsubtables[i].shift = sizeof(int) * 8 -
2356  cuddComputeFloorLog2(numSlots);
2357  newsubtables[i].keys = 0;
2358  newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY;
2359  newsubtables[i].dead = 0;
2360  newperm[i] = i;
2361  newinvperm[i] = i;
2362  newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots);
2363  if (newnodelist == NULL) {
2364  unique->errorCode = CUDD_MEMORY_OUT;
2365  return(0);
2366  }
2367  for (j = 0; (unsigned) j < numSlots; j++) {
2368  newnodelist[j] = NULL;
2369  }
2370  }
2371  FREE(unique->subtableZ);
2372  unique->subtableZ = newsubtables;
2373  unique->maxSizeZ = newsize;
2374  FREE(unique->permZ);
2375  unique->permZ = newperm;
2376  FREE(unique->invpermZ);
2377  unique->invpermZ = newinvperm;
2378  }
2379  unique->slots += (index + 1 - unique->sizeZ) * numSlots;
2380  ddFixLimits(unique);
2381  unique->sizeZ = index + 1;
2382 
2383  /* Now that the table is in a coherent state, update the ZDD
2384  ** universe. We need to temporarily disable reordering,
2385  ** because we cannot reorder without universe in place.
2386  */
2387 
2388  reorderSave = unique->autoDynZ;
2389  unique->autoDynZ = 0;
2390  cuddZddFreeUniv(unique);
2391  if (!cuddZddInitUniv(unique)) {
2392  unique->autoDynZ = reorderSave;
2393  return(0);
2394  }
2395  unique->autoDynZ = reorderSave;
2396 
2397  return(1);
2398 
2399 } /* end of cuddResizeTableZdd */
unsigned int keys
Definition: cuddInt.h:314
void cuddZddFreeUniv(DdManager *zdd)
Definition: cuddInit.c:294
int maxSizeZ
Definition: cuddInt.h:348
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
int * invpermZ
Definition: cuddInt.h:372
unsigned int slots
Definition: cuddInt.h:352
FILE * err
Definition: cuddInt.h:424
int * permZ
Definition: cuddInt.h:370
struct DdSubtable DdSubtable
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
DdNode ** stack
Definition: cuddInt.h:364
unsigned int initSlots
Definition: cuddInt.h:363
#define ALLOC(type, num)
Definition: util.h:76
unsigned int dead
Definition: cuddInt.h:316
int maxSize
Definition: cuddInt.h:347
unsigned int maxKeys
Definition: cuddInt.h:315
#define ddMax(x, y)
Definition: cuddInt.h:785
DdNode ** nodelist
Definition: cuddInt.h:311
int cuddZddInitUniv(DdManager *zdd)
Definition: cuddInit.c:245
unsigned long memused
Definition: cuddInt.h:429
#define DD_DEFAULT_RESIZE
Definition: cuddInt.h:103
int sizeZ
Definition: cuddInt.h:346
unsigned int slots
Definition: cuddInt.h:313
int autoDynZ
Definition: cuddInt.h:401
static DD_INLINE void ddFixLimits(DdManager *unique)
Definition: cuddTable.c:2843
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1036
int shift
Definition: cuddInt.h:312
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddSetInteract()

void cuddSetInteract ( DdManager table,
int  x,
int  y 
)

AutomaticEnd Function********************************************************************

Synopsis [Set interaction matrix entries.]

Description [Given a pair of variables 0 <= x < y < table->size, sets the corresponding bit of the interaction matrix to 1.]

SideEffects [None]

SeeAlso []

Definition at line 153 of file cuddInteract.c.

157 {
158  int posn, word, bit;
159 
160 #ifdef DD_DEBUG
161  assert(x < y);
162  assert(y < table->size);
163  assert(x >= 0);
164 #endif
165 
166  posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1;
167  word = posn >> LOGBPL;
168  bit = posn & (BPL-1);
169  table->interact[word] |= 1L << bit;
170 
171 } /* end of cuddSetInteract */
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
long * interact
Definition: cuddInt.h:377
#define BPL
Definition: cuddInteract.c:89
#define LOGBPL
Definition: cuddInteract.c:90

◆ cuddShrinkDeathRow()

void cuddShrinkDeathRow ( DdManager table)

Function********************************************************************

Synopsis [Shrinks the death row.]

Description [Shrinks the death row by a factor of four.]

SideEffects [None]

SeeAlso [cuddClearDeathRow]

Definition at line 684 of file cuddRef.c.

686 {
687 #ifndef DD_NO_DEATH_ROW
688  int i;
689 
690  if (table->deathRowDepth > 3) {
691  for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) {
692  if (table->deathRow[i] == NULL) break;
693  Cudd_IterDerefBdd(table,table->deathRow[i]);
694  table->deathRow[i] = NULL;
695  }
696  table->deathRowDepth /= 4;
697  table->deadMask = table->deathRowDepth - 1;
698  if ((unsigned) table->nextDead > table->deadMask) {
699  table->nextDead = 0;
700  }
701  table->deathRow = REALLOC(DdNodePtr, table->deathRow,
702  table->deathRowDepth);
703  }
704 #endif
705 
706 } /* end of cuddShrinkDeathRow */
Definition: cudd.h:270
unsigned deadMask
Definition: cuddInt.h:387
DdNode ** deathRow
Definition: cuddInt.h:384
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
int nextDead
Definition: cuddInt.h:386
int deathRowDepth
Definition: cuddInt.h:385
#define REALLOC(type, obj, num)
Definition: util.h:78

◆ cuddShrinkSubtable()

void cuddShrinkSubtable ( DdManager unique,
int  i 
)

Function********************************************************************

Synopsis [Shrinks a subtable.]

Description [Shrinks a subtable.]

SideEffects [None]

SeeAlso [cuddRehash]

Definition at line 1731 of file cuddTable.c.

1734 {
1735  int j;
1736  int shift, posn;
1737  DdNodePtr *nodelist, *oldnodelist;
1738  DdNode *node, *next;
1739  DdNode *sentinel = &(unique->sentinel);
1740  unsigned int slots, oldslots;
1741  extern DD_OOMFP MMoutOfMemory;
1742  DD_OOMFP saveHandler;
1743 
1744  oldnodelist = unique->subtables[i].nodelist;
1745  oldslots = unique->subtables[i].slots;
1746  slots = oldslots >> 1;
1747  saveHandler = MMoutOfMemory;
1748  MMoutOfMemory = Cudd_OutOfMem;
1749  nodelist = ALLOC(DdNodePtr, slots);
1750  MMoutOfMemory = saveHandler;
1751  if (nodelist == NULL) {
1752  return;
1753  }
1754  unique->subtables[i].nodelist = nodelist;
1755  unique->subtables[i].slots = slots;
1756  unique->subtables[i].shift++;
1757  unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
1758 #ifdef DD_VERBOSE
1759  (void) fprintf(unique->err,
1760  "shrunk layer %d (%d keys) from %d to %d slots\n",
1761  i, unique->subtables[i].keys, oldslots, slots);
1762 #endif
1763 
1764  for (j = 0; (unsigned) j < slots; j++) {
1765  nodelist[j] = sentinel;
1766  }
1767  shift = unique->subtables[i].shift;
1768  for (j = 0; (unsigned) j < oldslots; j++) {
1769  node = oldnodelist[j];
1770  while (node != sentinel) {
1771  DdNode *looking, *T, *E;
1772  DdNodePtr *previousP;
1773  next = node->next;
1774  posn = ddHash(cuddT(node), cuddE(node), shift);
1775  previousP = &(nodelist[posn]);
1776  looking = *previousP;
1777  T = cuddT(node);
1778  E = cuddE(node);
1779  while (T < cuddT(looking)) {
1780  previousP = &(looking->next);
1781  looking = *previousP;
1782 #ifdef DD_UNIQUE_PROFILE
1783  unique->uniqueLinks++;
1784 #endif
1785  }
1786  while (T == cuddT(looking) && E < cuddE(looking)) {
1787  previousP = &(looking->next);
1788  looking = *previousP;
1789 #ifdef DD_UNIQUE_PROFILE
1790  unique->uniqueLinks++;
1791 #endif
1792  }
1793  node->next = *previousP;
1794  *previousP = node;
1795  node = next;
1796  }
1797  }
1798  FREE(oldnodelist);
1799 
1800  unique->memused += ((long) slots - (long) oldslots) * sizeof(DdNode *);
1801  unique->slots += slots - oldslots;
1802  unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots);
1803  unique->cacheSlack = (int)
1805  - 2 * (int) unique->cacheSlots;
1806 
1807 } /* end of cuddShrinkSubtable */
unsigned int keys
Definition: cuddInt.h:314
#define ddHash(f, g, s)
Definition: cuddInt.h:696
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2845
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
double gcFrac
Definition: cuddInt.h:359
unsigned int maxCacheHard
Definition: cuddInt.h:343
unsigned int slots
Definition: cuddInt.h:352
FILE * err
Definition: cuddInt.h:424
DdSubtable * subtables
Definition: cuddInt.h:349
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
void(* DD_OOMFP)(long)
Definition: cudd.h:311
unsigned int cacheSlots
Definition: cuddInt.h:337
DdNode sentinel
Definition: cuddInt.h:328
#define ALLOC(type, num)
Definition: util.h:76
DdNode * next
Definition: cudd.h:273
unsigned int maxKeys
Definition: cuddInt.h:315
DdNode ** nodelist
Definition: cuddInt.h:311
#define ddMin(x, y)
Definition: cuddInt.h:771
#define DD_MAX_CACHE_TO_SLOTS_RATIO
Definition: cuddInt.h:145
int cacheSlack
Definition: cuddInt.h:342
#define cuddT(node)
Definition: cuddInt.h:609
void(* MMoutOfMemory)(long)
Definition: safe_mem.c:32
unsigned long memused
Definition: cuddInt.h:429
unsigned int slots
Definition: cuddInt.h:313
#define cuddE(node)
Definition: cuddInt.h:625
int shift
Definition: cuddInt.h:312
unsigned int minDead
Definition: cuddInt.h:358

◆ cuddSifting()

int cuddSifting ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [Implementation of Rudell's sifting algorithm.]

Description [Implementation of Rudell's sifting algorithm. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique table.
  2. Sift the variable up and down, remembering each time the total size of the DD heap.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 502 of file cuddReorder.c.

506 {
507  int i;
508  int *var;
509  int size;
510  int x;
511  int result;
512 #ifdef DD_STATS
513  int previousSize;
514 #endif
515 
516  size = table->size;
517 
518  /* Find order in which to sift variables. */
519  var = NULL;
520  entry = ALLOC(int,size);
521  if (entry == NULL) {
522  table->errorCode = CUDD_MEMORY_OUT;
523  goto cuddSiftingOutOfMem;
524  }
525  var = ALLOC(int,size);
526  if (var == NULL) {
527  table->errorCode = CUDD_MEMORY_OUT;
528  goto cuddSiftingOutOfMem;
529  }
530 
531  for (i = 0; i < size; i++) {
532  x = table->perm[i];
533  entry[i] = table->subtables[x].keys;
534  var[i] = i;
535  }
536 
537  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddUniqueCompare);
538 
539  /* Now sift. */
540  for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
541  if (ddTotalNumberSwapping >= table->siftMaxSwap)
542  break;
543  if (util_cpu_time() - table->startTime + table->reordTime
544  > table->timeLimit) {
545  table->autoDyn = 0; /* prevent further reordering */
546  break;
547  }
548  x = table->perm[var[i]];
549 
550  if (x < lower || x > upper || table->subtables[x].bindVar == 1)
551  continue;
552 #ifdef DD_STATS
553  previousSize = table->keys - table->isolated;
554 #endif
555  result = ddSiftingAux(table, x, lower, upper);
556  if (!result) goto cuddSiftingOutOfMem;
557 #ifdef DD_STATS
558  if (table->keys < (unsigned) previousSize + table->isolated) {
559  (void) fprintf(table->out,"-");
560  } else if (table->keys > (unsigned) previousSize + table->isolated) {
561  (void) fprintf(table->out,"+"); /* should never happen */
562  (void) fprintf(table->err,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]);
563  } else {
564  (void) fprintf(table->out,"=");
565  }
566  fflush(table->out);
567 #endif
568  }
569 
570  FREE(var);
571  FREE(entry);
572 
573  return(1);
574 
575 cuddSiftingOutOfMem:
576 
577  if (entry != NULL) FREE(entry);
578  if (var != NULL) FREE(var);
579 
580  return(0);
581 
582 } /* end of cuddSifting */
static int * entry
Definition: cuddReorder.c:101
unsigned int keys
Definition: cuddInt.h:314
unsigned long reordTime
Definition: cuddInt.h:434
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:313
unsigned long startTime
Definition: cuddInt.h:426
int size
Definition: cuddInt.h:345
FILE * err
Definition: cuddInt.h:424
static int ddSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddReorder.c:1487
int bindVar
Definition: cuddInt.h:318
DdSubtable * subtables
Definition: cuddInt.h:349
int ddTotalNumberSwapping
Definition: cuddReorder.c:103
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static int ddUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddReorder.c:1322
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: cpu_time.c:34
int siftMaxVar
Definition: cuddInt.h:395
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368
int autoDyn
Definition: cuddInt.h:400
int * perm
Definition: cuddInt.h:369
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddSlowTableGrowth()

void cuddSlowTableGrowth ( DdManager unique)

Function********************************************************************

Synopsis [Adjusts parameters of a table to slow down its growth.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 2414 of file cuddTable.c.

2416 {
2417  int i;
2418 
2419  unique->maxCacheHard = unique->cacheSlots - 1;
2420  unique->cacheSlack = - (int) (unique->cacheSlots + 1);
2421  for (i = 0; i < unique->size; i++) {
2422  unique->subtables[i].maxKeys <<= 2;
2423  }
2424  unique->gcFrac = DD_GC_FRAC_MIN;
2425  unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots);
2426  cuddShrinkDeathRow(unique);
2427  (void) fprintf(unique->err,"Slowing down table growth: ");
2428  (void) fprintf(unique->err,"GC fraction = %.2f\t", unique->gcFrac);
2429  (void) fprintf(unique->err,"minDead = %u\n", unique->minDead);
2430 
2431 } /* end of cuddSlowTableGrowth */
int size
Definition: cuddInt.h:345
double gcFrac
Definition: cuddInt.h:359
unsigned int maxCacheHard
Definition: cuddInt.h:343
unsigned int slots
Definition: cuddInt.h:352
FILE * err
Definition: cuddInt.h:424
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int cacheSlots
Definition: cuddInt.h:337
unsigned int maxKeys
Definition: cuddInt.h:315
int cacheSlack
Definition: cuddInt.h:342
#define DD_GC_FRAC_MIN
Definition: cuddInt.h:136
void cuddShrinkDeathRow(DdManager *table)
Definition: cuddRef.c:684
unsigned int minDead
Definition: cuddInt.h:358

◆ cuddSolveEqnRecur()

DdNode* cuddSolveEqnRecur ( DdManager bdd,
DdNode F,
DdNode Y,
DdNode **  G,
int  n,
int *  yIndex,
int  i 
)

◆ cuddSplitSetRecur()

DdNode* cuddSplitSetRecur ( DdManager manager,
st_table mtable,
int *  varSeen,
DdNode p,
double  n,
double  max,
int  index 
)

◆ cuddStCountfree()

enum st_retval cuddStCountfree ( char *  key,
char *  value,
char *  arg 
)

Function********************************************************************

Synopsis [Frees the memory used to store the minterm counts recorded in the visited table.]

Description [Frees the memory used to store the minterm counts recorded in the visited table. Returns ST_CONTINUE.]

SideEffects [None]

Definition at line 2903 of file cuddUtil.c.

2907 {
2908  double *d;
2909 
2910  d = (double *)value;
2911  FREE(d);
2912  return(ST_CONTINUE);
2913 
2914 } /* end of cuddStCountfree */
#define FREE(obj)
Definition: util.h:80
Definition: st.h:78

◆ cuddSubsetHeavyBranch()

DdNode* cuddSubsetHeavyBranch ( DdManager dd,
DdNode f,
int  numVars,
int  threshold 
)

◆ cuddSubsetShortPaths()

DdNode* cuddSubsetShortPaths ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
int  hardlimit 
)

◆ cuddSwapInPlace()

int cuddSwapInPlace ( DdManager table,
int  x,
int  y 
)

Function********************************************************************

Synopsis [Swaps two adjacent variables.]

Description [Swaps two adjacent variables. It assumes that no dead nodes are present on entry to this procedure. The procedure then guarantees that no dead nodes will be present when it terminates. cuddSwapInPlace assumes that x < y. Returns the number of keys in the table if successful; 0 otherwise.]

SideEffects [None]

Definition at line 760 of file cuddReorder.c.

764 {
765  DdNodePtr *xlist, *ylist;
766  int xindex, yindex;
767  int xslots, yslots;
768  int xshift, yshift;
769  int oldxkeys, oldykeys;
770  int newxkeys, newykeys;
771  int comple, newcomplement;
772  int i;
773  Cudd_VariableType varType;
774  Cudd_LazyGroupType groupType;
775  int posn;
776  int isolated;
777  DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0;
778  DdNode *g,*next;
779  DdNodePtr *previousP;
780  DdNode *tmp;
781  DdNode *sentinel = &(table->sentinel);
782  extern DD_OOMFP MMoutOfMemory;
783  DD_OOMFP saveHandler;
784 
785 #ifdef DD_DEBUG
786  int count,idcheck;
787 #endif
788 
789 #ifdef DD_DEBUG
790  assert(x < y);
791  assert(cuddNextHigh(table,x) == y);
792  assert(table->subtables[x].keys != 0);
793  assert(table->subtables[y].keys != 0);
794  assert(table->subtables[x].dead == 0);
795  assert(table->subtables[y].dead == 0);
796 #endif
797 
799 
800  /* Get parameters of x subtable. */
801  xindex = table->invperm[x];
802  xlist = table->subtables[x].nodelist;
803  oldxkeys = table->subtables[x].keys;
804  xslots = table->subtables[x].slots;
805  xshift = table->subtables[x].shift;
806 
807  /* Get parameters of y subtable. */
808  yindex = table->invperm[y];
809  ylist = table->subtables[y].nodelist;
810  oldykeys = table->subtables[y].keys;
811  yslots = table->subtables[y].slots;
812  yshift = table->subtables[y].shift;
813 
814  if (!cuddTestInteract(table,xindex,yindex)) {
815 #ifdef DD_STATS
816  ddTotalNISwaps++;
817 #endif
818  newxkeys = oldxkeys;
819  newykeys = oldykeys;
820  } else {
821  newxkeys = 0;
822  newykeys = oldykeys;
823 
824  /* Check whether the two projection functions involved in this
825  ** swap are isolated. At the end, we'll be able to tell how many
826  ** isolated projection functions are there by checking only these
827  ** two functions again. This is done to eliminate the isolated
828  ** projection functions from the node count.
829  */
830  isolated = - ((table->vars[xindex]->ref == 1) +
831  (table->vars[yindex]->ref == 1));
832 
833  /* The nodes in the x layer that do not depend on
834  ** y will stay there; the others are put in a chain.
835  ** The chain is handled as a LIFO; g points to the beginning.
836  */
837  g = NULL;
838  if ((oldxkeys >= xslots || (unsigned) xslots == table->initSlots) &&
839  oldxkeys <= DD_MAX_SUBTABLE_DENSITY * xslots) {
840  for (i = 0; i < xslots; i++) {
841  previousP = &(xlist[i]);
842  f = *previousP;
843  while (f != sentinel) {
844  next = f->next;
845  f1 = cuddT(f); f0 = cuddE(f);
846  if (f1->index != (DdHalfWord) yindex &&
847  Cudd_Regular(f0)->index != (DdHalfWord) yindex) {
848  /* stays */
849  newxkeys++;
850  *previousP = f;
851  previousP = &(f->next);
852  } else {
853  f->index = yindex;
854  f->next = g;
855  g = f;
856  }
857  f = next;
858  } /* while there are elements in the collision chain */
859  *previousP = sentinel;
860  } /* for each slot of the x subtable */
861  } else { /* resize xlist */
862  DdNode *h = NULL;
863  DdNodePtr *newxlist;
864  unsigned int newxslots;
865  int newxshift;
866  /* Empty current xlist. Nodes that stay go to list h;
867  ** nodes that move go to list g. */
868  for (i = 0; i < xslots; i++) {
869  f = xlist[i];
870  while (f != sentinel) {
871  next = f->next;
872  f1 = cuddT(f); f0 = cuddE(f);
873  if (f1->index != (DdHalfWord) yindex &&
874  Cudd_Regular(f0)->index != (DdHalfWord) yindex) {
875  /* stays */
876  f->next = h;
877  h = f;
878  newxkeys++;
879  } else {
880  f->index = yindex;
881  f->next = g;
882  g = f;
883  }
884  f = next;
885  } /* while there are elements in the collision chain */
886  } /* for each slot of the x subtable */
887  /* Decide size of new subtable. */
888  newxshift = xshift;
889  newxslots = xslots;
890  while ((unsigned) oldxkeys > DD_MAX_SUBTABLE_DENSITY * newxslots) {
891  newxshift--;
892  newxslots <<= 1;
893  }
894  while ((unsigned) oldxkeys < newxslots &&
895  newxslots > table->initSlots) {
896  newxshift++;
897  newxslots >>= 1;
898  }
899  /* Try to allocate new table. Be ready to back off. */
900  saveHandler = MMoutOfMemory;
901  MMoutOfMemory = Cudd_OutOfMem;
902  newxlist = ALLOC(DdNodePtr, newxslots);
903  MMoutOfMemory = saveHandler;
904  if (newxlist == NULL) {
905  (void) fprintf(table->err, "Unable to resize subtable %d for lack of memory\n", i);
906  newxlist = xlist;
907  newxslots = xslots;
908  newxshift = xshift;
909  } else {
910  table->slots += ((int) newxslots - xslots);
911  table->minDead = (unsigned)
912  (table->gcFrac * (double) table->slots);
913  table->cacheSlack = (int)
915  * table->slots) - 2 * (int) table->cacheSlots;
916  table->memused +=
917  ((int) newxslots - xslots) * sizeof(DdNodePtr);
918  FREE(xlist);
919  xslots = newxslots;
920  xshift = newxshift;
921  xlist = newxlist;
922  }
923  /* Initialize new subtable. */
924  for (i = 0; i < xslots; i++) {
925  xlist[i] = sentinel;
926  }
927  /* Move nodes that were parked in list h to their new home. */
928  f = h;
929  while (f != NULL) {
930  next = f->next;
931  f1 = cuddT(f);
932  f0 = cuddE(f);
933  /* Check xlist for pair (f11,f01). */
934  posn = ddHash(f1, f0, xshift);
935  /* For each element tmp in collision list xlist[posn]. */
936  previousP = &(xlist[posn]);
937  tmp = *previousP;
938  while (f1 < cuddT(tmp)) {
939  previousP = &(tmp->next);
940  tmp = *previousP;
941  }
942  while (f1 == cuddT(tmp) && f0 < cuddE(tmp)) {
943  previousP = &(tmp->next);
944  tmp = *previousP;
945  }
946  f->next = *previousP;
947  *previousP = f;
948  f = next;
949  }
950  }
951 
952 #ifdef DD_COUNT
953  table->swapSteps += oldxkeys - newxkeys;
954 #endif
955  /* Take care of the x nodes that must be re-expressed.
956  ** They form a linked list pointed by g. Their index has been
957  ** already changed to yindex.
958  */
959  f = g;
960  while (f != NULL) {
961  next = f->next;
962  /* Find f1, f0, f11, f10, f01, f00. */
963  f1 = cuddT(f);
964 #ifdef DD_DEBUG
965  assert(!(Cudd_IsComplement(f1)));
966 #endif
967  if ((int) f1->index == yindex) {
968  f11 = cuddT(f1); f10 = cuddE(f1);
969  } else {
970  f11 = f10 = f1;
971  }
972 #ifdef DD_DEBUG
973  assert(!(Cudd_IsComplement(f11)));
974 #endif
975  f0 = cuddE(f);
976  comple = Cudd_IsComplement(f0);
977  f0 = Cudd_Regular(f0);
978  if ((int) f0->index == yindex) {
979  f01 = cuddT(f0); f00 = cuddE(f0);
980  } else {
981  f01 = f00 = f0;
982  }
983  if (comple) {
984  f01 = Cudd_Not(f01);
985  f00 = Cudd_Not(f00);
986  }
987  /* Decrease ref count of f1. */
988  cuddSatDec(f1->ref);
989  /* Create the new T child. */
990  if (f11 == f01) {
991  newf1 = f11;
992  cuddSatInc(newf1->ref);
993  } else {
994  /* Check xlist for triple (xindex,f11,f01). */
995  posn = ddHash(f11, f01, xshift);
996  /* For each element newf1 in collision list xlist[posn]. */
997  previousP = &(xlist[posn]);
998  newf1 = *previousP;
999  while (f11 < cuddT(newf1)) {
1000  previousP = &(newf1->next);
1001  newf1 = *previousP;
1002  }
1003  while (f11 == cuddT(newf1) && f01 < cuddE(newf1)) {
1004  previousP = &(newf1->next);
1005  newf1 = *previousP;
1006  }
1007  if (cuddT(newf1) == f11 && cuddE(newf1) == f01) {
1008  cuddSatInc(newf1->ref);
1009  } else { /* no match */
1010  newf1 = cuddDynamicAllocNode(table);
1011  if (newf1 == NULL)
1012  goto cuddSwapOutOfMem;
1013  newf1->index = xindex; newf1->ref = 1;
1014  cuddT(newf1) = f11;
1015  cuddE(newf1) = f01;
1016  /* Insert newf1 in the collision list xlist[posn];
1017  ** increase the ref counts of f11 and f01.
1018  */
1019  newxkeys++;
1020  newf1->next = *previousP;
1021  *previousP = newf1;
1022  cuddSatInc(f11->ref);
1023  tmp = Cudd_Regular(f01);
1024  cuddSatInc(tmp->ref);
1025  }
1026  }
1027  cuddT(f) = newf1;
1028 #ifdef DD_DEBUG
1029  assert(!(Cudd_IsComplement(newf1)));
1030 #endif
1031 
1032  /* Do the same for f0, keeping complement dots into account. */
1033  /* Decrease ref count of f0. */
1034  tmp = Cudd_Regular(f0);
1035  cuddSatDec(tmp->ref);
1036  /* Create the new E child. */
1037  if (f10 == f00) {
1038  newf0 = f00;
1039  tmp = Cudd_Regular(newf0);
1040  cuddSatInc(tmp->ref);
1041  } else {
1042  /* make sure f10 is regular */
1043  newcomplement = Cudd_IsComplement(f10);
1044  if (newcomplement) {
1045  f10 = Cudd_Not(f10);
1046  f00 = Cudd_Not(f00);
1047  }
1048  /* Check xlist for triple (xindex,f10,f00). */
1049  posn = ddHash(f10, f00, xshift);
1050  /* For each element newf0 in collision list xlist[posn]. */
1051  previousP = &(xlist[posn]);
1052  newf0 = *previousP;
1053  while (f10 < cuddT(newf0)) {
1054  previousP = &(newf0->next);
1055  newf0 = *previousP;
1056  }
1057  while (f10 == cuddT(newf0) && f00 < cuddE(newf0)) {
1058  previousP = &(newf0->next);
1059  newf0 = *previousP;
1060  }
1061  if (cuddT(newf0) == f10 && cuddE(newf0) == f00) {
1062  cuddSatInc(newf0->ref);
1063  } else { /* no match */
1064  newf0 = cuddDynamicAllocNode(table);
1065  if (newf0 == NULL)
1066  goto cuddSwapOutOfMem;
1067  newf0->index = xindex; newf0->ref = 1;
1068  cuddT(newf0) = f10;
1069  cuddE(newf0) = f00;
1070  /* Insert newf0 in the collision list xlist[posn];
1071  ** increase the ref counts of f10 and f00.
1072  */
1073  newxkeys++;
1074  newf0->next = *previousP;
1075  *previousP = newf0;
1076  cuddSatInc(f10->ref);
1077  tmp = Cudd_Regular(f00);
1078  cuddSatInc(tmp->ref);
1079  }
1080  if (newcomplement) {
1081  newf0 = Cudd_Not(newf0);
1082  }
1083  }
1084  cuddE(f) = newf0;
1085 
1086  /* Insert the modified f in ylist.
1087  ** The modified f does not already exists in ylist.
1088  ** (Because of the uniqueness of the cofactors.)
1089  */
1090  posn = ddHash(newf1, newf0, yshift);
1091  newykeys++;
1092  previousP = &(ylist[posn]);
1093  tmp = *previousP;
1094  while (newf1 < cuddT(tmp)) {
1095  previousP = &(tmp->next);
1096  tmp = *previousP;
1097  }
1098  while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) {
1099  previousP = &(tmp->next);
1100  tmp = *previousP;
1101  }
1102  f->next = *previousP;
1103  *previousP = f;
1104  f = next;
1105  } /* while f != NULL */
1106 
1107  /* GC the y layer. */
1108 
1109  /* For each node f in ylist. */
1110  for (i = 0; i < yslots; i++) {
1111  previousP = &(ylist[i]);
1112  f = *previousP;
1113  while (f != sentinel) {
1114  next = f->next;
1115  if (f->ref == 0) {
1116  tmp = cuddT(f);
1117  cuddSatDec(tmp->ref);
1118  tmp = Cudd_Regular(cuddE(f));
1119  cuddSatDec(tmp->ref);
1120  cuddDeallocNode(table,f);
1121  newykeys--;
1122  } else {
1123  *previousP = f;
1124  previousP = &(f->next);
1125  }
1126  f = next;
1127  } /* while f */
1128  *previousP = sentinel;
1129  } /* for i */
1130 
1131 #ifdef DD_DEBUG
1132 #if 0
1133  (void) fprintf(table->out,"Swapping %d and %d\n",x,y);
1134 #endif
1135  count = 0;
1136  idcheck = 0;
1137  for (i = 0; i < yslots; i++) {
1138  f = ylist[i];
1139  while (f != sentinel) {
1140  count++;
1141  if (f->index != (DdHalfWord) yindex)
1142  idcheck++;
1143  f = f->next;
1144  }
1145  }
1146  if (count != newykeys) {
1147  (void) fprintf(table->out,
1148  "Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",
1149  oldykeys,newykeys,count);
1150  }
1151  if (idcheck != 0)
1152  (void) fprintf(table->out,
1153  "Error in id's of ylist\twrong id's = %d\n",
1154  idcheck);
1155  count = 0;
1156  idcheck = 0;
1157  for (i = 0; i < xslots; i++) {
1158  f = xlist[i];
1159  while (f != sentinel) {
1160  count++;
1161  if (f->index != (DdHalfWord) xindex)
1162  idcheck++;
1163  f = f->next;
1164  }
1165  }
1166  if (count != newxkeys) {
1167  (void) fprintf(table->out,
1168  "Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",
1169  oldxkeys,newxkeys,count);
1170  }
1171  if (idcheck != 0)
1172  (void) fprintf(table->out,
1173  "Error in id's of xlist\twrong id's = %d\n",
1174  idcheck);
1175 #endif
1176 
1177  isolated += (table->vars[xindex]->ref == 1) +
1178  (table->vars[yindex]->ref == 1);
1179  table->isolated += isolated;
1180  }
1181 
1182  /* Set the appropriate fields in table. */
1183  table->subtables[x].nodelist = ylist;
1184  table->subtables[x].slots = yslots;
1185  table->subtables[x].shift = yshift;
1186  table->subtables[x].keys = newykeys;
1187  table->subtables[x].maxKeys = yslots * DD_MAX_SUBTABLE_DENSITY;
1188  i = table->subtables[x].bindVar;
1189  table->subtables[x].bindVar = table->subtables[y].bindVar;
1190  table->subtables[y].bindVar = i;
1191  /* Adjust filds for lazy sifting. */
1192  varType = table->subtables[x].varType;
1193  table->subtables[x].varType = table->subtables[y].varType;
1194  table->subtables[y].varType = varType;
1195  i = table->subtables[x].pairIndex;
1196  table->subtables[x].pairIndex = table->subtables[y].pairIndex;
1197  table->subtables[y].pairIndex = i;
1198  i = table->subtables[x].varHandled;
1199  table->subtables[x].varHandled = table->subtables[y].varHandled;
1200  table->subtables[y].varHandled = i;
1201  groupType = table->subtables[x].varToBeGrouped;
1202  table->subtables[x].varToBeGrouped = table->subtables[y].varToBeGrouped;
1203  table->subtables[y].varToBeGrouped = groupType;
1204 
1205  table->subtables[y].nodelist = xlist;
1206  table->subtables[y].slots = xslots;
1207  table->subtables[y].shift = xshift;
1208  table->subtables[y].keys = newxkeys;
1209  table->subtables[y].maxKeys = xslots * DD_MAX_SUBTABLE_DENSITY;
1210 
1211  table->perm[xindex] = y; table->perm[yindex] = x;
1212  table->invperm[x] = yindex; table->invperm[y] = xindex;
1213 
1214  table->keys += newxkeys + newykeys - oldxkeys - oldykeys;
1215 
1216  return(table->keys - table->isolated);
1217 
1218 cuddSwapOutOfMem:
1219  (void) fprintf(table->err,"Error: cuddSwapInPlace out of memory\n");
1220 
1221  return (0);
1222 
1223 } /* end of cuddSwapInPlace */
DdHalfWord ref
Definition: cudd.h:272
unsigned int keys
Definition: cuddInt.h:314
unsigned short DdHalfWord
Definition: cudd.h:259
#define ddHash(f, g, s)
Definition: cuddInt.h:696
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2845
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define FREE(obj)
Definition: util.h:80
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
#define assert(ex)
Definition: util.h:141
double gcFrac
Definition: cuddInt.h:359
unsigned int maxCacheHard
Definition: cuddInt.h:343
unsigned int slots
Definition: cuddInt.h:352
#define Cudd_Regular(node)
Definition: cudd.h:384
FILE * err
Definition: cuddInt.h:424
int bindVar
Definition: cuddInt.h:318
DdSubtable * subtables
Definition: cuddInt.h:349
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
void(* DD_OOMFP)(long)
Definition: cudd.h:311
Cudd_VariableType
Definition: cudd.h:249
int ddTotalNumberSwapping
Definition: cuddReorder.c:103
unsigned int initSlots
Definition: cuddInt.h:363
Cudd_VariableType varType
Definition: cuddInt.h:320
unsigned int cacheSlots
Definition: cuddInt.h:337
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode sentinel
Definition: cuddInt.h:328
unsigned int keys
Definition: cuddInt.h:353
int cuddNextHigh(DdManager *table, int x)
Definition: cuddReorder.c:715
#define ALLOC(type, num)
Definition: util.h:76
unsigned int dead
Definition: cuddInt.h:316
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:273
Cudd_LazyGroupType varToBeGrouped
Definition: cuddInt.h:323
unsigned int maxKeys
Definition: cuddInt.h:315
DdNode ** nodelist
Definition: cuddInt.h:311
#define ddMin(x, y)
Definition: cuddInt.h:771
#define DD_MAX_CACHE_TO_SLOTS_RATIO
Definition: cuddInt.h:145
int cacheSlack
Definition: cuddInt.h:342
#define cuddT(node)
Definition: cuddInt.h:609
void(* MMoutOfMemory)(long)
Definition: safe_mem.c:32
int varHandled
Definition: cuddInt.h:322
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:520
unsigned long memused
Definition: cuddInt.h:429
DdHalfWord index
Definition: cudd.h:271
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
int pairIndex
Definition: cuddInt.h:321
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:188
int shift
Definition: cuddInt.h:312
Cudd_LazyGroupType
Definition: cudd.h:234
int * perm
Definition: cuddInt.h:369
unsigned int minDead
Definition: cuddInt.h:358
#define cuddSatInc(x)
Definition: cuddInt.h:831

◆ cuddSwapping()

int cuddSwapping ( DdManager table,
int  lower,
int  upper,
Cudd_ReorderingType  heuristic 
)

Function********************************************************************

Synopsis [Reorders variables by a sequence of (non-adjacent) swaps.]

Description [Implementation of Plessier's algorithm that reorders variables by a sequence of (non-adjacent) swaps.

  1. Select two variables (RANDOM or HEURISTIC).
  2. Permute these variables.
  3. If the nodes have decreased accept the permutation.
  4. Otherwise reconstruct the original heap.
  5. Loop.

Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 604 of file cuddReorder.c.

609 {
610  int i, j;
611  int max, keys;
612  int nvars;
613  int x, y;
614  int iterate;
615  int previousSize;
616  Move *moves, *move;
617  int pivot;
618  int modulo;
619  int result;
620 
621 #ifdef DD_DEBUG
622  /* Sanity check */
623  assert(lower >= 0 && upper < table->size && lower <= upper);
624 #endif
625 
626  nvars = upper - lower + 1;
627  iterate = nvars;
628 
629  for (i = 0; i < iterate; i++) {
630  if (ddTotalNumberSwapping >= table->siftMaxSwap)
631  break;
632  if (heuristic == CUDD_REORDER_RANDOM_PIVOT) {
633  max = -1;
634  for (j = lower; j <= upper; j++) {
635  if ((keys = table->subtables[j].keys) > max) {
636  max = keys;
637  pivot = j;
638  }
639  }
640 
641  modulo = upper - pivot;
642  if (modulo == 0) {
643  y = pivot;
644  } else{
645  y = pivot + 1 + ((int) Cudd_Random() % modulo);
646  }
647 
648  modulo = pivot - lower - 1;
649  if (modulo < 1) {
650  x = lower;
651  } else{
652  do {
653  x = (int) Cudd_Random() % modulo;
654  } while (x == y);
655  }
656  } else {
657  x = ((int) Cudd_Random() % nvars) + lower;
658  do {
659  y = ((int) Cudd_Random() % nvars) + lower;
660  } while (x == y);
661  }
662  previousSize = table->keys - table->isolated;
663  moves = ddSwapAny(table,x,y);
664  if (moves == NULL) goto cuddSwappingOutOfMem;
665  result = ddSiftingBackward(table,previousSize,moves);
666  if (!result) goto cuddSwappingOutOfMem;
667  while (moves != NULL) {
668  move = moves->next;
669  cuddDeallocMove(table, moves);
670  moves = move;
671  }
672 #ifdef DD_STATS
673  if (table->keys < (unsigned) previousSize + table->isolated) {
674  (void) fprintf(table->out,"-");
675  } else if (table->keys > (unsigned) previousSize + table->isolated) {
676  (void) fprintf(table->out,"+"); /* should never happen */
677  } else {
678  (void) fprintf(table->out,"=");
679  }
680  fflush(table->out);
681 #endif
682 #if 0
683  (void) fprintf(table->out,"#:t_SWAPPING %8d: tmp size\n",
684  table->keys - table->isolated);
685 #endif
686  }
687 
688  return(1);
689 
690 cuddSwappingOutOfMem:
691  while (moves != NULL) {
692  move = moves->next;
693  cuddDeallocMove(table, moves);
694  moves = move;
695  }
696 
697  return(0);
698 
699 } /* end of cuddSwapping */
unsigned int keys
Definition: cuddInt.h:314
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
int siftMaxSwap
Definition: cuddInt.h:396
static Move * ddSwapAny(DdManager *table, int x, int y)
Definition: cuddReorder.c:1346
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdSubtable * subtables
Definition: cuddInt.h:349
int ddTotalNumberSwapping
Definition: cuddReorder.c:103
long Cudd_Random(void)
Definition: cuddUtil.c:2710
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
static int ddSiftingBackward(DdManager *table, int size, Move *moves)
Definition: cuddReorder.c:1786
struct Move * next
Definition: cuddInt.h:474
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368

◆ cuddSymmCheck()

int cuddSymmCheck ( DdManager table,
int  x,
int  y 
)

Function********************************************************************

Synopsis [Checks for symmetry of x and y.]

Description [Checks for symmetry of x and y. Ignores projection functions, unless they are isolated. Returns 1 in case of symmetry; 0 otherwise.]

SideEffects [None]

Definition at line 188 of file cuddSymmetry.c.

192 {
193  DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10;
194  int comple; /* f0 is complemented */
195  int xsymmy; /* x and y may be positively symmetric */
196  int xsymmyp; /* x and y may be negatively symmetric */
197  int arccount; /* number of arcs from layer x to layer y */
198  int TotalRefCount; /* total reference count of layer y minus 1 */
199  int yindex;
200  int i;
201  DdNodePtr *list;
202  int slots;
203  DdNode *sentinel = &(table->sentinel);
204 #ifdef DD_DEBUG
205  int xindex;
206 #endif
207 
208  /* Checks that x and y are not the projection functions.
209  ** For x it is sufficient to check whether there is only one
210  ** node; indeed, if there is one node, it is the projection function
211  ** and it cannot point to y. Hence, if y isn't just the projection
212  ** function, it has one arc coming from a layer different from x.
213  */
214  if (table->subtables[x].keys == 1) {
215  return(0);
216  }
217  yindex = table->invperm[y];
218  if (table->subtables[y].keys == 1) {
219  if (table->vars[yindex]->ref == 1)
220  return(0);
221  }
222 
223  xsymmy = xsymmyp = 1;
224  arccount = 0;
225  slots = table->subtables[x].slots;
226  list = table->subtables[x].nodelist;
227  for (i = 0; i < slots; i++) {
228  f = list[i];
229  while (f != sentinel) {
230  /* Find f1, f0, f11, f10, f01, f00. */
231  f1 = cuddT(f);
232  f0 = Cudd_Regular(cuddE(f));
233  comple = Cudd_IsComplement(cuddE(f));
234  if ((int) f1->index == yindex) {
235  arccount++;
236  f11 = cuddT(f1); f10 = cuddE(f1);
237  } else {
238  if ((int) f0->index != yindex) {
239  /* If f is an isolated projection function it is
240  ** allowed to bypass layer y.
241  */
242  if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1)
243  return(0); /* f bypasses layer y */
244  }
245  f11 = f10 = f1;
246  }
247  if ((int) f0->index == yindex) {
248  arccount++;
249  f01 = cuddT(f0); f00 = cuddE(f0);
250  } else {
251  f01 = f00 = f0;
252  }
253  if (comple) {
254  f01 = Cudd_Not(f01);
255  f00 = Cudd_Not(f00);
256  }
257 
258  if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) {
259  xsymmy &= f01 == f10;
260  xsymmyp &= f11 == f00;
261  if ((xsymmy == 0) && (xsymmyp == 0))
262  return(0);
263  }
264 
265  f = f->next;
266  } /* while */
267  } /* for */
268 
269  /* Calculate the total reference counts of y */
270  TotalRefCount = -1; /* -1 for projection function */
271  slots = table->subtables[y].slots;
272  list = table->subtables[y].nodelist;
273  for (i = 0; i < slots; i++) {
274  f = list[i];
275  while (f != sentinel) {
276  TotalRefCount += f->ref;
277  f = f->next;
278  }
279  }
280 
281 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
282  if (arccount == TotalRefCount) {
283  xindex = table->invperm[x];
284  (void) fprintf(table->out,
285  "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n",
286  xindex,yindex,x,y);
287  }
288 #endif
289 
290  return(arccount == TotalRefCount);
291 
292 } /* end of cuddSymmCheck */
DdHalfWord ref
Definition: cudd.h:272
unsigned int keys
Definition: cuddInt.h:314
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
#define Cudd_Regular(node)
Definition: cudd.h:384
DdSubtable * subtables
Definition: cuddInt.h:349
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode sentinel
Definition: cuddInt.h:328
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:273
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:271
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
int * invperm
Definition: cuddInt.h:371
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ cuddSymmSifting()

int cuddSymmSifting ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [Symmetric sifting algorithm.]

Description [Symmetric sifting algorithm. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique subtable.
  2. Sift the variable up and down, remembering each time the total size of the DD heap and grouping variables that are symmetric.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 plus the number of symmetric variables if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddSymmSiftingConv]

Definition at line 318 of file cuddSymmetry.c.

322 {
323  int i;
324  int *var;
325  int size;
326  int x;
327  int result;
328  int symvars;
329  int symgroups;
330 #ifdef DD_STATS
331  int previousSize;
332 #endif
333 
334  size = table->size;
335 
336  /* Find order in which to sift variables. */
337  var = NULL;
338  entry = ALLOC(int,size);
339  if (entry == NULL) {
340  table->errorCode = CUDD_MEMORY_OUT;
341  goto ddSymmSiftingOutOfMem;
342  }
343  var = ALLOC(int,size);
344  if (var == NULL) {
345  table->errorCode = CUDD_MEMORY_OUT;
346  goto ddSymmSiftingOutOfMem;
347  }
348 
349  for (i = 0; i < size; i++) {
350  x = table->perm[i];
351  entry[i] = table->subtables[x].keys;
352  var[i] = i;
353  }
354 
355  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare);
356 
357  /* Initialize the symmetry of each subtable to itself. */
358  for (i = lower; i <= upper; i++) {
359  table->subtables[i].next = i;
360  }
361 
362  for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
363  if (ddTotalNumberSwapping >= table->siftMaxSwap)
364  break;
365  if (util_cpu_time() - table->startTime > table->timeLimit) {
366  table->autoDyn = 0; /* prevent further reordering */
367  break;
368  }
369  x = table->perm[var[i]];
370 #ifdef DD_STATS
371  previousSize = table->keys - table->isolated;
372 #endif
373  if (x < lower || x > upper) continue;
374  if (table->subtables[x].next == (unsigned) x) {
375  result = ddSymmSiftingAux(table,x,lower,upper);
376  if (!result) goto ddSymmSiftingOutOfMem;
377 #ifdef DD_STATS
378  if (table->keys < (unsigned) previousSize + table->isolated) {
379  (void) fprintf(table->out,"-");
380  } else if (table->keys > (unsigned) previousSize +
381  table->isolated) {
382  (void) fprintf(table->out,"+"); /* should never happen */
383  } else {
384  (void) fprintf(table->out,"=");
385  }
386  fflush(table->out);
387 #endif
388  }
389  }
390 
391  FREE(var);
392  FREE(entry);
393 
394  ddSymmSummary(table, lower, upper, &symvars, &symgroups);
395 
396 #ifdef DD_STATS
397  (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n",
398  symvars);
399  (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups",
400  symgroups);
401 #endif
402 
403  return(1+symvars);
404 
405 ddSymmSiftingOutOfMem:
406 
407  if (entry != NULL) FREE(entry);
408  if (var != NULL) FREE(var);
409 
410  return(0);
411 
412 } /* end of cuddSymmSifting */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
static int * entry
Definition: cuddSymmetry.c:93
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:313
unsigned long startTime
Definition: cuddInt.h:426
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static void ddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: cpu_time.c:34
int siftMaxVar
Definition: cuddInt.h:395
int ddTotalNumberSwapping
Definition: cuddReorder.c:103
unsigned int next
Definition: cuddInt.h:317
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368
static int ddSymmUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddSymmetry.c:613
int autoDyn
Definition: cuddInt.h:400
int * perm
Definition: cuddInt.h:369
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
static int ddSymmSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddSymmetry.c:641

◆ cuddSymmSiftingConv()

int cuddSymmSiftingConv ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [Symmetric sifting to convergence algorithm.]

Description [Symmetric sifting to convergence algorithm. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique subtable.
  2. Sift the variable up and down, remembering each time the total size of the DD heap and grouping variables that are symmetric.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.
  5. Repeat 1-4 until no further improvement.

Returns 1 plus the number of symmetric variables if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddSymmSifting]

Definition at line 439 of file cuddSymmetry.c.

443 {
444  int i;
445  int *var;
446  int size;
447  int x;
448  int result;
449  int symvars;
450  int symgroups;
451  int classes;
452  int initialSize;
453 #ifdef DD_STATS
454  int previousSize;
455 #endif
456 
457  initialSize = table->keys - table->isolated;
458 
459  size = table->size;
460 
461  /* Find order in which to sift variables. */
462  var = NULL;
463  entry = ALLOC(int,size);
464  if (entry == NULL) {
465  table->errorCode = CUDD_MEMORY_OUT;
466  goto ddSymmSiftingConvOutOfMem;
467  }
468  var = ALLOC(int,size);
469  if (var == NULL) {
470  table->errorCode = CUDD_MEMORY_OUT;
471  goto ddSymmSiftingConvOutOfMem;
472  }
473 
474  for (i = 0; i < size; i++) {
475  x = table->perm[i];
476  entry[i] = table->subtables[x].keys;
477  var[i] = i;
478  }
479 
480  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare);
481 
482  /* Initialize the symmetry of each subtable to itself
483  ** for first pass of converging symmetric sifting.
484  */
485  for (i = lower; i <= upper; i++) {
486  table->subtables[i].next = i;
487  }
488 
489  for (i = 0; i < ddMin(table->siftMaxVar, table->size); i++) {
490  if (ddTotalNumberSwapping >= table->siftMaxSwap)
491  break;
492  if (util_cpu_time() - table->startTime > table->timeLimit) {
493  table->autoDyn = 0; /* prevent further reordering */
494  break;
495  }
496  x = table->perm[var[i]];
497  if (x < lower || x > upper) continue;
498  /* Only sift if not in symmetry group already. */
499  if (table->subtables[x].next == (unsigned) x) {
500 #ifdef DD_STATS
501  previousSize = table->keys - table->isolated;
502 #endif
503  result = ddSymmSiftingAux(table,x,lower,upper);
504  if (!result) goto ddSymmSiftingConvOutOfMem;
505 #ifdef DD_STATS
506  if (table->keys < (unsigned) previousSize + table->isolated) {
507  (void) fprintf(table->out,"-");
508  } else if (table->keys > (unsigned) previousSize +
509  table->isolated) {
510  (void) fprintf(table->out,"+");
511  } else {
512  (void) fprintf(table->out,"=");
513  }
514  fflush(table->out);
515 #endif
516  }
517  }
518 
519  /* Sifting now until convergence. */
520  while ((unsigned) initialSize > table->keys - table->isolated) {
521  initialSize = table->keys - table->isolated;
522 #ifdef DD_STATS
523  (void) fprintf(table->out,"\n");
524 #endif
525  /* Here we consider only one representative for each symmetry class. */
526  for (x = lower, classes = 0; x <= upper; x++, classes++) {
527  while ((unsigned) x < table->subtables[x].next) {
528  x = table->subtables[x].next;
529  }
530  /* Here x is the largest index in a group.
531  ** Groups consist of adjacent variables.
532  ** Hence, the next increment of x will move it to a new group.
533  */
534  i = table->invperm[x];
535  entry[i] = table->subtables[x].keys;
536  var[classes] = i;
537  }
538 
539  qsort((void *)var,classes,sizeof(int),(DD_QSFP)ddSymmUniqueCompare);
540 
541  /* Now sift. */
542  for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) {
543  if (ddTotalNumberSwapping >= table->siftMaxSwap)
544  break;
545  if (util_cpu_time() - table->startTime > table->timeLimit) {
546  table->autoDyn = 0; /* prevent further reordering */
547  break;
548  }
549  x = table->perm[var[i]];
550  if ((unsigned) x >= table->subtables[x].next) {
551 #ifdef DD_STATS
552  previousSize = table->keys - table->isolated;
553 #endif
554  result = ddSymmSiftingConvAux(table,x,lower,upper);
555  if (!result ) goto ddSymmSiftingConvOutOfMem;
556 #ifdef DD_STATS
557  if (table->keys < (unsigned) previousSize + table->isolated) {
558  (void) fprintf(table->out,"-");
559  } else if (table->keys > (unsigned) previousSize +
560  table->isolated) {
561  (void) fprintf(table->out,"+");
562  } else {
563  (void) fprintf(table->out,"=");
564  }
565  fflush(table->out);
566 #endif
567  }
568  } /* for */
569  }
570 
571  ddSymmSummary(table, lower, upper, &symvars, &symgroups);
572 
573 #ifdef DD_STATS
574  (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n",
575  symvars);
576  (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups",
577  symgroups);
578 #endif
579 
580  FREE(var);
581  FREE(entry);
582 
583  return(1+symvars);
584 
585 ddSymmSiftingConvOutOfMem:
586 
587  if (entry != NULL) FREE(entry);
588  if (var != NULL) FREE(var);
589 
590  return(0);
591 
592 } /* end of cuddSymmSiftingConv */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
static int * entry
Definition: cuddSymmetry.c:93
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:313
unsigned long startTime
Definition: cuddInt.h:426
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static void ddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: cpu_time.c:34
static int ddSymmSiftingConvAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddSymmetry.c:943
int siftMaxVar
Definition: cuddInt.h:395
int ddTotalNumberSwapping
Definition: cuddReorder.c:103
unsigned int next
Definition: cuddInt.h:317
int * invperm
Definition: cuddInt.h:371
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368
static int ddSymmUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddSymmetry.c:613
int autoDyn
Definition: cuddInt.h:400
int * perm
Definition: cuddInt.h:369
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
static int ddSymmSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddSymmetry.c:641

◆ cuddTestInteract()

int cuddTestInteract ( DdManager table,
int  x,
int  y 
)

Function********************************************************************

Synopsis [Test interaction matrix entries.]

Description [Given a pair of variables 0 <= x < y < table->size, tests whether the corresponding bit of the interaction matrix is 1. Returns the value of the bit.]

SideEffects [None]

SeeAlso []

Definition at line 188 of file cuddInteract.c.

192 {
193  int posn, word, bit, result;
194 
195  if (x > y) {
196  int tmp = x;
197  x = y;
198  y = tmp;
199  }
200 #ifdef DD_DEBUG
201  assert(x < y);
202  assert(y < table->size);
203  assert(x >= 0);
204 #endif
205 
206  posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1;
207  word = posn >> LOGBPL;
208  bit = posn & (BPL-1);
209  result = (table->interact[word] >> bit) & 1L;
210  return(result);
211 
212 } /* end of cuddTestInteract */
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
long * interact
Definition: cuddInt.h:377
#define BPL
Definition: cuddInteract.c:89
static int result
Definition: cuddGenetic.c:121
#define LOGBPL
Definition: cuddInteract.c:90

◆ cuddTimesInDeathRow()

int cuddTimesInDeathRow ( DdManager dd,
DdNode f 
)

Function********************************************************************

Synopsis [Counts how many times a node is in the death row.]

Description []

SideEffects [None]

SeeAlso [Cudd_DelayedDerefBdd cuddClearDeathRow cuddIsInDeathRow]

Definition at line 789 of file cuddRef.c.

792 {
793  int count = 0;
794 #ifndef DD_NO_DEATH_ROW
795  int i;
796 
797  for (i = 0; i < dd->deathRowDepth; i++) {
798  count += f == dd->deathRow[i];
799  }
800 #endif
801 
802  return(count);
803 
804 } /* end of cuddTimesInDeathRow */
DdNode ** deathRow
Definition: cuddInt.h:384
int deathRowDepth
Definition: cuddInt.h:385

◆ cuddTreeSifting()

int cuddTreeSifting ( DdManager table,
Cudd_ReorderingType  method 
)

Function********************************************************************

Synopsis [Tree sifting algorithm.]

Description [Tree sifting algorithm. Assumes that a tree representing a group hierarchy is passed as a parameter. It then reorders each group in postorder fashion by calling ddTreeSiftingAux. Assumes that no dead nodes are present. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 271 of file cuddGroup.c.

274 {
275  int i;
276  int nvars;
277  int result;
278  int tempTree;
279 
280  /* If no tree is provided we create a temporary one in which all
281  ** variables are in a single group. After reordering this tree is
282  ** destroyed.
283  */
284  tempTree = table->tree == NULL;
285  if (tempTree) {
286  table->tree = Mtr_InitGroupTree(0,table->size);
287  table->tree->index = table->invperm[0];
288  }
289  nvars = table->size;
290 
291 #ifdef DD_DEBUG
292  if (pr > 0 && !tempTree) (void) fprintf(table->out,"cuddTreeSifting:");
293  Mtr_PrintGroups(table->tree,pr <= 0);
294 #endif
295 
296 #ifdef DD_STATS
297  extsymmcalls = 0;
298  extsymm = 0;
299  secdiffcalls = 0;
300  secdiff = 0;
301  secdiffmisfire = 0;
302 
303  (void) fprintf(table->out,"\n");
304  if (!tempTree)
305  (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n",
306  ddCountInternalMtrNodes(table,table->tree));
307 #endif
308 
309  /* Initialize the group of each subtable to itself. Initially
310  ** there are no groups. Groups are created according to the tree
311  ** structure in postorder fashion.
312  */
313  for (i = 0; i < nvars; i++)
314  table->subtables[i].next = i;
315 
316 
317  /* Reorder. */
318  result = ddTreeSiftingAux(table, table->tree, method);
319 
320 #ifdef DD_STATS /* print stats */
321  if (!tempTree && method == CUDD_REORDER_GROUP_SIFT &&
322  (table->groupcheck == CUDD_GROUP_CHECK7 ||
323  table->groupcheck == CUDD_GROUP_CHECK5)) {
324  (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls);
325  (void) fprintf(table->out,"extsymm = %d",extsymm);
326  }
327  if (!tempTree && method == CUDD_REORDER_GROUP_SIFT &&
328  table->groupcheck == CUDD_GROUP_CHECK7) {
329  (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls);
330  (void) fprintf(table->out,"secdiff = %d\n",secdiff);
331  (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire);
332  }
333 #endif
334 
335  if (tempTree)
336  Cudd_FreeTree(table);
337  else
338  Mtr_ReorderGroups(table->tree, table->perm);
339 
340  return(result);
341 
342 } /* end of cuddTreeSifting */
Cudd_AggregationType groupcheck
Definition: cuddInt.h:410
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
void Mtr_ReorderGroups(MtrNode *treenode, int *permutation)
Definition: mtrGroup.c:524
MtrNode * tree
Definition: cuddInt.h:408
void Cudd_FreeTree(DdManager *dd)
Definition: cuddAPI.c:2462
MtrHalfWord index
Definition: mtr.h:130
FILE * out
Definition: cuddInt.h:423
static int ddTreeSiftingAux(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddGroup.c:361
void Mtr_PrintGroups(MtrNode *root, int silent)
Definition: mtrGroup.c:595
MtrNode * Mtr_InitGroupTree(int lower, int size)
Definition: mtrGroup.c:120
unsigned int next
Definition: cuddInt.h:317
int * invperm
Definition: cuddInt.h:371
static int result
Definition: cuddGenetic.c:121
int * perm
Definition: cuddInt.h:369

◆ cuddUnderApprox()

DdNode* cuddUnderApprox ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
int  safe,
double  quality 
)

◆ cuddUniqueConst()

DdNode* cuddUniqueConst ( DdManager unique,
CUDD_VALUE_TYPE  value 
)

Function********************************************************************

Synopsis [Checks the unique table for the existence of a constant node.]

Description [Checks the unique table for the existence of a constant node. If it does not exist, it creates a new one. Does not modify the reference count of whatever is returned. A newly created internal node comes back with a reference count 0. Returns a pointer to the new node.]

SideEffects [None]

Definition at line 1479 of file cuddTable.c.

1482 {
1483  int pos;
1484  DdNodePtr *nodelist;
1485  DdNode *looking;
1486  hack split;
1487 
1488 #ifdef DD_UNIQUE_PROFILE
1489  unique->uniqueLookUps++;
1490 #endif
1491 
1492  if (unique->constants.keys > unique->constants.maxKeys) {
1493  if (unique->gcEnabled && ((unique->dead > unique->minDead) ||
1494  (10 * unique->constants.dead > 9 * unique->constants.keys))) { /* too many dead */
1495  (void) cuddGarbageCollect(unique,1);
1496  } else {
1497  cuddRehash(unique,CUDD_CONST_INDEX);
1498  }
1499  }
1500 
1501  cuddAdjust(value); /* for the case of crippled infinities */
1502 
1503  if (ddAbs(value) < unique->epsilon) {
1504  value = 0.0;
1505  }
1506  split.value = value;
1507 
1508  pos = ddHash(split.bits[0], split.bits[1], unique->constants.shift);
1509  nodelist = unique->constants.nodelist;
1510  looking = nodelist[pos];
1511 
1512  /* Here we compare values both for equality and for difference less
1513  * than epsilon. The first comparison is required when values are
1514  * infinite, since Infinity - Infinity is NaN and NaN < X is 0 for
1515  * every X.
1516  */
1517  while (looking != NULL) {
1518  if (looking->type.value == value ||
1519  ddEqualVal(looking->type.value,value,unique->epsilon)) {
1520  if (looking->ref == 0) {
1521  cuddReclaim(unique,looking);
1522  }
1523  return(looking);
1524  }
1525  looking = looking->next;
1526 #ifdef DD_UNIQUE_PROFILE
1527  unique->uniqueLinks++;
1528 #endif
1529  }
1530 
1531  unique->keys++;
1532  unique->constants.keys++;
1533 
1534  looking = cuddAllocNode(unique);
1535  if (looking == NULL) return(NULL);
1536  looking->index = CUDD_CONST_INDEX;
1537  looking->type.value = value;
1538  looking->next = nodelist[pos];
1539  nodelist[pos] = looking;
1540 
1541  return(looking);
1542 
1543 } /* end of cuddUniqueConst */
DdHalfWord ref
Definition: cudd.h:272
unsigned int keys
Definition: cuddInt.h:314
#define ddHash(f, g, s)
Definition: cuddInt.h:696
union DdNode::@0 type
Definition: cudd.h:270
unsigned int bits[2]
Definition: cuddTable.c:109
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddRef.c:580
unsigned int dead
Definition: cuddInt.h:355
CUDD_VALUE_TYPE value
Definition: cudd.h:275
unsigned int keys
Definition: cuddInt.h:353
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:762
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:273
#define ddAbs(x)
Definition: cuddInt.h:799
void cuddRehash(DdManager *unique, int i)
Definition: cuddTable.c:1559
unsigned int maxKeys
Definition: cuddInt.h:315
int gcEnabled
Definition: cuddInt.h:360
#define CUDD_CONST_INDEX
Definition: cudd.h:113
DdNode ** nodelist
Definition: cuddInt.h:311
CUDD_VALUE_TYPE value
Definition: cuddTable.c:108
#define ddEqualVal(x, y, e)
Definition: cuddInt.h:814
DdHalfWord index
Definition: cudd.h:271
CUDD_VALUE_TYPE epsilon
Definition: cuddInt.h:390
DdSubtable constants
Definition: cuddInt.h:351
#define cuddAdjust(x)
Definition: cuddInt.h:932
int shift
Definition: cuddInt.h:312
DdNode * cuddAllocNode(DdManager *unique)
Definition: cuddTable.c:266
unsigned int minDead
Definition: cuddInt.h:358

◆ cuddUniqueInter()

DdNode* cuddUniqueInter ( DdManager unique,
int  index,
DdNode T,
DdNode E 
)

Function********************************************************************

Synopsis [Checks the unique table for the existence of an internal node.]

Description [Checks the unique table for the existence of an internal node. If it does not exist, it creates a new one. Does not modify the reference count of whatever is returned. A newly created internal node comes back with a reference count 0. For a newly created node, increments the reference counts of what T and E point to. Returns a pointer to the new node if successful; NULL if memory is exhausted or if reordering took place.]

SideEffects [None]

SeeAlso [cuddUniqueInterZdd]

Definition at line 1137 of file cuddTable.c.

1142 {
1143  int pos;
1144  unsigned int level;
1145  int retval;
1146  DdNodePtr *nodelist;
1147  DdNode *looking;
1148  DdNodePtr *previousP;
1149  DdSubtable *subtable;
1150  int gcNumber;
1151 
1152 #ifdef DD_UNIQUE_PROFILE
1153  unique->uniqueLookUps++;
1154 #endif
1155 
1156  if ((0x1ffffUL & (unsigned long) unique->cacheMisses) == 0) {
1157  if (util_cpu_time() - unique->startTime > unique->timeLimit) {
1158  unique->errorCode = CUDD_TIMEOUT_EXPIRED;
1159  return(NULL);
1160  }
1161  }
1162  if (index >= unique->size) {
1163  int amount = ddMax(DD_DEFAULT_RESIZE,unique->size/20);
1164  if (!ddResizeTable(unique,index,amount)) return(NULL);
1165  }
1166 
1167  level = unique->perm[index];
1168  subtable = &(unique->subtables[level]);
1169 
1170 #ifdef DD_DEBUG
1171  assert(level < (unsigned) cuddI(unique,T->index));
1172  assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index));
1173 #endif
1174 
1175  pos = ddHash(T, E, subtable->shift);
1176  nodelist = subtable->nodelist;
1177  previousP = &(nodelist[pos]);
1178  looking = *previousP;
1179 
1180  while (T < cuddT(looking)) {
1181  previousP = &(looking->next);
1182  looking = *previousP;
1183 #ifdef DD_UNIQUE_PROFILE
1184  unique->uniqueLinks++;
1185 #endif
1186  }
1187  while (T == cuddT(looking) && E < cuddE(looking)) {
1188  previousP = &(looking->next);
1189  looking = *previousP;
1190 #ifdef DD_UNIQUE_PROFILE
1191  unique->uniqueLinks++;
1192 #endif
1193  }
1194  if (T == cuddT(looking) && E == cuddE(looking)) {
1195  if (looking->ref == 0) {
1196  cuddReclaim(unique,looking);
1197  }
1198  return(looking);
1199  }
1200 
1201  /* countDead is 0 if deads should be counted and ~0 if they should not. */
1202  if (unique->autoDyn &&
1203  unique->keys - (unique->dead & unique->countDead) >= unique->nextDyn &&
1204  unique->maxReorderings > 0) {
1205  unsigned long cpuTime;
1206 #ifdef DD_DEBUG
1207  retval = Cudd_DebugCheck(unique);
1208  if (retval != 0) return(NULL);
1209  retval = Cudd_CheckKeys(unique);
1210  if (retval != 0) return(NULL);
1211 #endif
1212  retval = Cudd_ReduceHeap(unique,unique->autoMethod,10); /* 10 = whatever */
1213  unique->maxReorderings--;
1214  if (retval == 0) {
1215  unique->reordered = 2;
1216  } else if ((cpuTime = util_cpu_time()) - unique->startTime > unique->timeLimit) {
1217  unique->errorCode = CUDD_TIMEOUT_EXPIRED;
1218  unique->reordered = 0;
1219  } else if (unique->timeLimit - (cpuTime - unique->startTime)
1220  < unique->reordTime) {
1221  unique->autoDyn = 0;
1222  }
1223 #ifdef DD_DEBUG
1224  retval = Cudd_DebugCheck(unique);
1225  if (retval != 0) unique->reordered = 2;
1226  retval = Cudd_CheckKeys(unique);
1227  if (retval != 0) unique->reordered = 2;
1228 #endif
1229  return(NULL);
1230  }
1231 
1232  if (subtable->keys > subtable->maxKeys) {
1233  if (unique->gcEnabled &&
1234  ((unique->dead > unique->minDead) ||
1235  ((unique->dead > unique->minDead / 2) &&
1236  (subtable->dead > subtable->keys * 0.95)))) { /* too many dead */
1237  if (util_cpu_time() - unique->startTime > unique->timeLimit) {
1238  unique->errorCode = CUDD_TIMEOUT_EXPIRED;
1239  return(NULL);
1240  }
1241  (void) cuddGarbageCollect(unique,1);
1242  } else {
1243  cuddRehash(unique,(int)level);
1244  }
1245  /* Update pointer to insertion point. In the case of rehashing,
1246  ** the slot may have changed. In the case of garbage collection,
1247  ** the predecessor may have been dead. */
1248  pos = ddHash(T, E, subtable->shift);
1249  nodelist = subtable->nodelist;
1250  previousP = &(nodelist[pos]);
1251  looking = *previousP;
1252 
1253  while (T < cuddT(looking)) {
1254  previousP = &(looking->next);
1255  looking = *previousP;
1256 #ifdef DD_UNIQUE_PROFILE
1257  unique->uniqueLinks++;
1258 #endif
1259  }
1260  while (T == cuddT(looking) && E < cuddE(looking)) {
1261  previousP = &(looking->next);
1262  looking = *previousP;
1263 #ifdef DD_UNIQUE_PROFILE
1264  unique->uniqueLinks++;
1265 #endif
1266  }
1267  }
1268 
1269  gcNumber = unique->garbageCollections;
1270  looking = cuddAllocNode(unique);
1271  if (looking == NULL) {
1272  return(NULL);
1273  }
1274  unique->keys++;
1275  subtable->keys++;
1276 
1277  if (gcNumber != unique->garbageCollections) {
1278  DdNode *looking2;
1279  pos = ddHash(T, E, subtable->shift);
1280  nodelist = subtable->nodelist;
1281  previousP = &(nodelist[pos]);
1282  looking2 = *previousP;
1283 
1284  while (T < cuddT(looking2)) {
1285  previousP = &(looking2->next);
1286  looking2 = *previousP;
1287 #ifdef DD_UNIQUE_PROFILE
1288  unique->uniqueLinks++;
1289 #endif
1290  }
1291  while (T == cuddT(looking2) && E < cuddE(looking2)) {
1292  previousP = &(looking2->next);
1293  looking2 = *previousP;
1294 #ifdef DD_UNIQUE_PROFILE
1295  unique->uniqueLinks++;
1296 #endif
1297  }
1298  }
1299  looking->index = index;
1300  cuddT(looking) = T;
1301  cuddE(looking) = E;
1302  looking->next = *previousP;
1303  *previousP = looking;
1304  cuddSatInc(T->ref); /* we know T is a regular pointer */
1305  cuddRef(E);
1306 
1307 #ifdef DD_DEBUG
1308  cuddCheckCollisionOrdering(unique,level,pos);
1309 #endif
1310 
1311  return(looking);
1312 
1313 } /* end of cuddUniqueInter */
DdHalfWord ref
Definition: cudd.h:272
#define cuddRef(n)
Definition: cuddInt.h:557
unsigned int keys
Definition: cuddInt.h:314
static int ddResizeTable(DdManager *unique, int index, int amount)
Definition: cuddTable.c:2555
#define ddHash(f, g, s)
Definition: cuddInt.h:696
unsigned long reordTime
Definition: cuddInt.h:434
Cudd_ReorderingType autoMethod
Definition: cuddInt.h:402
Definition: cudd.h:270
unsigned long startTime
Definition: cuddInt.h:426
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
#define Cudd_Regular(node)
Definition: cudd.h:384
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddRef.c:580
int garbageCollections
Definition: cuddInt.h:432
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int countDead
Definition: cuddInt.h:407
int reordered
Definition: cuddInt.h:392
unsigned int nextDyn
Definition: cuddInt.h:406
unsigned int dead
Definition: cuddInt.h:355
unsigned int keys
Definition: cuddInt.h:353
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:762
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:273
void cuddRehash(DdManager *unique, int i)
Definition: cuddTable.c:1559
unsigned int maxKeys
Definition: cuddInt.h:315
int gcEnabled
Definition: cuddInt.h:360
#define ddMax(x, y)
Definition: cuddInt.h:785
DdNode ** nodelist
Definition: cuddInt.h:311
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:138
long util_cpu_time(void)
Definition: cpu_time.c:34
#define cuddT(node)
Definition: cuddInt.h:609
unsigned int maxReorderings
Definition: cuddInt.h:394
#define cuddI(dd, index)
Definition: cuddInt.h:659
#define DD_DEFAULT_RESIZE
Definition: cuddInt.h:103
DdHalfWord index
Definition: cudd.h:271
double cacheMisses
Definition: cuddInt.h:339
int Cudd_CheckKeys(DdManager *table)
Definition: cuddCheck.c:460
#define cuddE(node)
Definition: cuddInt.h:625
int Cudd_ReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
Definition: cuddReorder.c:172
int autoDyn
Definition: cuddInt.h:400
int shift
Definition: cuddInt.h:312
int * perm
Definition: cuddInt.h:369
unsigned long timeLimit
Definition: cuddInt.h:427
DdNode * cuddAllocNode(DdManager *unique)
Definition: cuddTable.c:266
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
unsigned int minDead
Definition: cuddInt.h:358
#define cuddSatInc(x)
Definition: cuddInt.h:831

◆ cuddUniqueInterIVO()

DdNode* cuddUniqueInterIVO ( DdManager unique,
int  index,
DdNode T,
DdNode E 
)

Function********************************************************************

Synopsis [Wrapper for cuddUniqueInter that is independent of variable ordering.]

Description [Wrapper for cuddUniqueInter that is independent of variable ordering (IVO). This function does not require parameter index to precede the indices of the top nodes of T and E in the variable order. Returns a pointer to the result node under normal conditions; NULL if reordering occurred or memory was exhausted.]

SideEffects [None]

SeeAlso [cuddUniqueInter Cudd_MakeBddFromZddCover]

Definition at line 1333 of file cuddTable.c.

1338 {
1339  DdNode *result;
1340  DdNode *v;
1341 
1342  v = cuddUniqueInter(unique, index, DD_ONE(unique),
1343  Cudd_Not(DD_ONE(unique)));
1344  if (v == NULL)
1345  return(NULL);
1346  /* Since v is a projection function, we can skip the call to cuddRef. */
1347  result = cuddBddIteRecur(unique, v, T, E);
1348  return(result);
1349 
1350 } /* end of cuddUniqueInterIVO */
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:742
static int result
Definition: cuddGenetic.c:121
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ cuddUniqueInterZdd()

DdNode* cuddUniqueInterZdd ( DdManager unique,
int  index,
DdNode T,
DdNode E 
)

Function********************************************************************

Synopsis [Checks the unique table for the existence of an internal ZDD node.]

Description [Checks the unique table for the existence of an internal ZDD node. If it does not exist, it creates a new one. Does not modify the reference count of whatever is returned. A newly created internal node comes back with a reference count 0. For a newly created node, increments the reference counts of what T and E point to. Returns a pointer to the new node if successful; NULL if memory is exhausted or if reordering took place.]

SideEffects [None]

SeeAlso [cuddUniqueInter]

Definition at line 1372 of file cuddTable.c.

1377 {
1378  int pos;
1379  unsigned int level;
1380  int retval;
1381  DdNodePtr *nodelist;
1382  DdNode *looking;
1383  DdSubtable *subtable;
1384 
1385 #ifdef DD_UNIQUE_PROFILE
1386  unique->uniqueLookUps++;
1387 #endif
1388 
1389  if (index >= unique->sizeZ) {
1390  if (!cuddResizeTableZdd(unique,index)) return(NULL);
1391  }
1392 
1393  level = unique->permZ[index];
1394  subtable = &(unique->subtableZ[level]);
1395 
1396 #ifdef DD_DEBUG
1397  assert(level < (unsigned) cuddIZ(unique,T->index));
1398  assert(level < (unsigned) cuddIZ(unique,Cudd_Regular(E)->index));
1399 #endif
1400 
1401  if (subtable->keys > subtable->maxKeys) {
1402  if (unique->gcEnabled && ((unique->deadZ > unique->minDead) ||
1403  (10 * subtable->dead > 9 * subtable->keys))) { /* too many dead */
1404  (void) cuddGarbageCollect(unique,1);
1405  } else {
1406  ddRehashZdd(unique,(int)level);
1407  }
1408  }
1409 
1410  pos = ddHash(T, E, subtable->shift);
1411  nodelist = subtable->nodelist;
1412  looking = nodelist[pos];
1413 
1414  while (looking != NULL) {
1415  if (cuddT(looking) == T && cuddE(looking) == E) {
1416  if (looking->ref == 0) {
1417  cuddReclaimZdd(unique,looking);
1418  }
1419  return(looking);
1420  }
1421  looking = looking->next;
1422 #ifdef DD_UNIQUE_PROFILE
1423  unique->uniqueLinks++;
1424 #endif
1425  }
1426 
1427  /* countDead is 0 if deads should be counted and ~0 if they should not. */
1428  if (unique->autoDynZ &&
1429  unique->keysZ - (unique->deadZ & unique->countDead) >= unique->nextDyn) {
1430 #ifdef DD_DEBUG
1431  retval = Cudd_DebugCheck(unique);
1432  if (retval != 0) return(NULL);
1433  retval = Cudd_CheckKeys(unique);
1434  if (retval != 0) return(NULL);
1435 #endif
1436  retval = Cudd_zddReduceHeap(unique,unique->autoMethodZ,10); /* 10 = whatever */
1437  if (retval == 0) unique->reordered = 2;
1438 #ifdef DD_DEBUG
1439  retval = Cudd_DebugCheck(unique);
1440  if (retval != 0) unique->reordered = 2;
1441  retval = Cudd_CheckKeys(unique);
1442  if (retval != 0) unique->reordered = 2;
1443 #endif
1444  return(NULL);
1445  }
1446 
1447  unique->keysZ++;
1448  subtable->keys++;
1449 
1450  looking = cuddAllocNode(unique);
1451  if (looking == NULL) return(NULL);
1452  looking->index = index;
1453  cuddT(looking) = T;
1454  cuddE(looking) = E;
1455  looking->next = nodelist[pos];
1456  nodelist[pos] = looking;
1457  cuddRef(T);
1458  cuddRef(E);
1459 
1460  return(looking);
1461 
1462 } /* end of cuddUniqueInterZdd */
DdHalfWord ref
Definition: cudd.h:272
#define cuddRef(n)
Definition: cuddInt.h:557
unsigned int keys
Definition: cuddInt.h:314
#define ddHash(f, g, s)
Definition: cuddInt.h:696
#define cuddIZ(dd, index)
Definition: cuddInt.h:677
Definition: cudd.h:270
unsigned int deadZ
Definition: cuddInt.h:356
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:384
Cudd_ReorderingType autoMethodZ
Definition: cuddInt.h:403
int * permZ
Definition: cuddInt.h:370
unsigned int countDead
Definition: cuddInt.h:407
int reordered
Definition: cuddInt.h:392
unsigned int nextDyn
Definition: cuddInt.h:406
int cuddResizeTableZdd(DdManager *unique, int index)
Definition: cuddTable.c:2270
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:762
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:273
unsigned int maxKeys
Definition: cuddInt.h:315
int gcEnabled
Definition: cuddInt.h:360
DdNode ** nodelist
Definition: cuddInt.h:311
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:138
#define cuddT(node)
Definition: cuddInt.h:609
static void ddRehashZdd(DdManager *unique, int i)
Definition: cuddTable.c:2451
void cuddReclaimZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:634
int Cudd_zddReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
Definition: cuddZddReord.c:167
int sizeZ
Definition: cuddInt.h:346
DdHalfWord index
Definition: cudd.h:271
int Cudd_CheckKeys(DdManager *table)
Definition: cuddCheck.c:460
int autoDynZ
Definition: cuddInt.h:401
#define cuddE(node)
Definition: cuddInt.h:625
int shift
Definition: cuddInt.h:312
unsigned int keysZ
Definition: cuddInt.h:354
DdNode * cuddAllocNode(DdManager *unique)
Definition: cuddTable.c:266
unsigned int minDead
Definition: cuddInt.h:358
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddUpdateInteractionMatrix()

void cuddUpdateInteractionMatrix ( DdManager table,
int  xindex,
int  yindex 
)

Function********************************************************************

Synopsis [Updates the interaction matrix.]

Description []

SideEffects [none]

SeeAlso []

Definition at line 714 of file cuddLinear.c.

718 {
719  int i;
720  for (i = 0; i < yindex; i++) {
721  if (i != xindex && cuddTestInteract(table,i,yindex)) {
722  if (i < xindex) {
723  cuddSetInteract(table,i,xindex);
724  } else {
725  cuddSetInteract(table,xindex,i);
726  }
727  }
728  }
729  for (i = yindex+1; i < table->size; i++) {
730  if (i != xindex && cuddTestInteract(table,yindex,i)) {
731  if (i < xindex) {
732  cuddSetInteract(table,i,xindex);
733  } else {
734  cuddSetInteract(table,xindex,i);
735  }
736  }
737  }
738 
739 } /* end of cuddUpdateInteractionMatrix */
int size
Definition: cuddInt.h:345
void cuddSetInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:153
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:188

◆ cuddVerifySol()

DdNode* cuddVerifySol ( DdManager bdd,
DdNode F,
DdNode **  G,
int *  yIndex,
int  n 
)

◆ cuddWindowReorder()

int cuddWindowReorder ( DdManager table,
int  low,
int  high,
Cudd_ReorderingType  submethod 
)

AutomaticEnd Function********************************************************************

Synopsis [Reorders by applying the method of the sliding window.]

Description [Reorders by applying the method of the sliding window. Tries all possible permutations to the variables in a window that slides from low to high. The size of the window is determined by submethod. Assumes that no dead nodes are present. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 138 of file cuddWindow.c.

143 {
144 
145  int res;
146 #ifdef DD_DEBUG
147  int supposedOpt;
148 #endif
149 
150  switch (submethod) {
152  res = ddWindow2(table,low,high);
153  break;
155  res = ddWindow3(table,low,high);
156  break;
158  res = ddWindow4(table,low,high);
159  break;
161  res = ddWindowConv2(table,low,high);
162  break;
164  res = ddWindowConv3(table,low,high);
165 #ifdef DD_DEBUG
166  supposedOpt = table->keys - table->isolated;
167  res = ddWindow3(table,low,high);
168  if (table->keys - table->isolated != (unsigned) supposedOpt) {
169  (void) fprintf(table->err, "Convergence failed! (%d != %d)\n",
170  table->keys - table->isolated, supposedOpt);
171  }
172 #endif
173  break;
175  res = ddWindowConv4(table,low,high);
176 #ifdef DD_DEBUG
177  supposedOpt = table->keys - table->isolated;
178  res = ddWindow4(table,low,high);
179  if (table->keys - table->isolated != (unsigned) supposedOpt) {
180  (void) fprintf(table->err,"Convergence failed! (%d != %d)\n",
181  table->keys - table->isolated, supposedOpt);
182  }
183 #endif
184  break;
185  default: return(0);
186  }
187 
188  return(res);
189 
190 } /* end of cuddWindowReorder */
static int ddWindow2(DdManager *table, int low, int high)
Definition: cuddWindow.c:210
static int ddWindow4(DdManager *table, int low, int high)
Definition: cuddWindow.c:853
static int ddWindow3(DdManager *table, int low, int high)
Definition: cuddWindow.c:452
static int ddWindowConv2(DdManager *table, int low, int high)
Definition: cuddWindow.c:264
FILE * err
Definition: cuddInt.h:424
static int ddWindowConv4(DdManager *table, int low, int high)
Definition: cuddWindow.c:900
unsigned int keys
Definition: cuddInt.h:353
int isolated
Definition: cuddInt.h:368
static int ddWindowConv3(DdManager *table, int low, int high)
Definition: cuddWindow.c:499

◆ cuddZddAlignToBdd()

int cuddZddAlignToBdd ( DdManager table)

Function********************************************************************

Synopsis [Reorders ZDD variables according to the order of the BDD variables.]

Description [Reorders ZDD variables according to the order of the BDD variables. This function can be called at the end of BDD reordering to insure that the order of the ZDD variables is consistent with the order of the BDD variables. The number of ZDD variables must be a multiple of the number of BDD variables. Let M be the ratio of the two numbers. cuddZddAlignToBdd then considers the ZDD variables from M*i to (M+1)*i-1 as corresponding to BDD variable i. This function should be normally called from Cudd_ReduceHeap, which clears the cache. Returns 1 in case of success; 0 otherwise.]

SideEffects [Changes the ZDD variable order for all diagrams and performs garbage collection of the ZDD unique table.]

SeeAlso [Cudd_zddShuffleHeap Cudd_ReduceHeap]

Definition at line 348 of file cuddZddReord.c.

350 {
351  int *invpermZ; /* permutation array */
352  int M; /* ratio of ZDD variables to BDD variables */
353  int i,j; /* loop indices */
354  int result; /* return value */
355 
356  /* We assume that a ratio of 0 is OK. */
357  if (table->sizeZ == 0)
358  return(1);
359 
360  empty = table->zero;
361  M = table->sizeZ / table->size;
362  /* Check whether the number of ZDD variables is a multiple of the
363  ** number of BDD variables.
364  */
365  if (M * table->size != table->sizeZ)
366  return(0);
367  /* Create and initialize the inverse permutation array. */
368  invpermZ = ALLOC(int,table->sizeZ);
369  if (invpermZ == NULL) {
370  table->errorCode = CUDD_MEMORY_OUT;
371  return(0);
372  }
373  for (i = 0; i < table->size; i++) {
374  int index = table->invperm[i];
375  int indexZ = index * M;
376  int levelZ = table->permZ[indexZ];
377  levelZ = (levelZ / M) * M;
378  for (j = 0; j < M; j++) {
379  invpermZ[M * i + j] = table->invpermZ[levelZ + j];
380  }
381  }
382  /* Eliminate dead nodes. Do not scan the cache again, because we
383  ** assume that Cudd_ReduceHeap has already cleared it.
384  */
385  cuddGarbageCollect(table,0);
386 
387  result = zddShuffle(table, invpermZ);
388  FREE(invpermZ);
389  /* Fix the ZDD variable group tree. */
390  zddFixTree(table,table->treeZ);
391  return(result);
392 
393 } /* end of cuddZddAlignToBdd */
#define FREE(obj)
Definition: util.h:80
int * invpermZ
Definition: cuddInt.h:372
int size
Definition: cuddInt.h:345
DdNode * zero
Definition: cuddInt.h:330
int * permZ
Definition: cuddInt.h:370
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:762
static DdNode * empty
Definition: cuddZddReord.c:108
#define ALLOC(type, num)
Definition: util.h:76
int sizeZ
Definition: cuddInt.h:346
MtrNode * treeZ
Definition: cuddInt.h:409
int * invperm
Definition: cuddInt.h:371
static int result
Definition: cuddGenetic.c:121
static void zddFixTree(DdManager *table, MtrNode *treenode)
static int zddShuffle(DdManager *table, int *permutation)
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddZddChange()

DdNode* cuddZddChange ( DdManager dd,
DdNode P,
int  var 
)

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. cuddZddChange performs the same function as Cudd_zddChange, but does not restart if reordering has taken place. Therefore it can be called from within a recursive procedure.]

SideEffects [None]

SeeAlso [Cudd_zddChange]

Definition at line 967 of file cuddZddSetop.c.

971 {
972  DdNode *zvar, *res;
973 
974  zvar = cuddUniqueInterZdd(dd, var, DD_ONE(dd), DD_ZERO(dd));
975  if (zvar == NULL) return(NULL);
976  cuddRef(zvar);
977 
978  res = cuddZddChangeAux(dd, P, zvar);
979  if (res == NULL) {
980  Cudd_RecursiveDerefZdd(dd,zvar);
981  return(NULL);
982  }
983  cuddRef(res);
984  Cudd_RecursiveDerefZdd(dd,zvar);
985  cuddDeref(res);
986  return(res);
987 
988 } /* end of cuddZddChange */
#define cuddRef(n)
Definition: cuddInt.h:557
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1372
DdNode * cuddZddChangeAux(DdManager *zdd, DdNode *P, DdNode *zvar)
Definition: cuddZddSetop.c:795
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddChangeAux()

DdNode* cuddZddChangeAux ( DdManager zdd,
DdNode P,
DdNode zvar 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddChange.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 795 of file cuddZddSetop.c.

799 {
800  int top_var, level;
801  DdNode *res, *t, *e;
802  DdNode *base = DD_ONE(zdd);
803  DdNode *empty = DD_ZERO(zdd);
804 
805  statLine(zdd);
806  if (P == empty)
807  return(empty);
808  if (P == base)
809  return(zvar);
810 
811  /* Check cache. */
812  res = cuddCacheLookup2Zdd(zdd, cuddZddChangeAux, P, zvar);
813  if (res != NULL)
814  return(res);
815 
816  top_var = zdd->permZ[P->index];
817  level = zdd->permZ[zvar->index];
818 
819  if (top_var > level) {
820  res = cuddZddGetNode(zdd, zvar->index, P, DD_ZERO(zdd));
821  if (res == NULL) return(NULL);
822  } else if (top_var == level) {
823  res = cuddZddGetNode(zdd, zvar->index, cuddE(P), cuddT(P));
824  if (res == NULL) return(NULL);
825  } else {
826  t = cuddZddChangeAux(zdd, cuddT(P), zvar);
827  if (t == NULL) return(NULL);
828  cuddRef(t);
829  e = cuddZddChangeAux(zdd, cuddE(P), zvar);
830  if (e == NULL) {
831  Cudd_RecursiveDerefZdd(zdd, t);
832  return(NULL);
833  }
834  cuddRef(e);
835  res = cuddZddGetNode(zdd, P->index, t, e);
836  if (res == NULL) {
837  Cudd_RecursiveDerefZdd(zdd, t);
838  Cudd_RecursiveDerefZdd(zdd, e);
839  return(NULL);
840  }
841  cuddDeref(t);
842  cuddDeref(e);
843  }
844 
845  cuddCacheInsert2(zdd, cuddZddChangeAux, P, zvar, res);
846 
847  return(res);
848 
849 } /* end of cuddZddChangeAux */
#define cuddRef(n)
Definition: cuddInt.h:557
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1050
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddCacheLookup2Zdd(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
DdNode * cuddZddChangeAux(DdManager *zdd, DdNode *P, DdNode *zvar)
Definition: cuddZddSetop.c:795
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * empty
Definition: cuddZddLin.c:94
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddComplement()

DdNode* cuddZddComplement ( DdManager dd,
DdNode node 
)

Function********************************************************************

Synopsis [Computes a complement of a ZDD node.]

Description [Computes the complement of a ZDD node. So far, since we couldn't find a direct way to get the complement of a ZDD cover, we first convert a ZDD cover to a BDD, then make the complement of the ZDD cover from the complement of the BDD node by using ISOP.]

SideEffects [The result depends on current variable order.]

SeeAlso []

Definition at line 1518 of file cuddZddFuncs.c.

1521 {
1522  DdNode *b, *isop, *zdd_I;
1523 
1524  /* Check cache */
1525  zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node);
1526  if (zdd_I)
1527  return(zdd_I);
1528 
1529  b = cuddMakeBddFromZddCover(dd, node);
1530  if (!b)
1531  return(NULL);
1532  cuddRef(b);
1533  isop = cuddZddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I);
1534  if (!isop) {
1535  Cudd_RecursiveDeref(dd, b);
1536  return(NULL);
1537  }
1538  cuddRef(isop);
1539  cuddRef(zdd_I);
1540  Cudd_RecursiveDeref(dd, b);
1541  Cudd_RecursiveDeref(dd, isop);
1542 
1543  cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I);
1544  cuddDeref(zdd_I);
1545  return(zdd_I);
1546 } /* end of cuddZddComplement */
#define cuddRef(n)
Definition: cuddInt.h:557
DdNode * cuddCacheLookup1Zdd(DdManager *table, DdNode *(*)(DdManager *, DdNode *), DdNode *f)
#define cuddDeref(n)
Definition: cuddInt.h:577
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
void cuddCacheInsert1(DdManager *table, DdNode *(*)(DdManager *, DdNode *), DdNode *f, DdNode *data)
DdNode * cuddZddIsop(DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)
Definition: cuddZddIsop.c:231
DdNode * cuddMakeBddFromZddCover(DdManager *dd, DdNode *node)
Definition: cuddZddIsop.c:797
DdNode * cuddZddComplement(DdManager *dd, DdNode *node)

◆ cuddZddDiff()

DdNode* cuddZddDiff ( DdManager zdd,
DdNode P,
DdNode Q 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddDiff.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 713 of file cuddZddSetop.c.

717 {
718  int p_top, q_top;
719  DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
720  DdManager *table = zdd;
721 
722  statLine(zdd);
723  if (P == empty)
724  return(empty);
725  if (Q == empty)
726  return(P);
727  if (P == Q)
728  return(empty);
729 
730  /* Check cache. The cache is shared by Cudd_zddDiffConst(). */
731  res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q);
732  if (res != NULL && res != DD_NON_CONSTANT)
733  return(res);
734 
735  if (cuddIsConstant(P))
736  p_top = P->index;
737  else
738  p_top = zdd->permZ[P->index];
739  if (cuddIsConstant(Q))
740  q_top = Q->index;
741  else
742  q_top = zdd->permZ[Q->index];
743  if (p_top < q_top) {
744  e = cuddZddDiff(zdd, cuddE(P), Q);
745  if (e == NULL) return(NULL);
746  cuddRef(e);
747  res = cuddZddGetNode(zdd, P->index, cuddT(P), e);
748  if (res == NULL) {
749  Cudd_RecursiveDerefZdd(table, e);
750  return(NULL);
751  }
752  cuddDeref(e);
753  } else if (p_top > q_top) {
754  res = cuddZddDiff(zdd, P, cuddE(Q));
755  if (res == NULL) return(NULL);
756  } else {
757  t = cuddZddDiff(zdd, cuddT(P), cuddT(Q));
758  if (t == NULL) return(NULL);
759  cuddRef(t);
760  e = cuddZddDiff(zdd, cuddE(P), cuddE(Q));
761  if (e == NULL) {
762  Cudd_RecursiveDerefZdd(table, t);
763  return(NULL);
764  }
765  cuddRef(e);
766  res = cuddZddGetNode(zdd, P->index, t, e);
767  if (res == NULL) {
768  Cudd_RecursiveDerefZdd(table, t);
769  Cudd_RecursiveDerefZdd(table, e);
770  return(NULL);
771  }
772  cuddDeref(t);
773  cuddDeref(e);
774  }
775 
776  cuddCacheInsert2(table, cuddZddDiff, P, Q, res);
777 
778  return(res);
779 
780 } /* end of cuddZddDiff */
#define cuddRef(n)
Definition: cuddInt.h:557
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1050
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddCacheLookup2Zdd(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
DdNode * cuddZddDiff(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:713
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * empty
Definition: cuddZddLin.c:94
#define DD_NON_CONSTANT
Definition: cuddInt.h:124
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddDivide()

DdNode* cuddZddDivide ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddDivide.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddDivide]

Definition at line 1155 of file cuddZddFuncs.c.

1159 {
1160  int v;
1161  DdNode *one = DD_ONE(dd);
1162  DdNode *zero = DD_ZERO(dd);
1163  DdNode *f0, *f1, *g0, *g1;
1164  DdNode *q, *r, *tmp;
1165  int flag;
1166 
1167  statLine(dd);
1168  if (g == one)
1169  return(f);
1170  if (f == zero || f == one)
1171  return(zero);
1172  if (f == g)
1173  return(one);
1174 
1175  /* Check cache. */
1176  r = cuddCacheLookup2Zdd(dd, cuddZddDivide, f, g);
1177  if (r)
1178  return(r);
1179 
1180  v = g->index;
1181 
1182  flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
1183  if (flag == 1)
1184  return(NULL);
1185  Cudd_Ref(f1);
1186  Cudd_Ref(f0);
1187  flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */
1188  if (flag == 1) {
1189  Cudd_RecursiveDerefZdd(dd, f1);
1190  Cudd_RecursiveDerefZdd(dd, f0);
1191  return(NULL);
1192  }
1193  Cudd_Ref(g1);
1194  Cudd_Ref(g0);
1195 
1196  r = cuddZddDivide(dd, f1, g1);
1197  if (r == NULL) {
1198  Cudd_RecursiveDerefZdd(dd, f1);
1199  Cudd_RecursiveDerefZdd(dd, f0);
1200  Cudd_RecursiveDerefZdd(dd, g1);
1201  Cudd_RecursiveDerefZdd(dd, g0);
1202  return(NULL);
1203  }
1204  Cudd_Ref(r);
1205 
1206  if (r != zero && g0 != zero) {
1207  tmp = r;
1208  q = cuddZddDivide(dd, f0, g0);
1209  if (q == NULL) {
1210  Cudd_RecursiveDerefZdd(dd, f1);
1211  Cudd_RecursiveDerefZdd(dd, f0);
1212  Cudd_RecursiveDerefZdd(dd, g1);
1213  Cudd_RecursiveDerefZdd(dd, g0);
1214  return(NULL);
1215  }
1216  Cudd_Ref(q);
1217  r = cuddZddIntersect(dd, r, q);
1218  if (r == NULL) {
1219  Cudd_RecursiveDerefZdd(dd, f1);
1220  Cudd_RecursiveDerefZdd(dd, f0);
1221  Cudd_RecursiveDerefZdd(dd, g1);
1222  Cudd_RecursiveDerefZdd(dd, g0);
1223  Cudd_RecursiveDerefZdd(dd, q);
1224  return(NULL);
1225  }
1226  Cudd_Ref(r);
1227  Cudd_RecursiveDerefZdd(dd, q);
1228  Cudd_RecursiveDerefZdd(dd, tmp);
1229  }
1230 
1231  Cudd_RecursiveDerefZdd(dd, f1);
1232  Cudd_RecursiveDerefZdd(dd, f0);
1233  Cudd_RecursiveDerefZdd(dd, g1);
1234  Cudd_RecursiveDerefZdd(dd, g0);
1235 
1236  cuddCacheInsert2(dd, cuddZddDivide, f, g, r);
1237  Cudd_Deref(r);
1238  return(r);
1239 
1240 } /* end of cuddZddDivide */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
DdNode * cuddZddDivide(DdManager *dd, DdNode *f, DdNode *g)
Definition: cudd.h:270
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
int cuddZddGetCofactors2(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0)
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:638
DdNode * cuddCacheLookup2Zdd(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddDivideF()

DdNode* cuddZddDivideF ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddDivideF.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddDivideF]

Definition at line 1255 of file cuddZddFuncs.c.

1259 {
1260  int v;
1261  DdNode *one = DD_ONE(dd);
1262  DdNode *zero = DD_ZERO(dd);
1263  DdNode *f0, *f1, *g0, *g1;
1264  DdNode *q, *r, *tmp;
1265  int flag;
1266 
1267  statLine(dd);
1268  if (g == one)
1269  return(f);
1270  if (f == zero || f == one)
1271  return(zero);
1272  if (f == g)
1273  return(one);
1274 
1275  /* Check cache. */
1276  r = cuddCacheLookup2Zdd(dd, cuddZddDivideF, f, g);
1277  if (r)
1278  return(r);
1279 
1280  v = g->index;
1281 
1282  flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
1283  if (flag == 1)
1284  return(NULL);
1285  Cudd_Ref(f1);
1286  Cudd_Ref(f0);
1287  flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */
1288  if (flag == 1) {
1289  Cudd_RecursiveDerefZdd(dd, f1);
1290  Cudd_RecursiveDerefZdd(dd, f0);
1291  return(NULL);
1292  }
1293  Cudd_Ref(g1);
1294  Cudd_Ref(g0);
1295 
1296  r = cuddZddDivideF(dd, f1, g1);
1297  if (r == NULL) {
1298  Cudd_RecursiveDerefZdd(dd, f1);
1299  Cudd_RecursiveDerefZdd(dd, f0);
1300  Cudd_RecursiveDerefZdd(dd, g1);
1301  Cudd_RecursiveDerefZdd(dd, g0);
1302  return(NULL);
1303  }
1304  Cudd_Ref(r);
1305 
1306  if (r != zero && g0 != zero) {
1307  tmp = r;
1308  q = cuddZddDivideF(dd, f0, g0);
1309  if (q == NULL) {
1310  Cudd_RecursiveDerefZdd(dd, f1);
1311  Cudd_RecursiveDerefZdd(dd, f0);
1312  Cudd_RecursiveDerefZdd(dd, g1);
1313  Cudd_RecursiveDerefZdd(dd, g0);
1314  return(NULL);
1315  }
1316  Cudd_Ref(q);
1317  r = cuddZddIntersect(dd, r, q);
1318  if (r == NULL) {
1319  Cudd_RecursiveDerefZdd(dd, f1);
1320  Cudd_RecursiveDerefZdd(dd, f0);
1321  Cudd_RecursiveDerefZdd(dd, g1);
1322  Cudd_RecursiveDerefZdd(dd, g0);
1323  Cudd_RecursiveDerefZdd(dd, q);
1324  return(NULL);
1325  }
1326  Cudd_Ref(r);
1327  Cudd_RecursiveDerefZdd(dd, q);
1328  Cudd_RecursiveDerefZdd(dd, tmp);
1329  }
1330 
1331  Cudd_RecursiveDerefZdd(dd, f1);
1332  Cudd_RecursiveDerefZdd(dd, f0);
1333  Cudd_RecursiveDerefZdd(dd, g1);
1334  Cudd_RecursiveDerefZdd(dd, g0);
1335 
1336  cuddCacheInsert2(dd, cuddZddDivideF, f, g, r);
1337  Cudd_Deref(r);
1338  return(r);
1339 
1340 } /* end of cuddZddDivideF */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
Definition: cudd.h:270
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
int cuddZddGetCofactors2(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0)
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:638
DdNode * cuddCacheLookup2Zdd(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddZddDivideF(DdManager *dd, DdNode *f, DdNode *g)
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddFreeUniv()

void cuddZddFreeUniv ( DdManager zdd)

Function********************************************************************

Synopsis [Frees the ZDD universe.]

Description [Frees the ZDD universe.]

SideEffects [None]

SeeAlso [cuddZddInitUniv]

Definition at line 294 of file cuddInit.c.

296 {
297  if (zdd->univ) {
298  Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]);
299  FREE(zdd->univ);
300  }
301 
302 } /* end of cuddZddFreeUniv */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
#define FREE(obj)
Definition: util.h:80
DdNode ** univ
Definition: cuddInt.h:375

◆ cuddZddGetCofactors2()

int cuddZddGetCofactors2 ( DdManager dd,
DdNode f,
int  v,
DdNode **  f1,
DdNode **  f0 
)

Function********************************************************************

Synopsis [Computes the two-way decomposition of f w.r.t. v.]

Description []

SideEffects [The results are returned in f1 and f0.]

SeeAlso [cuddZddGetCofactors3]

Definition at line 1483 of file cuddZddFuncs.c.

1489 {
1490  *f1 = cuddZddSubset1(dd, f, v);
1491  if (*f1 == NULL)
1492  return(1);
1493  *f0 = cuddZddSubset0(dd, f, v);
1494  if (*f0 == NULL) {
1495  Cudd_RecursiveDerefZdd(dd, *f1);
1496  return(1);
1497  }
1498  return(0);
1499 
1500 } /* end of cuddZddGetCofactors2 */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
DdNode * cuddZddSubset1(DdManager *dd, DdNode *P, int var)
Definition: cuddZddSetop.c:870
DdNode * cuddZddSubset0(DdManager *dd, DdNode *P, int var)
Definition: cuddZddSetop.c:919

◆ cuddZddGetCofactors3()

int cuddZddGetCofactors3 ( DdManager dd,
DdNode f,
int  v,
DdNode **  f1,
DdNode **  f0,
DdNode **  fd 
)

Function********************************************************************

Synopsis [Computes the three-way decomposition of f w.r.t. v.]

Description [Computes the three-way decomposition of function f (represented by a ZDD) wit respect to variable v. Returns 0 if successful; 1 otherwise.]

SideEffects [The results are returned in f1, f0, and fd.]

SeeAlso [cuddZddGetCofactors2]

Definition at line 1356 of file cuddZddFuncs.c.

1363 {
1364  DdNode *pc, *nc;
1365  DdNode *zero = DD_ZERO(dd);
1366  int top, hv, ht, pv, nv;
1367  int level;
1368 
1369  top = dd->permZ[f->index];
1370  level = dd->permZ[v];
1371  hv = level >> 1;
1372  ht = top >> 1;
1373 
1374  if (hv < ht) {
1375  *f1 = zero;
1376  *f0 = zero;
1377  *fd = f;
1378  }
1379  else {
1380  pv = cuddZddGetPosVarIndex(dd, v);
1381  nv = cuddZddGetNegVarIndex(dd, v);
1382 
1383  /* not to create intermediate ZDD node */
1384  if (cuddZddGetPosVarLevel(dd, v) < cuddZddGetNegVarLevel(dd, v)) {
1385  pc = cuddZddSubset1(dd, f, pv);
1386  if (pc == NULL)
1387  return(1);
1388  Cudd_Ref(pc);
1389  nc = cuddZddSubset0(dd, f, pv);
1390  if (nc == NULL) {
1391  Cudd_RecursiveDerefZdd(dd, pc);
1392  return(1);
1393  }
1394  Cudd_Ref(nc);
1395 
1396  *f1 = cuddZddSubset0(dd, pc, nv);
1397  if (*f1 == NULL) {
1398  Cudd_RecursiveDerefZdd(dd, pc);
1399  Cudd_RecursiveDerefZdd(dd, nc);
1400  return(1);
1401  }
1402  Cudd_Ref(*f1);
1403  *f0 = cuddZddSubset1(dd, nc, nv);
1404  if (*f0 == NULL) {
1405  Cudd_RecursiveDerefZdd(dd, pc);
1406  Cudd_RecursiveDerefZdd(dd, nc);
1407  Cudd_RecursiveDerefZdd(dd, *f1);
1408  return(1);
1409  }
1410  Cudd_Ref(*f0);
1411 
1412  *fd = cuddZddSubset0(dd, nc, nv);
1413  if (*fd == NULL) {
1414  Cudd_RecursiveDerefZdd(dd, pc);
1415  Cudd_RecursiveDerefZdd(dd, nc);
1416  Cudd_RecursiveDerefZdd(dd, *f1);
1417  Cudd_RecursiveDerefZdd(dd, *f0);
1418  return(1);
1419  }
1420  Cudd_Ref(*fd);
1421  } else {
1422  pc = cuddZddSubset1(dd, f, nv);
1423  if (pc == NULL)
1424  return(1);
1425  Cudd_Ref(pc);
1426  nc = cuddZddSubset0(dd, f, nv);
1427  if (nc == NULL) {
1428  Cudd_RecursiveDerefZdd(dd, pc);
1429  return(1);
1430  }
1431  Cudd_Ref(nc);
1432 
1433  *f0 = cuddZddSubset0(dd, pc, pv);
1434  if (*f0 == NULL) {
1435  Cudd_RecursiveDerefZdd(dd, pc);
1436  Cudd_RecursiveDerefZdd(dd, nc);
1437  return(1);
1438  }
1439  Cudd_Ref(*f0);
1440  *f1 = cuddZddSubset1(dd, nc, pv);
1441  if (*f1 == NULL) {
1442  Cudd_RecursiveDerefZdd(dd, pc);
1443  Cudd_RecursiveDerefZdd(dd, nc);
1444  Cudd_RecursiveDerefZdd(dd, *f0);
1445  return(1);
1446  }
1447  Cudd_Ref(*f1);
1448 
1449  *fd = cuddZddSubset0(dd, nc, pv);
1450  if (*fd == NULL) {
1451  Cudd_RecursiveDerefZdd(dd, pc);
1452  Cudd_RecursiveDerefZdd(dd, nc);
1453  Cudd_RecursiveDerefZdd(dd, *f1);
1454  Cudd_RecursiveDerefZdd(dd, *f0);
1455  return(1);
1456  }
1457  Cudd_Ref(*fd);
1458  }
1459 
1460  Cudd_RecursiveDerefZdd(dd, pc);
1461  Cudd_RecursiveDerefZdd(dd, nc);
1462  Cudd_Deref(*f1);
1463  Cudd_Deref(*f0);
1464  Cudd_Deref(*fd);
1465  }
1466  return(0);
1467 
1468 } /* end of cuddZddGetCofactors3 */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
Definition: cudd.h:270
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
int * permZ
Definition: cuddInt.h:370
int cuddZddGetPosVarLevel(DdManager *dd, int index)
int cuddZddGetNegVarIndex(DdManager *dd, int index)
int cuddZddGetPosVarIndex(DdManager *dd, int index)
DdNode * cuddZddSubset1(DdManager *dd, DdNode *P, int var)
Definition: cuddZddSetop.c:870
int cuddZddGetNegVarLevel(DdManager *dd, int index)
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
DdNode * cuddZddSubset0(DdManager *dd, DdNode *P, int var)
Definition: cuddZddSetop.c:919
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddGetNegVarIndex()

int cuddZddGetNegVarIndex ( DdManager dd,
int  index 
)

Function********************************************************************

Synopsis [Returns the index of negative ZDD variable.]

Description [Returns the index of negative ZDD variable.]

SideEffects []

SeeAlso []

Definition at line 1582 of file cuddZddFuncs.c.

1585 {
1586  int nv = index | 0x1;
1587  return(nv);
1588 } /* end of cuddZddGetPosVarIndex */

◆ cuddZddGetNegVarLevel()

int cuddZddGetNegVarLevel ( DdManager dd,
int  index 
)

Function********************************************************************

Synopsis [Returns the level of negative ZDD variable.]

Description [Returns the level of negative ZDD variable.]

SideEffects []

SeeAlso []

Definition at line 1624 of file cuddZddFuncs.c.

1627 {
1628  int nv = cuddZddGetNegVarIndex(dd, index);
1629  return(dd->permZ[nv]);
1630 } /* end of cuddZddGetNegVarLevel */
int * permZ
Definition: cuddInt.h:370
int cuddZddGetNegVarIndex(DdManager *dd, int index)

◆ cuddZddGetNode()

DdNode* cuddZddGetNode ( DdManager zdd,
int  id,
DdNode T,
DdNode E 
)

Function********************************************************************

Synopsis [Wrapper for cuddUniqueInterZdd.]

Description [Wrapper for cuddUniqueInterZdd, which applies the ZDD reduction rule. Returns a pointer to the result node under normal conditions; NULL if reordering occurred or memory was exhausted.]

SideEffects [None]

SeeAlso [cuddUniqueInterZdd]

Definition at line 1050 of file cuddTable.c.

1055 {
1056  DdNode *node;
1057 
1058  if (T == DD_ZERO(zdd))
1059  return(E);
1060  node = cuddUniqueInterZdd(zdd, id, T, E);
1061  return(node);
1062 
1063 } /* end of cuddZddGetNode */
Definition: cudd.h:270
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1372
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddGetNodeIVO()

DdNode* cuddZddGetNodeIVO ( DdManager dd,
int  index,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Wrapper for cuddUniqueInterZdd that is independent of variable ordering.]

Description [Wrapper for cuddUniqueInterZdd that is independent of variable ordering (IVO). This function does not require parameter index to precede the indices of the top nodes of g and h in the variable order. Returns a pointer to the result node under normal conditions; NULL if reordering occurred or memory was exhausted.]

SideEffects [None]

SeeAlso [cuddZddGetNode cuddZddIsop]

Definition at line 1083 of file cuddTable.c.

1088 {
1089  DdNode *f, *r, *t;
1090  DdNode *zdd_one = DD_ONE(dd);
1091  DdNode *zdd_zero = DD_ZERO(dd);
1092 
1093  f = cuddUniqueInterZdd(dd, index, zdd_one, zdd_zero);
1094  if (f == NULL) {
1095  return(NULL);
1096  }
1097  cuddRef(f);
1098  t = cuddZddProduct(dd, f, g);
1099  if (t == NULL) {
1100  Cudd_RecursiveDerefZdd(dd, f);
1101  return(NULL);
1102  }
1103  cuddRef(t);
1104  Cudd_RecursiveDerefZdd(dd, f);
1105  r = cuddZddUnion(dd, t, h);
1106  if (r == NULL) {
1107  Cudd_RecursiveDerefZdd(dd, t);
1108  return(NULL);
1109  }
1110  cuddRef(r);
1111  Cudd_RecursiveDerefZdd(dd, t);
1112 
1113  cuddDeref(r);
1114  return(r);
1115 
1116 } /* end of cuddZddGetNodeIVO */
#define cuddRef(n)
Definition: cuddInt.h:557
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
DdNode * cuddZddProduct(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddZddFuncs.c:376
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:549
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1372
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddGetPosVarIndex()

int cuddZddGetPosVarIndex ( DdManager dd,
int  index 
)

Function********************************************************************

Synopsis [Returns the index of positive ZDD variable.]

Description [Returns the index of positive ZDD variable.]

SideEffects []

SeeAlso []

Definition at line 1561 of file cuddZddFuncs.c.

1564 {
1565  int pv = (index >> 1) << 1;
1566  return(pv);
1567 } /* end of cuddZddGetPosVarIndex */

◆ cuddZddGetPosVarLevel()

int cuddZddGetPosVarLevel ( DdManager dd,
int  index 
)

Function********************************************************************

Synopsis [Returns the level of positive ZDD variable.]

Description [Returns the level of positive ZDD variable.]

SideEffects []

SeeAlso []

Definition at line 1603 of file cuddZddFuncs.c.

1606 {
1607  int pv = cuddZddGetPosVarIndex(dd, index);
1608  return(dd->permZ[pv]);
1609 } /* end of cuddZddGetPosVarLevel */
int * permZ
Definition: cuddInt.h:370
int cuddZddGetPosVarIndex(DdManager *dd, int index)

◆ cuddZddInitUniv()

int cuddZddInitUniv ( DdManager zdd)

Function********************************************************************

Synopsis [Initializes the ZDD universe.]

Description [Initializes the ZDD universe. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddZddFreeUniv]

Definition at line 245 of file cuddInit.c.

247 {
248  DdNode *p, *res;
249  int i;
250 
251  zdd->univ = ALLOC(DdNodePtr, zdd->sizeZ);
252  if (zdd->univ == NULL) {
253  zdd->errorCode = CUDD_MEMORY_OUT;
254  return(0);
255  }
256 
257  res = DD_ONE(zdd);
258  cuddRef(res);
259  for (i = zdd->sizeZ - 1; i >= 0; i--) {
260  unsigned int index = zdd->invpermZ[i];
261  p = res;
262  res = cuddUniqueInterZdd(zdd, index, p, p);
263  if (res == NULL) {
264  Cudd_RecursiveDerefZdd(zdd,p);
265  FREE(zdd->univ);
266  return(0);
267  }
268  cuddRef(res);
269  cuddDeref(p);
270  zdd->univ[i] = res;
271  }
272 
273 #ifdef DD_VERBOSE
274  cuddZddP(zdd, zdd->univ[0]);
275 #endif
276 
277  return(1);
278 
279 } /* end of cuddZddInitUniv */
#define cuddRef(n)
Definition: cuddInt.h:557
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
int * invpermZ
Definition: cuddInt.h:372
#define ALLOC(type, num)
Definition: util.h:76
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1372
int sizeZ
Definition: cuddInt.h:346
#define DD_ONE(dd)
Definition: cuddInt.h:864
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
int cuddZddP(DdManager *zdd, DdNode *f)
DdNode ** univ
Definition: cuddInt.h:375

◆ cuddZddIntersect()

DdNode* cuddZddIntersect ( DdManager zdd,
DdNode P,
DdNode Q 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddIntersect.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 638 of file cuddZddSetop.c.

642 {
643  int p_top, q_top;
644  DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
645  DdManager *table = zdd;
646 
647  statLine(zdd);
648  if (P == empty)
649  return(empty);
650  if (Q == empty)
651  return(empty);
652  if (P == Q)
653  return(P);
654 
655  /* Check cache. */
656  res = cuddCacheLookup2Zdd(table, cuddZddIntersect, P, Q);
657  if (res != NULL)
658  return(res);
659 
660  if (cuddIsConstant(P))
661  p_top = P->index;
662  else
663  p_top = zdd->permZ[P->index];
664  if (cuddIsConstant(Q))
665  q_top = Q->index;
666  else
667  q_top = zdd->permZ[Q->index];
668  if (p_top < q_top) {
669  res = cuddZddIntersect(zdd, cuddE(P), Q);
670  if (res == NULL) return(NULL);
671  } else if (p_top > q_top) {
672  res = cuddZddIntersect(zdd, P, cuddE(Q));
673  if (res == NULL) return(NULL);
674  } else {
675  t = cuddZddIntersect(zdd, cuddT(P), cuddT(Q));
676  if (t == NULL) return(NULL);
677  cuddRef(t);
678  e = cuddZddIntersect(zdd, cuddE(P), cuddE(Q));
679  if (e == NULL) {
680  Cudd_RecursiveDerefZdd(table, t);
681  return(NULL);
682  }
683  cuddRef(e);
684  res = cuddZddGetNode(zdd, P->index, t, e);
685  if (res == NULL) {
686  Cudd_RecursiveDerefZdd(table, t);
687  Cudd_RecursiveDerefZdd(table, e);
688  return(NULL);
689  }
690  cuddDeref(t);
691  cuddDeref(e);
692  }
693 
694  cuddCacheInsert2(table, cuddZddIntersect, P, Q, res);
695 
696  return(res);
697 
698 } /* end of cuddZddIntersect */
#define cuddRef(n)
Definition: cuddInt.h:557
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1050
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:638
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddCacheLookup2Zdd(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * empty
Definition: cuddZddLin.c:94
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddIsop()

DdNode* cuddZddIsop ( DdManager dd,
DdNode L,
DdNode U,
DdNode **  zdd_I 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddIsop.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddIsop]

Definition at line 231 of file cuddZddIsop.c.

236 {
237  DdNode *one = DD_ONE(dd);
238  DdNode *zero = Cudd_Not(one);
239  DdNode *zdd_one = DD_ONE(dd);
240  DdNode *zdd_zero = DD_ZERO(dd);
241  int v, top_l, top_u;
242  DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud;
243  DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1;
244  DdNode *Isub0, *Isub1, *Id;
245  DdNode *zdd_Isub0, *zdd_Isub1, *zdd_Id;
246  DdNode *x;
247  DdNode *term0, *term1, *sum;
248  DdNode *Lv, *Uv, *Lnv, *Unv;
249  DdNode *r, *y, *z;
250  int index;
251  DD_CTFP cacheOp;
252 
253  statLine(dd);
254  if (L == zero) {
255  *zdd_I = zdd_zero;
256  return(zero);
257  }
258  if (U == one) {
259  *zdd_I = zdd_one;
260  return(one);
261  }
262 
263  if (U == zero || L == one) {
264  printf("*** ERROR : illegal condition for ISOP (U < L).\n");
265  exit(1);
266  }
267 
268  /* Check the cache. We store two results for each recursive call.
269  ** One is the BDD, and the other is the ZDD. Both are needed.
270  ** Hence we need a double hit in the cache to terminate the
271  ** recursion. Clearly, collisions may evict only one of the two
272  ** results. */
273  cacheOp = (DD_CTFP) cuddZddIsop;
274  r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
275  if (r) {
276  *zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U);
277  if (*zdd_I)
278  return(r);
279  else {
280  /* The BDD result may have been dead. In that case
281  ** cuddCacheLookup2 would have called cuddReclaim,
282  ** whose effects we now have to undo. */
283  cuddRef(r);
284  Cudd_RecursiveDeref(dd, r);
285  }
286  }
287 
288  top_l = dd->perm[Cudd_Regular(L)->index];
289  top_u = dd->perm[Cudd_Regular(U)->index];
290  v = ddMin(top_l, top_u);
291 
292  /* Compute cofactors. */
293  if (top_l == v) {
294  index = Cudd_Regular(L)->index;
295  Lv = Cudd_T(L);
296  Lnv = Cudd_E(L);
297  if (Cudd_IsComplement(L)) {
298  Lv = Cudd_Not(Lv);
299  Lnv = Cudd_Not(Lnv);
300  }
301  }
302  else {
303  index = Cudd_Regular(U)->index;
304  Lv = Lnv = L;
305  }
306 
307  if (top_u == v) {
308  Uv = Cudd_T(U);
309  Unv = Cudd_E(U);
310  if (Cudd_IsComplement(U)) {
311  Uv = Cudd_Not(Uv);
312  Unv = Cudd_Not(Unv);
313  }
314  }
315  else {
316  Uv = Unv = U;
317  }
318 
319  Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
320  if (Lsub0 == NULL)
321  return(NULL);
322  Cudd_Ref(Lsub0);
323  Usub0 = Unv;
324  Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv));
325  if (Lsub1 == NULL) {
326  Cudd_RecursiveDeref(dd, Lsub0);
327  return(NULL);
328  }
329  Cudd_Ref(Lsub1);
330  Usub1 = Uv;
331 
332  Isub0 = cuddZddIsop(dd, Lsub0, Usub0, &zdd_Isub0);
333  if (Isub0 == NULL) {
334  Cudd_RecursiveDeref(dd, Lsub0);
335  Cudd_RecursiveDeref(dd, Lsub1);
336  return(NULL);
337  }
338  /*
339  if ((!cuddIsConstant(Cudd_Regular(Isub0))) &&
340  (Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 ||
341  dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) {
342  printf("*** ERROR : illegal permutation in ZDD. ***\n");
343  }
344  */
345  Cudd_Ref(Isub0);
346  Cudd_Ref(zdd_Isub0);
347  Isub1 = cuddZddIsop(dd, Lsub1, Usub1, &zdd_Isub1);
348  if (Isub1 == NULL) {
349  Cudd_RecursiveDeref(dd, Lsub0);
350  Cudd_RecursiveDeref(dd, Lsub1);
351  Cudd_RecursiveDeref(dd, Isub0);
352  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
353  return(NULL);
354  }
355  /*
356  if ((!cuddIsConstant(Cudd_Regular(Isub1))) &&
357  (Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 ||
358  dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) {
359  printf("*** ERROR : illegal permutation in ZDD. ***\n");
360  }
361  */
362  Cudd_Ref(Isub1);
363  Cudd_Ref(zdd_Isub1);
364  Cudd_RecursiveDeref(dd, Lsub0);
365  Cudd_RecursiveDeref(dd, Lsub1);
366 
367  Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0));
368  if (Lsuper0 == NULL) {
369  Cudd_RecursiveDeref(dd, Isub0);
370  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
371  Cudd_RecursiveDeref(dd, Isub1);
372  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
373  return(NULL);
374  }
375  Cudd_Ref(Lsuper0);
376  Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1));
377  if (Lsuper1 == NULL) {
378  Cudd_RecursiveDeref(dd, Isub0);
379  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
380  Cudd_RecursiveDeref(dd, Isub1);
381  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
382  Cudd_RecursiveDeref(dd, Lsuper0);
383  return(NULL);
384  }
385  Cudd_Ref(Lsuper1);
386  Usuper0 = Unv;
387  Usuper1 = Uv;
388 
389  /* Ld = Lsuper0 + Lsuper1 */
390  Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1));
391  if (Ld == NULL) {
392  Cudd_RecursiveDeref(dd, Isub0);
393  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
394  Cudd_RecursiveDeref(dd, Isub1);
395  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
396  Cudd_RecursiveDeref(dd, Lsuper0);
397  Cudd_RecursiveDeref(dd, Lsuper1);
398  return(NULL);
399  }
400  Ld = Cudd_Not(Ld);
401  Cudd_Ref(Ld);
402  /* Ud = Usuper0 * Usuper1 */
403  Ud = cuddBddAndRecur(dd, Usuper0, Usuper1);
404  if (Ud == NULL) {
405  Cudd_RecursiveDeref(dd, Isub0);
406  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
407  Cudd_RecursiveDeref(dd, Isub1);
408  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
409  Cudd_RecursiveDeref(dd, Lsuper0);
410  Cudd_RecursiveDeref(dd, Lsuper1);
411  Cudd_RecursiveDeref(dd, Ld);
412  return(NULL);
413  }
414  Cudd_Ref(Ud);
415  Cudd_RecursiveDeref(dd, Lsuper0);
416  Cudd_RecursiveDeref(dd, Lsuper1);
417 
418  Id = cuddZddIsop(dd, Ld, Ud, &zdd_Id);
419  if (Id == NULL) {
420  Cudd_RecursiveDeref(dd, Isub0);
421  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
422  Cudd_RecursiveDeref(dd, Isub1);
423  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
424  Cudd_RecursiveDeref(dd, Ld);
425  Cudd_RecursiveDeref(dd, Ud);
426  return(NULL);
427  }
428  /*
429  if ((!cuddIsConstant(Cudd_Regular(Id))) &&
430  (Cudd_Regular(Id)->index != zdd_Id->index / 2 ||
431  dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) {
432  printf("*** ERROR : illegal permutation in ZDD. ***\n");
433  }
434  */
435  Cudd_Ref(Id);
436  Cudd_Ref(zdd_Id);
437  Cudd_RecursiveDeref(dd, Ld);
438  Cudd_RecursiveDeref(dd, Ud);
439 
440  x = cuddUniqueInter(dd, index, one, zero);
441  if (x == NULL) {
442  Cudd_RecursiveDeref(dd, Isub0);
443  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
444  Cudd_RecursiveDeref(dd, Isub1);
445  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
446  Cudd_RecursiveDeref(dd, Id);
447  Cudd_RecursiveDerefZdd(dd, zdd_Id);
448  return(NULL);
449  }
450  Cudd_Ref(x);
451  /* term0 = x * Isub0 */
452  term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0);
453  if (term0 == NULL) {
454  Cudd_RecursiveDeref(dd, Isub0);
455  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
456  Cudd_RecursiveDeref(dd, Isub1);
457  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
458  Cudd_RecursiveDeref(dd, Id);
459  Cudd_RecursiveDerefZdd(dd, zdd_Id);
460  Cudd_RecursiveDeref(dd, x);
461  return(NULL);
462  }
463  Cudd_Ref(term0);
464  Cudd_RecursiveDeref(dd, Isub0);
465  /* term1 = x * Isub1 */
466  term1 = cuddBddAndRecur(dd, x, Isub1);
467  if (term1 == NULL) {
468  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
469  Cudd_RecursiveDeref(dd, Isub1);
470  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
471  Cudd_RecursiveDeref(dd, Id);
472  Cudd_RecursiveDerefZdd(dd, zdd_Id);
473  Cudd_RecursiveDeref(dd, x);
474  Cudd_RecursiveDeref(dd, term0);
475  return(NULL);
476  }
477  Cudd_Ref(term1);
478  Cudd_RecursiveDeref(dd, x);
479  Cudd_RecursiveDeref(dd, Isub1);
480  /* sum = term0 + term1 */
481  sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1));
482  if (sum == NULL) {
483  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
484  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
485  Cudd_RecursiveDeref(dd, Id);
486  Cudd_RecursiveDerefZdd(dd, zdd_Id);
487  Cudd_RecursiveDeref(dd, term0);
488  Cudd_RecursiveDeref(dd, term1);
489  return(NULL);
490  }
491  sum = Cudd_Not(sum);
492  Cudd_Ref(sum);
493  Cudd_RecursiveDeref(dd, term0);
494  Cudd_RecursiveDeref(dd, term1);
495  /* r = sum + Id */
496  r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id));
497  r = Cudd_NotCond(r, r != NULL);
498  if (r == NULL) {
499  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
500  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
501  Cudd_RecursiveDeref(dd, Id);
502  Cudd_RecursiveDerefZdd(dd, zdd_Id);
503  Cudd_RecursiveDeref(dd, sum);
504  return(NULL);
505  }
506  Cudd_Ref(r);
507  Cudd_RecursiveDeref(dd, sum);
508  Cudd_RecursiveDeref(dd, Id);
509 
510  if (zdd_Isub0 != zdd_zero) {
511  z = cuddZddGetNodeIVO(dd, index * 2 + 1, zdd_Isub0, zdd_Id);
512  if (z == NULL) {
513  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
514  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
515  Cudd_RecursiveDerefZdd(dd, zdd_Id);
516  Cudd_RecursiveDeref(dd, r);
517  return(NULL);
518  }
519  }
520  else {
521  z = zdd_Id;
522  }
523  Cudd_Ref(z);
524  if (zdd_Isub1 != zdd_zero) {
525  y = cuddZddGetNodeIVO(dd, index * 2, zdd_Isub1, z);
526  if (y == NULL) {
527  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
528  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
529  Cudd_RecursiveDerefZdd(dd, zdd_Id);
530  Cudd_RecursiveDeref(dd, r);
531  Cudd_RecursiveDerefZdd(dd, z);
532  return(NULL);
533  }
534  }
535  else
536  y = z;
537  Cudd_Ref(y);
538 
539  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
540  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
541  Cudd_RecursiveDerefZdd(dd, zdd_Id);
542  Cudd_RecursiveDerefZdd(dd, z);
543 
544  cuddCacheInsert2(dd, cuddBddIsop, L, U, r);
545  cuddCacheInsert2(dd, cacheOp, L, U, y);
546 
547  Cudd_Deref(r);
548  Cudd_Deref(y);
549  *zdd_I = y;
550  /*
551  if (Cudd_Regular(r)->index != y->index / 2) {
552  printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n");
553  }
554  */
555  return(r);
556 
557 } /* end of cuddZddIsop */
DdNode * cuddZddGetNodeIVO(DdManager *dd, int index, DdNode *g, DdNode *h)
Definition: cuddTable.c:1083
#define cuddRef(n)
Definition: cuddInt.h:557
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
#define Cudd_T(node)
Definition: cudd.h:427
VOID_OR_INT exit()
#define Cudd_E(node)
Definition: cudd.h:442
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
DdNode * cuddCacheLookup2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
#define Cudd_Regular(node)
Definition: cudd.h:384
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddZddIsop(DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)
Definition: cuddZddIsop.c:231
static DdNode * one
Definition: cuddSat.c:105
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:308
#define ddMin(x, y)
Definition: cuddInt.h:771
DdNode * cuddCacheLookup2Zdd(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:995
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
static DdNode * zero
Definition: cuddSat.c:105
DdNode * cuddBddIsop(DdManager *dd, DdNode *L, DdNode *U)
Definition: cuddZddIsop.c:572
#define Cudd_NotCond(node, c)
Definition: cudd.h:370
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1137
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddIte()

DdNode* cuddZddIte ( DdManager dd,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddIte.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 423 of file cuddZddSetop.c.

428 {
429  DdNode *tautology, *empty;
430  DdNode *r,*Gv,*Gvn,*Hv,*Hvn,*t,*e;
431  unsigned int topf,topg,toph,v,top;
432  int index;
433 
434  statLine(dd);
435  /* Trivial cases. */
436  /* One variable cases. */
437  if (f == (empty = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
438  return(h);
439  }
440  topf = cuddIZ(dd,f->index);
441  topg = cuddIZ(dd,g->index);
442  toph = cuddIZ(dd,h->index);
443  v = ddMin(topg,toph);
444  top = ddMin(topf,v);
445 
446  tautology = (top == CUDD_MAXINDEX) ? DD_ONE(dd) : dd->univ[top];
447  if (f == tautology) { /* ITE(1,G,H) = G */
448  return(g);
449  }
450 
451  /* From now on, f is known to not be a constant. */
452  zddVarToConst(f,&g,&h,tautology,empty);
453 
454  /* Check remaining one variable cases. */
455  if (g == h) { /* ITE(F,G,G) = G */
456  return(g);
457  }
458 
459  if (g == tautology) { /* ITE(F,1,0) = F */
460  if (h == empty) return(f);
461  }
462 
463  /* Check cache. */
464  r = cuddCacheLookupZdd(dd,DD_ZDD_ITE_TAG,f,g,h);
465  if (r != NULL) {
466  return(r);
467  }
468 
469  /* Recompute these because they may have changed in zddVarToConst. */
470  topg = cuddIZ(dd,g->index);
471  toph = cuddIZ(dd,h->index);
472  v = ddMin(topg,toph);
473 
474  if (topf < v) {
475  r = cuddZddIte(dd,cuddE(f),g,h);
476  if (r == NULL) return(NULL);
477  } else if (topf > v) {
478  if (topg > v) {
479  Gvn = g;
480  index = h->index;
481  } else {
482  Gvn = cuddE(g);
483  index = g->index;
484  }
485  if (toph > v) {
486  Hv = empty; Hvn = h;
487  } else {
488  Hv = cuddT(h); Hvn = cuddE(h);
489  }
490  e = cuddZddIte(dd,f,Gvn,Hvn);
491  if (e == NULL) return(NULL);
492  cuddRef(e);
493  r = cuddZddGetNode(dd,index,Hv,e);
494  if (r == NULL) {
496  return(NULL);
497  }
498  cuddDeref(e);
499  } else {
500  index = f->index;
501  if (topg > v) {
502  Gv = empty; Gvn = g;
503  } else {
504  Gv = cuddT(g); Gvn = cuddE(g);
505  }
506  if (toph > v) {
507  Hv = empty; Hvn = h;
508  } else {
509  Hv = cuddT(h); Hvn = cuddE(h);
510  }
511  e = cuddZddIte(dd,cuddE(f),Gvn,Hvn);
512  if (e == NULL) return(NULL);
513  cuddRef(e);
514  t = cuddZddIte(dd,cuddT(f),Gv,Hv);
515  if (t == NULL) {
517  return(NULL);
518  }
519  cuddRef(t);
520  r = cuddZddGetNode(dd,index,t,e);
521  if (r == NULL) {
524  return(NULL);
525  }
526  cuddDeref(t);
527  cuddDeref(e);
528  }
529 
530  cuddCacheInsert(dd,DD_ZDD_ITE_TAG,f,g,h,r);
531 
532  return(r);
533 
534 } /* end of cuddZddIte */
DdNode * cuddZddIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddZddSetop.c:423
#define cuddRef(n)
Definition: cuddInt.h:557
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
#define cuddDeref(n)
Definition: cuddInt.h:577
#define cuddIZ(dd, index)
Definition: cuddInt.h:677
Definition: cudd.h:270
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1050
#define statLine(dd)
Definition: cuddInt.h:990
static void zddVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty)
DdNode * cuddCacheLookupZdd(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:409
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#define DD_ZDD_ITE_TAG
Definition: cuddInt.h:184
DdHalfWord index
Definition: cudd.h:271
#define CUDD_MAXINDEX
Definition: cudd.h:108
#define cuddE(node)
Definition: cuddInt.h:625
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:217
static DdNode * empty
Definition: cuddZddLin.c:94
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode ** univ
Definition: cuddInt.h:375
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddLinearSifting()

int cuddZddLinearSifting ( DdManager table,
int  lower,
int  upper 
)

AutomaticEnd Function********************************************************************

Synopsis [Implementation of the linear sifting algorithm for ZDDs.]

Description [Implementation of the linear sifting algorithm for ZDDs. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique table.
  2. Sift the variable up and down and applies the XOR transformation, remembering each time the total size of the DD heap.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 152 of file cuddZddLin.c.

156 {
157  int i;
158  int *var;
159  int size;
160  int x;
161  int result;
162 #ifdef DD_STATS
163  int previousSize;
164 #endif
165 
166  size = table->sizeZ;
167  empty = table->zero;
168 
169  /* Find order in which to sift variables. */
170  var = NULL;
171  zdd_entry = ALLOC(int, size);
172  if (zdd_entry == NULL) {
173  table->errorCode = CUDD_MEMORY_OUT;
174  goto cuddZddSiftingOutOfMem;
175  }
176  var = ALLOC(int, size);
177  if (var == NULL) {
178  table->errorCode = CUDD_MEMORY_OUT;
179  goto cuddZddSiftingOutOfMem;
180  }
181 
182  for (i = 0; i < size; i++) {
183  x = table->permZ[i];
184  zdd_entry[i] = table->subtableZ[x].keys;
185  var[i] = i;
186  }
187 
188  qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
189 
190  /* Now sift. */
191  for (i = 0; i < ddMin(table->siftMaxVar, size); i++) {
192  if (zddTotalNumberSwapping >= table->siftMaxSwap)
193  break;
194  if (util_cpu_time() - table->startTime > table->timeLimit) {
195  table->autoDynZ = 0; /* prevent further reordering */
196  break;
197  }
198  x = table->permZ[var[i]];
199  if (x < lower || x > upper) continue;
200 #ifdef DD_STATS
201  previousSize = table->keysZ;
202 #endif
203  result = cuddZddLinearAux(table, x, lower, upper);
204  if (!result)
205  goto cuddZddSiftingOutOfMem;
206 #ifdef DD_STATS
207  if (table->keysZ < (unsigned) previousSize) {
208  (void) fprintf(table->out,"-");
209  } else if (table->keysZ > (unsigned) previousSize) {
210  (void) fprintf(table->out,"+"); /* should never happen */
211  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]);
212  } else {
213  (void) fprintf(table->out,"=");
214  }
215  fflush(table->out);
216 #endif
217  }
218 
219  FREE(var);
220  FREE(zdd_entry);
221 
222  return(1);
223 
224 cuddZddSiftingOutOfMem:
225 
226  if (zdd_entry != NULL) FREE(zdd_entry);
227  if (var != NULL) FREE(var);
228 
229  return(0);
230 
231 } /* end of cuddZddLinearSifting */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:313
unsigned long startTime
Definition: cuddInt.h:426
DdNode * zero
Definition: cuddInt.h:330
int * permZ
Definition: cuddInt.h:370
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static int cuddZddLinearAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddZddLin.c:577
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: cpu_time.c:34
int siftMaxVar
Definition: cuddInt.h:395
int sizeZ
Definition: cuddInt.h:346
int autoDynZ
Definition: cuddInt.h:401
static int result
Definition: cuddGenetic.c:121
static DdNode * empty
Definition: cuddZddLin.c:94
unsigned int keysZ
Definition: cuddInt.h:354
int * zdd_entry
Definition: cuddZddReord.c:104
unsigned long timeLimit
Definition: cuddInt.h:427
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddZddReord.c:455
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
int zddTotalNumberSwapping
Definition: cuddZddReord.c:106
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddNextHigh()

int cuddZddNextHigh ( DdManager table,
int  x 
)

Function********************************************************************

Synopsis [Finds the next subtable with a larger index.]

Description [Finds the next subtable with a larger index. Returns the index.]

SideEffects [None]

SeeAlso []

Definition at line 409 of file cuddZddReord.c.

412 {
413  return(x + 1);
414 
415 } /* end of cuddZddNextHigh */

◆ cuddZddNextLow()

int cuddZddNextLow ( DdManager table,
int  x 
)

Function********************************************************************

Synopsis [Finds the next subtable with a smaller index.]

Description [Finds the next subtable with a smaller index. Returns the index.]

SideEffects [None]

SeeAlso []

Definition at line 431 of file cuddZddReord.c.

434 {
435  return(x - 1);
436 
437 } /* end of cuddZddNextLow */

◆ cuddZddP()

int cuddZddP ( DdManager zdd,
DdNode f 
)

◆ cuddZddProduct()

DdNode* cuddZddProduct ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddProduct.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddProduct]

Definition at line 376 of file cuddZddFuncs.c.

380 {
381  int v, top_f, top_g;
382  DdNode *tmp, *term1, *term2, *term3;
383  DdNode *f0, *f1, *fd, *g0, *g1, *gd;
384  DdNode *R0, *R1, *Rd, *N0, *N1;
385  DdNode *r;
386  DdNode *one = DD_ONE(dd);
387  DdNode *zero = DD_ZERO(dd);
388  int flag;
389  int pv, nv;
390 
391  statLine(dd);
392  if (f == zero || g == zero)
393  return(zero);
394  if (f == one)
395  return(g);
396  if (g == one)
397  return(f);
398 
399  top_f = dd->permZ[f->index];
400  top_g = dd->permZ[g->index];
401 
402  if (top_f > top_g)
403  return(cuddZddProduct(dd, g, f));
404 
405  /* Check cache */
406  r = cuddCacheLookup2Zdd(dd, cuddZddProduct, f, g);
407  if (r)
408  return(r);
409 
410  v = f->index; /* either yi or zi */
411  flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
412  if (flag == 1)
413  return(NULL);
414  Cudd_Ref(f1);
415  Cudd_Ref(f0);
416  Cudd_Ref(fd);
417  flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd);
418  if (flag == 1) {
419  Cudd_RecursiveDerefZdd(dd, f1);
420  Cudd_RecursiveDerefZdd(dd, f0);
421  Cudd_RecursiveDerefZdd(dd, fd);
422  return(NULL);
423  }
424  Cudd_Ref(g1);
425  Cudd_Ref(g0);
426  Cudd_Ref(gd);
427  pv = cuddZddGetPosVarIndex(dd, v);
428  nv = cuddZddGetNegVarIndex(dd, v);
429 
430  Rd = cuddZddProduct(dd, fd, gd);
431  if (Rd == NULL) {
432  Cudd_RecursiveDerefZdd(dd, f1);
433  Cudd_RecursiveDerefZdd(dd, f0);
434  Cudd_RecursiveDerefZdd(dd, fd);
435  Cudd_RecursiveDerefZdd(dd, g1);
436  Cudd_RecursiveDerefZdd(dd, g0);
437  Cudd_RecursiveDerefZdd(dd, gd);
438  return(NULL);
439  }
440  Cudd_Ref(Rd);
441 
442  term1 = cuddZddProduct(dd, f0, g0);
443  if (term1 == NULL) {
444  Cudd_RecursiveDerefZdd(dd, f1);
445  Cudd_RecursiveDerefZdd(dd, f0);
446  Cudd_RecursiveDerefZdd(dd, fd);
447  Cudd_RecursiveDerefZdd(dd, g1);
448  Cudd_RecursiveDerefZdd(dd, g0);
449  Cudd_RecursiveDerefZdd(dd, gd);
450  Cudd_RecursiveDerefZdd(dd, Rd);
451  return(NULL);
452  }
453  Cudd_Ref(term1);
454  term2 = cuddZddProduct(dd, f0, gd);
455  if (term2 == NULL) {
456  Cudd_RecursiveDerefZdd(dd, f1);
457  Cudd_RecursiveDerefZdd(dd, f0);
458  Cudd_RecursiveDerefZdd(dd, fd);
459  Cudd_RecursiveDerefZdd(dd, g1);
460  Cudd_RecursiveDerefZdd(dd, g0);
461  Cudd_RecursiveDerefZdd(dd, gd);
462  Cudd_RecursiveDerefZdd(dd, Rd);
463  Cudd_RecursiveDerefZdd(dd, term1);
464  return(NULL);
465  }
466  Cudd_Ref(term2);
467  term3 = cuddZddProduct(dd, fd, g0);
468  if (term3 == NULL) {
469  Cudd_RecursiveDerefZdd(dd, f1);
470  Cudd_RecursiveDerefZdd(dd, f0);
471  Cudd_RecursiveDerefZdd(dd, fd);
472  Cudd_RecursiveDerefZdd(dd, g1);
473  Cudd_RecursiveDerefZdd(dd, g0);
474  Cudd_RecursiveDerefZdd(dd, gd);
475  Cudd_RecursiveDerefZdd(dd, Rd);
476  Cudd_RecursiveDerefZdd(dd, term1);
477  Cudd_RecursiveDerefZdd(dd, term2);
478  return(NULL);
479  }
480  Cudd_Ref(term3);
481  Cudd_RecursiveDerefZdd(dd, f0);
482  Cudd_RecursiveDerefZdd(dd, g0);
483  tmp = cuddZddUnion(dd, term1, term2);
484  if (tmp == NULL) {
485  Cudd_RecursiveDerefZdd(dd, f1);
486  Cudd_RecursiveDerefZdd(dd, fd);
487  Cudd_RecursiveDerefZdd(dd, g1);
488  Cudd_RecursiveDerefZdd(dd, gd);
489  Cudd_RecursiveDerefZdd(dd, Rd);
490  Cudd_RecursiveDerefZdd(dd, term1);
491  Cudd_RecursiveDerefZdd(dd, term2);
492  Cudd_RecursiveDerefZdd(dd, term3);
493  return(NULL);
494  }
495  Cudd_Ref(tmp);
496  Cudd_RecursiveDerefZdd(dd, term1);
497  Cudd_RecursiveDerefZdd(dd, term2);
498  R0 = cuddZddUnion(dd, tmp, term3);
499  if (R0 == NULL) {
500  Cudd_RecursiveDerefZdd(dd, f1);
501  Cudd_RecursiveDerefZdd(dd, fd);
502  Cudd_RecursiveDerefZdd(dd, g1);
503  Cudd_RecursiveDerefZdd(dd, gd);
504  Cudd_RecursiveDerefZdd(dd, Rd);
505  Cudd_RecursiveDerefZdd(dd, term3);
506  Cudd_RecursiveDerefZdd(dd, tmp);
507  return(NULL);
508  }
509  Cudd_Ref(R0);
510  Cudd_RecursiveDerefZdd(dd, tmp);
511  Cudd_RecursiveDerefZdd(dd, term3);
512  N0 = cuddZddGetNode(dd, nv, R0, Rd); /* nv = zi */
513  if (N0 == NULL) {
514  Cudd_RecursiveDerefZdd(dd, f1);
515  Cudd_RecursiveDerefZdd(dd, fd);
516  Cudd_RecursiveDerefZdd(dd, g1);
517  Cudd_RecursiveDerefZdd(dd, gd);
518  Cudd_RecursiveDerefZdd(dd, Rd);
519  Cudd_RecursiveDerefZdd(dd, R0);
520  return(NULL);
521  }
522  Cudd_Ref(N0);
523  Cudd_RecursiveDerefZdd(dd, R0);
524  Cudd_RecursiveDerefZdd(dd, Rd);
525 
526  term1 = cuddZddProduct(dd, f1, g1);
527  if (term1 == NULL) {
528  Cudd_RecursiveDerefZdd(dd, f1);
529  Cudd_RecursiveDerefZdd(dd, fd);
530  Cudd_RecursiveDerefZdd(dd, g1);
531  Cudd_RecursiveDerefZdd(dd, gd);
532  Cudd_RecursiveDerefZdd(dd, N0);
533  return(NULL);
534  }
535  Cudd_Ref(term1);
536  term2 = cuddZddProduct(dd, f1, gd);
537  if (term2 == NULL) {
538  Cudd_RecursiveDerefZdd(dd, f1);
539  Cudd_RecursiveDerefZdd(dd, fd);
540  Cudd_RecursiveDerefZdd(dd, g1);
541  Cudd_RecursiveDerefZdd(dd, gd);
542  Cudd_RecursiveDerefZdd(dd, N0);
543  Cudd_RecursiveDerefZdd(dd, term1);
544  return(NULL);
545  }
546  Cudd_Ref(term2);
547  term3 = cuddZddProduct(dd, fd, g1);
548  if (term3 == NULL) {
549  Cudd_RecursiveDerefZdd(dd, f1);
550  Cudd_RecursiveDerefZdd(dd, fd);
551  Cudd_RecursiveDerefZdd(dd, g1);
552  Cudd_RecursiveDerefZdd(dd, gd);
553  Cudd_RecursiveDerefZdd(dd, N0);
554  Cudd_RecursiveDerefZdd(dd, term1);
555  Cudd_RecursiveDerefZdd(dd, term2);
556  return(NULL);
557  }
558  Cudd_Ref(term3);
559  Cudd_RecursiveDerefZdd(dd, f1);
560  Cudd_RecursiveDerefZdd(dd, g1);
561  Cudd_RecursiveDerefZdd(dd, fd);
562  Cudd_RecursiveDerefZdd(dd, gd);
563  tmp = cuddZddUnion(dd, term1, term2);
564  if (tmp == NULL) {
565  Cudd_RecursiveDerefZdd(dd, N0);
566  Cudd_RecursiveDerefZdd(dd, term1);
567  Cudd_RecursiveDerefZdd(dd, term2);
568  Cudd_RecursiveDerefZdd(dd, term3);
569  return(NULL);
570  }
571  Cudd_Ref(tmp);
572  Cudd_RecursiveDerefZdd(dd, term1);
573  Cudd_RecursiveDerefZdd(dd, term2);
574  R1 = cuddZddUnion(dd, tmp, term3);
575  if (R1 == NULL) {
576  Cudd_RecursiveDerefZdd(dd, N0);
577  Cudd_RecursiveDerefZdd(dd, term3);
578  Cudd_RecursiveDerefZdd(dd, tmp);
579  return(NULL);
580  }
581  Cudd_Ref(R1);
582  Cudd_RecursiveDerefZdd(dd, tmp);
583  Cudd_RecursiveDerefZdd(dd, term3);
584  N1 = cuddZddGetNode(dd, pv, R1, N0); /* pv = yi */
585  if (N1 == NULL) {
586  Cudd_RecursiveDerefZdd(dd, N0);
587  Cudd_RecursiveDerefZdd(dd, R1);
588  return(NULL);
589  }
590  Cudd_Ref(N1);
591  Cudd_RecursiveDerefZdd(dd, R1);
592  Cudd_RecursiveDerefZdd(dd, N0);
593 
594  cuddCacheInsert2(dd, cuddZddProduct, f, g, N1);
595  Cudd_Deref(N1);
596  return(N1);
597 
598 } /* end of cuddZddProduct */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
Definition: cudd.h:270
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1050
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
int * permZ
Definition: cuddInt.h:370
int cuddZddGetCofactors3(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddZddProduct(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddZddFuncs.c:376
static DdNode * one
Definition: cuddSat.c:105
int cuddZddGetNegVarIndex(DdManager *dd, int index)
int cuddZddGetPosVarIndex(DdManager *dd, int index)
DdNode * cuddCacheLookup2Zdd(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:549
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddSifting()

int cuddZddSifting ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [Implementation of Rudell's sifting algorithm.]

Description [Implementation of Rudell's sifting algorithm. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique table.
  2. Sift the variable up and down, remembering each time the total size of the DD heap.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 863 of file cuddZddReord.c.

867 {
868  int i;
869  int *var;
870  int size;
871  int x;
872  int result;
873 #ifdef DD_STATS
874  int previousSize;
875 #endif
876 
877  size = table->sizeZ;
878 
879  /* Find order in which to sift variables. */
880  var = NULL;
881  zdd_entry = ALLOC(int, size);
882  if (zdd_entry == NULL) {
883  table->errorCode = CUDD_MEMORY_OUT;
884  goto cuddZddSiftingOutOfMem;
885  }
886  var = ALLOC(int, size);
887  if (var == NULL) {
888  table->errorCode = CUDD_MEMORY_OUT;
889  goto cuddZddSiftingOutOfMem;
890  }
891 
892  for (i = 0; i < size; i++) {
893  x = table->permZ[i];
894  zdd_entry[i] = table->subtableZ[x].keys;
895  var[i] = i;
896  }
897 
898  qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
899 
900  /* Now sift. */
901  for (i = 0; i < ddMin(table->siftMaxVar, size); i++) {
902  if (zddTotalNumberSwapping >= table->siftMaxSwap)
903  break;
904  if (util_cpu_time() - table->startTime > table->timeLimit) {
905  table->autoDynZ = 0; /* prevent further reordering */
906  break;
907  }
908  x = table->permZ[var[i]];
909  if (x < lower || x > upper) continue;
910 #ifdef DD_STATS
911  previousSize = table->keysZ;
912 #endif
913  result = cuddZddSiftingAux(table, x, lower, upper);
914  if (!result)
915  goto cuddZddSiftingOutOfMem;
916 #ifdef DD_STATS
917  if (table->keysZ < (unsigned) previousSize) {
918  (void) fprintf(table->out,"-");
919  } else if (table->keysZ > (unsigned) previousSize) {
920  (void) fprintf(table->out,"+"); /* should never happen */
921  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]);
922  } else {
923  (void) fprintf(table->out,"=");
924  }
925  fflush(table->out);
926 #endif
927  }
928 
929  FREE(var);
930  FREE(zdd_entry);
931 
932  return(1);
933 
934 cuddZddSiftingOutOfMem:
935 
936  if (zdd_entry != NULL) FREE(zdd_entry);
937  if (var != NULL) FREE(var);
938 
939  return(0);
940 
941 } /* end of cuddZddSifting */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:313
unsigned long startTime
Definition: cuddInt.h:426
int * permZ
Definition: cuddInt.h:370
static int cuddZddSiftingAux(DdManager *table, int x, int x_low, int x_high)
int zddTotalNumberSwapping
Definition: cuddZddReord.c:106
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
#define ddMin(x, y)
Definition: cuddInt.h:771
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddZddReord.c:455
long util_cpu_time(void)
Definition: cpu_time.c:34
int siftMaxVar
Definition: cuddInt.h:395
int sizeZ
Definition: cuddInt.h:346
int autoDynZ
Definition: cuddInt.h:401
static int result
Definition: cuddGenetic.c:121
unsigned int keysZ
Definition: cuddInt.h:354
int * zdd_entry
Definition: cuddZddReord.c:104
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSubset0()

DdNode* cuddZddSubset0 ( DdManager dd,
DdNode P,
int  var 
)

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. cuddZddSubset0 performs the same function as Cudd_zddSubset0, but does not restart if reordering has taken place. Therefore it can be called from within a recursive procedure.]

SideEffects [None]

SeeAlso [cuddZddSubset1 Cudd_zddSubset0]

Definition at line 919 of file cuddZddSetop.c.

923 {
924  DdNode *zvar, *r;
925  DdNode *base, *empty;
926 
927  base = DD_ONE(dd);
928  empty = DD_ZERO(dd);
929 
930  zvar = cuddUniqueInterZdd(dd, var, base, empty);
931  if (zvar == NULL) {
932  return(NULL);
933  } else {
934  cuddRef(zvar);
935  r = zdd_subset0_aux(dd, P, zvar);
936  if (r == NULL) {
937  Cudd_RecursiveDerefZdd(dd, zvar);
938  return(NULL);
939  }
940  cuddRef(r);
941  Cudd_RecursiveDerefZdd(dd, zvar);
942  }
943 
944  cuddDeref(r);
945  return(r);
946 
947 } /* end of cuddZddSubset0 */
#define cuddRef(n)
Definition: cuddInt.h:557
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1372
static DdNode * zdd_subset0_aux(DdManager *zdd, DdNode *P, DdNode *zvar)
static DdNode * empty
Definition: cuddZddLin.c:94
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddSubset1()

DdNode* cuddZddSubset1 ( DdManager dd,
DdNode P,
int  var 
)

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. cuddZddSubset1 performs the same function as Cudd_zddSubset1, but does not restart if reordering has taken place. Therefore it can be called from within a recursive procedure.]

SideEffects [None]

SeeAlso [cuddZddSubset0 Cudd_zddSubset1]

Definition at line 870 of file cuddZddSetop.c.

874 {
875  DdNode *zvar, *r;
876  DdNode *base, *empty;
877 
878  base = DD_ONE(dd);
879  empty = DD_ZERO(dd);
880 
881  zvar = cuddUniqueInterZdd(dd, var, base, empty);
882  if (zvar == NULL) {
883  return(NULL);
884  } else {
885  cuddRef(zvar);
886  r = zdd_subset1_aux(dd, P, zvar);
887  if (r == NULL) {
888  Cudd_RecursiveDerefZdd(dd, zvar);
889  return(NULL);
890  }
891  cuddRef(r);
892  Cudd_RecursiveDerefZdd(dd, zvar);
893  }
894 
895  cuddDeref(r);
896  return(r);
897 
898 } /* end of cuddZddSubset1 */
#define cuddRef(n)
Definition: cuddInt.h:557
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
static DdNode * zdd_subset1_aux(DdManager *zdd, DdNode *P, DdNode *zvar)
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1372
static DdNode * empty
Definition: cuddZddLin.c:94
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddSwapInPlace()

int cuddZddSwapInPlace ( DdManager table,
int  x,
int  y 
)

Function********************************************************************

Synopsis [Swaps two adjacent variables.]

Description [Swaps two adjacent variables. It assumes that no dead nodes are present on entry to this procedure. The procedure then guarantees that no dead nodes will be present when it terminates. cuddZddSwapInPlace assumes that x < y. Returns the number of keys in the table if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 480 of file cuddZddReord.c.

484 {
485  DdNodePtr *xlist, *ylist;
486  int xindex, yindex;
487  int xslots, yslots;
488  int xshift, yshift;
489  int oldxkeys, oldykeys;
490  int newxkeys, newykeys;
491  int i;
492  int posn;
493  DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00;
494  DdNode *newf1, *newf0, *next;
495  DdNodePtr g, *lastP, *previousP;
496 
497 #ifdef DD_DEBUG
498  assert(x < y);
499  assert(cuddZddNextHigh(table,x) == y);
500  assert(table->subtableZ[x].keys != 0);
501  assert(table->subtableZ[y].keys != 0);
502  assert(table->subtableZ[x].dead == 0);
503  assert(table->subtableZ[y].dead == 0);
504 #endif
505 
507 
508  /* Get parameters of x subtable. */
509  xindex = table->invpermZ[x];
510  xlist = table->subtableZ[x].nodelist;
511  oldxkeys = table->subtableZ[x].keys;
512  xslots = table->subtableZ[x].slots;
513  xshift = table->subtableZ[x].shift;
514  newxkeys = 0;
515 
516  yindex = table->invpermZ[y];
517  ylist = table->subtableZ[y].nodelist;
518  oldykeys = table->subtableZ[y].keys;
519  yslots = table->subtableZ[y].slots;
520  yshift = table->subtableZ[y].shift;
521  newykeys = oldykeys;
522 
523  /* The nodes in the x layer that don't depend on y directly
524  ** will stay there; the others are put in a chain.
525  ** The chain is handled as a FIFO; g points to the beginning and
526  ** last points to the end.
527  */
528 
529  g = NULL;
530  lastP = &g;
531  for (i = 0; i < xslots; i++) {
532  previousP = &(xlist[i]);
533  f = *previousP;
534  while (f != NULL) {
535  next = f->next;
536  f1 = cuddT(f); f0 = cuddE(f);
537  if ((f1->index != (DdHalfWord) yindex) &&
538  (f0->index != (DdHalfWord) yindex)) { /* stays */
539  newxkeys++;
540  *previousP = f;
541  previousP = &(f->next);
542  } else {
543  f->index = yindex;
544  *lastP = f;
545  lastP = &(f->next);
546  }
547  f = next;
548  } /* while there are elements in the collision chain */
549  *previousP = NULL;
550  } /* for each slot of the x subtable */
551  *lastP = NULL;
552 
553 
554 #ifdef DD_COUNT
555  table->swapSteps += oldxkeys - newxkeys;
556 #endif
557  /* Take care of the x nodes that must be re-expressed.
558  ** They form a linked list pointed by g. Their index has been
559  ** changed to yindex already.
560  */
561  f = g;
562  while (f != NULL) {
563  next = f->next;
564  /* Find f1, f0, f11, f10, f01, f00. */
565  f1 = cuddT(f);
566  if ((int) f1->index == yindex) {
567  f11 = cuddT(f1); f10 = cuddE(f1);
568  } else {
569  f11 = empty; f10 = f1;
570  }
571  f0 = cuddE(f);
572  if ((int) f0->index == yindex) {
573  f01 = cuddT(f0); f00 = cuddE(f0);
574  } else {
575  f01 = empty; f00 = f0;
576  }
577 
578  /* Decrease ref count of f1. */
579  cuddSatDec(f1->ref);
580  /* Create the new T child. */
581  if (f11 == empty) {
582  if (f01 != empty) {
583  newf1 = f01;
584  cuddSatInc(newf1->ref);
585  }
586  /* else case was already handled when finding nodes
587  ** with both children below level y
588  */
589  } else {
590  /* Check xlist for triple (xindex, f11, f01). */
591  posn = ddHash(f11, f01, xshift);
592  /* For each element newf1 in collision list xlist[posn]. */
593  newf1 = xlist[posn];
594  while (newf1 != NULL) {
595  if (cuddT(newf1) == f11 && cuddE(newf1) == f01) {
596  cuddSatInc(newf1->ref);
597  break; /* match */
598  }
599  newf1 = newf1->next;
600  } /* while newf1 */
601  if (newf1 == NULL) { /* no match */
602  newf1 = cuddDynamicAllocNode(table);
603  if (newf1 == NULL)
604  goto zddSwapOutOfMem;
605  newf1->index = xindex; newf1->ref = 1;
606  cuddT(newf1) = f11;
607  cuddE(newf1) = f01;
608  /* Insert newf1 in the collision list xlist[pos];
609  ** increase the ref counts of f11 and f01
610  */
611  newxkeys++;
612  newf1->next = xlist[posn];
613  xlist[posn] = newf1;
614  cuddSatInc(f11->ref);
615  cuddSatInc(f01->ref);
616  }
617  }
618  cuddT(f) = newf1;
619 
620  /* Do the same for f0. */
621  /* Decrease ref count of f0. */
622  cuddSatDec(f0->ref);
623  /* Create the new E child. */
624  if (f10 == empty) {
625  newf0 = f00;
626  cuddSatInc(newf0->ref);
627  } else {
628  /* Check xlist for triple (xindex, f10, f00). */
629  posn = ddHash(f10, f00, xshift);
630  /* For each element newf0 in collision list xlist[posn]. */
631  newf0 = xlist[posn];
632  while (newf0 != NULL) {
633  if (cuddT(newf0) == f10 && cuddE(newf0) == f00) {
634  cuddSatInc(newf0->ref);
635  break; /* match */
636  }
637  newf0 = newf0->next;
638  } /* while newf0 */
639  if (newf0 == NULL) { /* no match */
640  newf0 = cuddDynamicAllocNode(table);
641  if (newf0 == NULL)
642  goto zddSwapOutOfMem;
643  newf0->index = xindex; newf0->ref = 1;
644  cuddT(newf0) = f10; cuddE(newf0) = f00;
645  /* Insert newf0 in the collision list xlist[posn];
646  ** increase the ref counts of f10 and f00.
647  */
648  newxkeys++;
649  newf0->next = xlist[posn];
650  xlist[posn] = newf0;
651  cuddSatInc(f10->ref);
652  cuddSatInc(f00->ref);
653  }
654  }
655  cuddE(f) = newf0;
656 
657  /* Insert the modified f in ylist.
658  ** The modified f does not already exists in ylist.
659  ** (Because of the uniqueness of the cofactors.)
660  */
661  posn = ddHash(newf1, newf0, yshift);
662  newykeys++;
663  f->next = ylist[posn];
664  ylist[posn] = f;
665  f = next;
666  } /* while f != NULL */
667 
668  /* GC the y layer. */
669 
670  /* For each node f in ylist. */
671  for (i = 0; i < yslots; i++) {
672  previousP = &(ylist[i]);
673  f = *previousP;
674  while (f != NULL) {
675  next = f->next;
676  if (f->ref == 0) {
677  cuddSatDec(cuddT(f)->ref);
678  cuddSatDec(cuddE(f)->ref);
679  cuddDeallocNode(table, f);
680  newykeys--;
681  } else {
682  *previousP = f;
683  previousP = &(f->next);
684  }
685  f = next;
686  } /* while f */
687  *previousP = NULL;
688  } /* for i */
689 
690  /* Set the appropriate fields in table. */
691  table->subtableZ[x].nodelist = ylist;
692  table->subtableZ[x].slots = yslots;
693  table->subtableZ[x].shift = yshift;
694  table->subtableZ[x].keys = newykeys;
695  table->subtableZ[x].maxKeys = yslots * DD_MAX_SUBTABLE_DENSITY;
696 
697  table->subtableZ[y].nodelist = xlist;
698  table->subtableZ[y].slots = xslots;
699  table->subtableZ[y].shift = xshift;
700  table->subtableZ[y].keys = newxkeys;
701  table->subtableZ[y].maxKeys = xslots * DD_MAX_SUBTABLE_DENSITY;
702 
703  table->permZ[xindex] = y; table->permZ[yindex] = x;
704  table->invpermZ[x] = yindex; table->invpermZ[y] = xindex;
705 
706  table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys;
707 
708  /* Update univ section; univ[x] remains the same. */
709  table->univ[y] = cuddT(table->univ[x]);
710 
711  return (table->keysZ);
712 
713 zddSwapOutOfMem:
714  (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n");
715 
716  return (0);
717 
718 } /* end of cuddZddSwapInPlace */
DdHalfWord ref
Definition: cudd.h:272
unsigned int keys
Definition: cuddInt.h:314
unsigned short DdHalfWord
Definition: cudd.h:259
#define ddHash(f, g, s)
Definition: cuddInt.h:696
Definition: cudd.h:270
int * invpermZ
Definition: cuddInt.h:372
#define assert(ex)
Definition: util.h:141
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:409
FILE * err
Definition: cuddInt.h:424
int * permZ
Definition: cuddInt.h:370
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
static DdNode * empty
Definition: cuddZddReord.c:108
int zddTotalNumberSwapping
Definition: cuddZddReord.c:106
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:273
unsigned int maxKeys
Definition: cuddInt.h:315
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:520
DdHalfWord index
Definition: cudd.h:271
unsigned int slots
Definition: cuddInt.h:313
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
int shift
Definition: cuddInt.h:312
unsigned int keysZ
Definition: cuddInt.h:354
#define cuddSatInc(x)
Definition: cuddInt.h:831
DdSubtable * subtableZ
Definition: cuddInt.h:350
DdNode ** univ
Definition: cuddInt.h:375

◆ cuddZddSwapping()

int cuddZddSwapping ( DdManager table,
int  lower,
int  upper,
Cudd_ReorderingType  heuristic 
)

Function********************************************************************

Synopsis [Reorders variables by a sequence of (non-adjacent) swaps.]

Description [Implementation of Plessier's algorithm that reorders variables by a sequence of (non-adjacent) swaps.

  1. Select two variables (RANDOM or HEURISTIC).
  2. Permute these variables.
  3. If the nodes have decreased accept the permutation.
  4. Otherwise reconstruct the original heap.
  5. Loop.

Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 742 of file cuddZddReord.c.

747 {
748  int i, j;
749  int max, keys;
750  int nvars;
751  int x, y;
752  int iterate;
753  int previousSize;
754  Move *moves, *move;
755  int pivot;
756  int modulo;
757  int result;
758 
759 #ifdef DD_DEBUG
760  /* Sanity check */
761  assert(lower >= 0 && upper < table->sizeZ && lower <= upper);
762 #endif
763 
764  nvars = upper - lower + 1;
765  iterate = nvars;
766 
767  for (i = 0; i < iterate; i++) {
768  if (heuristic == CUDD_REORDER_RANDOM_PIVOT) {
769  /* Find pivot <= id with maximum keys. */
770  for (max = -1, j = lower; j <= upper; j++) {
771  if ((keys = table->subtableZ[j].keys) > max) {
772  max = keys;
773  pivot = j;
774  }
775  }
776 
777  modulo = upper - pivot;
778  if (modulo == 0) {
779  y = pivot; /* y = nvars-1 */
780  } else {
781  /* y = random # from {pivot+1 .. nvars-1} */
782  y = pivot + 1 + (int) (Cudd_Random() % modulo);
783  }
784 
785  modulo = pivot - lower - 1;
786  if (modulo < 1) { /* if pivot = 1 or 0 */
787  x = lower;
788  } else {
789  do { /* x = random # from {0 .. pivot-2} */
790  x = (int) Cudd_Random() % modulo;
791  } while (x == y);
792  /* Is this condition really needed, since x and y
793  are in regions separated by pivot? */
794  }
795  } else {
796  x = (int) (Cudd_Random() % nvars) + lower;
797  do {
798  y = (int) (Cudd_Random() % nvars) + lower;
799  } while (x == y);
800  }
801 
802  previousSize = table->keysZ;
803  moves = zddSwapAny(table, x, y);
804  if (moves == NULL)
805  goto cuddZddSwappingOutOfMem;
806 
807  result = cuddZddSiftingBackward(table, moves, previousSize);
808  if (!result)
809  goto cuddZddSwappingOutOfMem;
810 
811  while (moves != NULL) {
812  move = moves->next;
813  cuddDeallocMove(table, moves);
814  moves = move;
815  }
816 #ifdef DD_STATS
817  if (table->keysZ < (unsigned) previousSize) {
818  (void) fprintf(table->out,"-");
819  } else if (table->keysZ > (unsigned) previousSize) {
820  (void) fprintf(table->out,"+"); /* should never happen */
821  } else {
822  (void) fprintf(table->out,"=");
823  }
824  fflush(table->out);
825 #endif
826  }
827 
828  return(1);
829 
830 cuddZddSwappingOutOfMem:
831  while (moves != NULL) {
832  move = moves->next;
833  cuddDeallocMove(table, moves);
834  moves = move;
835  }
836  return(0);
837 
838 } /* end of cuddZddSwapping */
unsigned int keys
Definition: cuddInt.h:314
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
long Cudd_Random(void)
Definition: cuddUtil.c:2710
FILE * out
Definition: cuddInt.h:423
static Move * zddSwapAny(DdManager *table, int x, int y)
Definition: cuddZddReord.c:961
static int cuddZddSiftingBackward(DdManager *table, Move *moves, int size)
struct Move * next
Definition: cuddInt.h:474
static int result
Definition: cuddGenetic.c:121
unsigned int keysZ
Definition: cuddInt.h:354
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSymmCheck()

int cuddZddSymmCheck ( DdManager table,
int  x,
int  y 
)

Function********************************************************************

Synopsis [Checks for symmetry of x and y.]

Description [Checks for symmetry of x and y. Ignores projection functions, unless they are isolated. Returns 1 in case of symmetry; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 193 of file cuddZddSymm.c.

197 {
198  int i;
199  DdNode *f, *f0, *f1, *f01, *f00, *f11, *f10;
200  int yindex;
201  int xsymmy = 1;
202  int xsymmyp = 1;
203  int arccount = 0;
204  int TotalRefCount = 0;
205  int symm_found;
206 
207  empty = table->zero;
208 
209  yindex = table->invpermZ[y];
210  for (i = table->subtableZ[x].slots - 1; i >= 0; i--) {
211  f = table->subtableZ[x].nodelist[i];
212  while (f != NULL) {
213  /* Find f1, f0, f11, f10, f01, f00 */
214  f1 = cuddT(f);
215  f0 = cuddE(f);
216  if ((int) f1->index == yindex) {
217  f11 = cuddT(f1);
218  f10 = cuddE(f1);
219  if (f10 != empty)
220  arccount++;
221  } else {
222  if ((int) f0->index != yindex) {
223  return(0); /* f bypasses layer y */
224  }
225  f11 = empty;
226  f10 = f1;
227  }
228  if ((int) f0->index == yindex) {
229  f01 = cuddT(f0);
230  f00 = cuddE(f0);
231  if (f00 != empty)
232  arccount++;
233  } else {
234  f01 = empty;
235  f00 = f0;
236  }
237  if (f01 != f10)
238  xsymmy = 0;
239  if (f11 != f00)
240  xsymmyp = 0;
241  if ((xsymmy == 0) && (xsymmyp == 0))
242  return(0);
243 
244  f = f->next;
245  } /* for each element of the collision list */
246  } /* for each slot of the subtable */
247 
248  /* Calculate the total reference counts of y
249  ** whose else arc is not empty.
250  */
251  for (i = table->subtableZ[y].slots - 1; i >= 0; i--) {
252  f = table->subtableZ[y].nodelist[i];
253  while (f != NIL(DdNode)) {
254  if (cuddE(f) != empty)
255  TotalRefCount += f->ref;
256  f = f->next;
257  }
258  }
259 
260  symm_found = (arccount == TotalRefCount);
261 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
262  if (symm_found) {
263  int xindex = table->invpermZ[x];
264  (void) fprintf(table->out,
265  "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n",
266  xindex,yindex,x,y);
267  }
268 #endif
269 
270  return(symm_found);
271 
272 } /* end cuddZddSymmCheck */
DdHalfWord ref
Definition: cudd.h:272
Definition: cudd.h:270
int * invpermZ
Definition: cuddInt.h:372
DdNode * zero
Definition: cuddInt.h:330
#define NIL(type)
Definition: util.h:44
static DdNode * empty
Definition: cuddZddSymm.c:99
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:273
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:271
unsigned int slots
Definition: cuddInt.h:313
#define cuddE(node)
Definition: cuddInt.h:625
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSymmSifting()

int cuddZddSymmSifting ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [Symmetric sifting algorithm for ZDDs.]

Description [Symmetric sifting algorithm. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique subtable.
  2. Sift the variable up and down, remembering each time the total size of the ZDD heap and grouping variables that are symmetric.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 plus the number of symmetric variables if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddZddSymmSiftingConv]

Definition at line 298 of file cuddZddSymm.c.

302 {
303  int i;
304  int *var;
305  int nvars;
306  int x;
307  int result;
308  int symvars;
309  int symgroups;
310  int iteration;
311 #ifdef DD_STATS
312  int previousSize;
313 #endif
314 
315  nvars = table->sizeZ;
316 
317  /* Find order in which to sift variables. */
318  var = NULL;
319  zdd_entry = ALLOC(int, nvars);
320  if (zdd_entry == NULL) {
321  table->errorCode = CUDD_MEMORY_OUT;
322  goto cuddZddSymmSiftingOutOfMem;
323  }
324  var = ALLOC(int, nvars);
325  if (var == NULL) {
326  table->errorCode = CUDD_MEMORY_OUT;
327  goto cuddZddSymmSiftingOutOfMem;
328  }
329 
330  for (i = 0; i < nvars; i++) {
331  x = table->permZ[i];
332  zdd_entry[i] = table->subtableZ[x].keys;
333  var[i] = i;
334  }
335 
336  qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
337 
338  /* Initialize the symmetry of each subtable to itself. */
339  for (i = lower; i <= upper; i++)
340  table->subtableZ[i].next = i;
341 
342  iteration = ddMin(table->siftMaxVar, nvars);
343  for (i = 0; i < iteration; i++) {
344  if (zddTotalNumberSwapping >= table->siftMaxSwap)
345  break;
346  if (util_cpu_time() - table->startTime > table->timeLimit) {
347  table->autoDynZ = 0; /* prevent further reordering */
348  break;
349  }
350  x = table->permZ[var[i]];
351 #ifdef DD_STATS
352  previousSize = table->keysZ;
353 #endif
354  if (x < lower || x > upper) continue;
355  if (table->subtableZ[x].next == (unsigned) x) {
356  result = cuddZddSymmSiftingAux(table, x, lower, upper);
357  if (!result)
358  goto cuddZddSymmSiftingOutOfMem;
359 #ifdef DD_STATS
360  if (table->keysZ < (unsigned) previousSize) {
361  (void) fprintf(table->out,"-");
362  } else if (table->keysZ > (unsigned) previousSize) {
363  (void) fprintf(table->out,"+");
364 #ifdef DD_VERBOSE
365  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]);
366 #endif
367  } else {
368  (void) fprintf(table->out,"=");
369  }
370  fflush(table->out);
371 #endif
372  }
373  }
374 
375  FREE(var);
376  FREE(zdd_entry);
377 
378  cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups);
379 
380 #ifdef DD_STATS
381  (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",symvars);
382  (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",symgroups);
383 #endif
384 
385  return(1+symvars);
386 
387 cuddZddSymmSiftingOutOfMem:
388 
389  if (zdd_entry != NULL)
390  FREE(zdd_entry);
391  if (var != NULL)
392  FREE(var);
393 
394  return(0);
395 
396 } /* end of cuddZddSymmSifting */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:313
unsigned long startTime
Definition: cuddInt.h:426
int * zdd_entry
Definition: cuddZddReord.c:104
int * permZ
Definition: cuddInt.h:370
int zddTotalNumberSwapping
Definition: cuddZddReord.c:106
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: cpu_time.c:34
int siftMaxVar
Definition: cuddInt.h:395
static void cuddZddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
Definition: cuddZddSymm.c:1679
int sizeZ
Definition: cuddInt.h:346
unsigned int next
Definition: cuddInt.h:317
int autoDynZ
Definition: cuddInt.h:401
static int result
Definition: cuddGenetic.c:121
unsigned int keysZ
Definition: cuddInt.h:354
static int cuddZddSymmSiftingAux(DdManager *table, int x, int x_low, int x_high)
Definition: cuddZddSymm.c:609
unsigned long timeLimit
Definition: cuddInt.h:427
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddZddReord.c:455
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSymmSiftingConv()

int cuddZddSymmSiftingConv ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [Symmetric sifting to convergence algorithm for ZDDs.]

Description [Symmetric sifting to convergence algorithm for ZDDs. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique subtable.
  2. Sift the variable up and down, remembering each time the total size of the ZDD heap and grouping variables that are symmetric.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.
  5. Repeat 1-4 until no further improvement.

Returns 1 plus the number of symmetric variables if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddZddSymmSifting]

Definition at line 423 of file cuddZddSymm.c.

427 {
428  int i;
429  int *var;
430  int nvars;
431  int initialSize;
432  int x;
433  int result;
434  int symvars;
435  int symgroups;
436  int classes;
437  int iteration;
438 #ifdef DD_STATS
439  int previousSize;
440 #endif
441 
442  initialSize = table->keysZ;
443 
444  nvars = table->sizeZ;
445 
446  /* Find order in which to sift variables. */
447  var = NULL;
448  zdd_entry = ALLOC(int, nvars);
449  if (zdd_entry == NULL) {
450  table->errorCode = CUDD_MEMORY_OUT;
451  goto cuddZddSymmSiftingConvOutOfMem;
452  }
453  var = ALLOC(int, nvars);
454  if (var == NULL) {
455  table->errorCode = CUDD_MEMORY_OUT;
456  goto cuddZddSymmSiftingConvOutOfMem;
457  }
458 
459  for (i = 0; i < nvars; i++) {
460  x = table->permZ[i];
461  zdd_entry[i] = table->subtableZ[x].keys;
462  var[i] = i;
463  }
464 
465  qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
466 
467  /* Initialize the symmetry of each subtable to itself
468  ** for first pass of converging symmetric sifting.
469  */
470  for (i = lower; i <= upper; i++)
471  table->subtableZ[i].next = i;
472 
473  iteration = ddMin(table->siftMaxVar, table->sizeZ);
474  for (i = 0; i < iteration; i++) {
475  if (zddTotalNumberSwapping >= table->siftMaxSwap)
476  break;
477  if (util_cpu_time() - table->startTime > table->timeLimit) {
478  table->autoDynZ = 0; /* prevent further reordering */
479  break;
480  }
481  x = table->permZ[var[i]];
482  if (x < lower || x > upper) continue;
483  /* Only sift if not in symmetry group already. */
484  if (table->subtableZ[x].next == (unsigned) x) {
485 #ifdef DD_STATS
486  previousSize = table->keysZ;
487 #endif
488  result = cuddZddSymmSiftingAux(table, x, lower, upper);
489  if (!result)
490  goto cuddZddSymmSiftingConvOutOfMem;
491 #ifdef DD_STATS
492  if (table->keysZ < (unsigned) previousSize) {
493  (void) fprintf(table->out,"-");
494  } else if (table->keysZ > (unsigned) previousSize) {
495  (void) fprintf(table->out,"+");
496 #ifdef DD_VERBOSE
497  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]);
498 #endif
499  } else {
500  (void) fprintf(table->out,"=");
501  }
502  fflush(table->out);
503 #endif
504  }
505  }
506 
507  /* Sifting now until convergence. */
508  while ((unsigned) initialSize > table->keysZ) {
509  initialSize = table->keysZ;
510 #ifdef DD_STATS
511  (void) fprintf(table->out,"\n");
512 #endif
513  /* Here we consider only one representative for each symmetry class. */
514  for (x = lower, classes = 0; x <= upper; x++, classes++) {
515  while ((unsigned) x < table->subtableZ[x].next)
516  x = table->subtableZ[x].next;
517  /* Here x is the largest index in a group.
518  ** Groups consists of adjacent variables.
519  ** Hence, the next increment of x will move it to a new group.
520  */
521  i = table->invpermZ[x];
522  zdd_entry[i] = table->subtableZ[x].keys;
523  var[classes] = i;
524  }
525 
526  qsort((void *)var,classes,sizeof(int),(DD_QSFP)cuddZddUniqueCompare);
527 
528  /* Now sift. */
529  iteration = ddMin(table->siftMaxVar, nvars);
530  for (i = 0; i < iteration; i++) {
531  if (zddTotalNumberSwapping >= table->siftMaxSwap)
532  break;
533  if (util_cpu_time() - table->startTime > table->timeLimit) {
534  table->autoDynZ = 0; /* prevent further reordering */
535  break;
536  }
537  x = table->permZ[var[i]];
538  if ((unsigned) x >= table->subtableZ[x].next) {
539 #ifdef DD_STATS
540  previousSize = table->keysZ;
541 #endif
542  result = cuddZddSymmSiftingConvAux(table, x, lower, upper);
543  if (!result)
544  goto cuddZddSymmSiftingConvOutOfMem;
545 #ifdef DD_STATS
546  if (table->keysZ < (unsigned) previousSize) {
547  (void) fprintf(table->out,"-");
548  } else if (table->keysZ > (unsigned) previousSize) {
549  (void) fprintf(table->out,"+");
550 #ifdef DD_VERBOSE
551  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]);
552 #endif
553  } else {
554  (void) fprintf(table->out,"=");
555  }
556  fflush(table->out);
557 #endif
558  }
559  } /* for */
560  }
561 
562  cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups);
563 
564 #ifdef DD_STATS
565  (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",
566  symvars);
567  (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",
568  symgroups);
569 #endif
570 
571  FREE(var);
572  FREE(zdd_entry);
573 
574  return(1+symvars);
575 
576 cuddZddSymmSiftingConvOutOfMem:
577 
578  if (zdd_entry != NULL)
579  FREE(zdd_entry);
580  if (var != NULL)
581  FREE(var);
582 
583  return(0);
584 
585 } /* end of cuddZddSymmSiftingConv */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:313
unsigned long startTime
Definition: cuddInt.h:426
int * invpermZ
Definition: cuddInt.h:372
int * zdd_entry
Definition: cuddZddReord.c:104
int * permZ
Definition: cuddInt.h:370
int zddTotalNumberSwapping
Definition: cuddZddReord.c:106
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: cpu_time.c:34
int siftMaxVar
Definition: cuddInt.h:395
static void cuddZddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
Definition: cuddZddSymm.c:1679
int sizeZ
Definition: cuddInt.h:346
unsigned int next
Definition: cuddInt.h:317
int autoDynZ
Definition: cuddInt.h:401
static int result
Definition: cuddGenetic.c:121
unsigned int keysZ
Definition: cuddInt.h:354
static int cuddZddSymmSiftingAux(DdManager *table, int x, int x_low, int x_high)
Definition: cuddZddSymm.c:609
static int cuddZddSymmSiftingConvAux(DdManager *table, int x, int x_low, int x_high)
Definition: cuddZddSymm.c:949
unsigned long timeLimit
Definition: cuddInt.h:427
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddZddReord.c:455
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddTreeSifting()

int cuddZddTreeSifting ( DdManager table,
Cudd_ReorderingType  method 
)

Function********************************************************************

Synopsis [Tree sifting algorithm for ZDDs.]

Description [Tree sifting algorithm for ZDDs. Assumes that a tree representing a group hierarchy is passed as a parameter. It then reorders each group in postorder fashion by calling zddTreeSiftingAux. Assumes that no dead nodes are present. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 228 of file cuddZddGroup.c.

231 {
232  int i;
233  int nvars;
234  int result;
235  int tempTree;
236 
237  /* If no tree is provided we create a temporary one in which all
238  ** variables are in a single group. After reordering this tree is
239  ** destroyed.
240  */
241  tempTree = table->treeZ == NULL;
242  if (tempTree) {
243  table->treeZ = Mtr_InitGroupTree(0,table->sizeZ);
244  table->treeZ->index = table->invpermZ[0];
245  }
246  nvars = table->sizeZ;
247 
248 #ifdef DD_DEBUG
249  if (pr > 0 && !tempTree)
250  (void) fprintf(table->out,"cuddZddTreeSifting:");
251  Mtr_PrintGroups(table->treeZ,pr <= 0);
252 #endif
253 #if 0
254  /* Debugging code. */
255  if (table->tree && table->treeZ) {
256  (void) fprintf(table->out,"\n");
257  Mtr_PrintGroups(table->tree, 0);
258  cuddPrintVarGroups(table,table->tree,0,0);
259  for (i = 0; i < table->size; i++) {
260  (void) fprintf(table->out,"%s%d",
261  (i == 0) ? "" : ",", table->invperm[i]);
262  }
263  (void) fprintf(table->out,"\n");
264  for (i = 0; i < table->size; i++) {
265  (void) fprintf(table->out,"%s%d",
266  (i == 0) ? "" : ",", table->perm[i]);
267  }
268  (void) fprintf(table->out,"\n\n");
269  Mtr_PrintGroups(table->treeZ,0);
270  cuddPrintVarGroups(table,table->treeZ,1,0);
271  for (i = 0; i < table->sizeZ; i++) {
272  (void) fprintf(table->out,"%s%d",
273  (i == 0) ? "" : ",", table->invpermZ[i]);
274  }
275  (void) fprintf(table->out,"\n");
276  for (i = 0; i < table->sizeZ; i++) {
277  (void) fprintf(table->out,"%s%d",
278  (i == 0) ? "" : ",", table->permZ[i]);
279  }
280  (void) fprintf(table->out,"\n");
281  }
282  /* End of debugging code. */
283 #endif
284 #ifdef DD_STATS
285  extsymmcalls = 0;
286  extsymm = 0;
287  secdiffcalls = 0;
288  secdiff = 0;
289  secdiffmisfire = 0;
290 
291  (void) fprintf(table->out,"\n");
292  if (!tempTree)
293  (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n",
294  zddCountInternalMtrNodes(table,table->treeZ));
295 #endif
296 
297  /* Initialize the group of each subtable to itself. Initially
298  ** there are no groups. Groups are created according to the tree
299  ** structure in postorder fashion.
300  */
301  for (i = 0; i < nvars; i++)
302  table->subtableZ[i].next = i;
303 
304  /* Reorder. */
305  result = zddTreeSiftingAux(table, table->treeZ, method);
306 
307 #ifdef DD_STATS /* print stats */
308  if (!tempTree && method == CUDD_REORDER_GROUP_SIFT &&
309  (table->groupcheck == CUDD_GROUP_CHECK7 ||
310  table->groupcheck == CUDD_GROUP_CHECK5)) {
311  (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls);
312  (void) fprintf(table->out,"extsymm = %d",extsymm);
313  }
314  if (!tempTree && method == CUDD_REORDER_GROUP_SIFT &&
315  table->groupcheck == CUDD_GROUP_CHECK7) {
316  (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls);
317  (void) fprintf(table->out,"secdiff = %d\n",secdiff);
318  (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire);
319  }
320 #endif
321 
322  if (tempTree)
323  Cudd_FreeZddTree(table);
324  return(result);
325 
326 } /* end of cuddZddTreeSifting */
Cudd_AggregationType groupcheck
Definition: cuddInt.h:410
int * invpermZ
Definition: cuddInt.h:372
int size
Definition: cuddInt.h:345
int * permZ
Definition: cuddInt.h:370
void cuddPrintVarGroups(DdManager *dd, MtrNode *root, int zdd, int silent)
Definition: cuddCheck.c:749
MtrNode * tree
Definition: cuddInt.h:408
MtrHalfWord index
Definition: mtr.h:130
FILE * out
Definition: cuddInt.h:423
void Mtr_PrintGroups(MtrNode *root, int silent)
Definition: mtrGroup.c:595
MtrNode * Mtr_InitGroupTree(int lower, int size)
Definition: mtrGroup.c:120
int sizeZ
Definition: cuddInt.h:346
unsigned int next
Definition: cuddInt.h:317
MtrNode * treeZ
Definition: cuddInt.h:409
static int zddTreeSiftingAux(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddZddGroup.c:345
int * invperm
Definition: cuddInt.h:371
static int result
Definition: cuddGenetic.c:121
void Cudd_FreeZddTree(DdManager *dd)
Definition: cuddAPI.c:2534
int * perm
Definition: cuddInt.h:369
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddUnateProduct()

DdNode* cuddZddUnateProduct ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddUnateProduct.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddUnateProduct]

Definition at line 613 of file cuddZddFuncs.c.

617 {
618  int v, top_f, top_g;
619  DdNode *term1, *term2, *term3, *term4;
620  DdNode *sum1, *sum2;
621  DdNode *f0, *f1, *g0, *g1;
622  DdNode *r;
623  DdNode *one = DD_ONE(dd);
624  DdNode *zero = DD_ZERO(dd);
625  int flag;
626 
627  statLine(dd);
628  if (f == zero || g == zero)
629  return(zero);
630  if (f == one)
631  return(g);
632  if (g == one)
633  return(f);
634 
635  top_f = dd->permZ[f->index];
636  top_g = dd->permZ[g->index];
637 
638  if (top_f > top_g)
639  return(cuddZddUnateProduct(dd, g, f));
640 
641  /* Check cache */
643  if (r)
644  return(r);
645 
646  v = f->index; /* either yi or zi */
647  flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
648  if (flag == 1)
649  return(NULL);
650  Cudd_Ref(f1);
651  Cudd_Ref(f0);
652  flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0);
653  if (flag == 1) {
654  Cudd_RecursiveDerefZdd(dd, f1);
655  Cudd_RecursiveDerefZdd(dd, f0);
656  return(NULL);
657  }
658  Cudd_Ref(g1);
659  Cudd_Ref(g0);
660 
661  term1 = cuddZddUnateProduct(dd, f1, g1);
662  if (term1 == NULL) {
663  Cudd_RecursiveDerefZdd(dd, f1);
664  Cudd_RecursiveDerefZdd(dd, f0);
665  Cudd_RecursiveDerefZdd(dd, g1);
666  Cudd_RecursiveDerefZdd(dd, g0);
667  return(NULL);
668  }
669  Cudd_Ref(term1);
670  term2 = cuddZddUnateProduct(dd, f1, g0);
671  if (term2 == NULL) {
672  Cudd_RecursiveDerefZdd(dd, f1);
673  Cudd_RecursiveDerefZdd(dd, f0);
674  Cudd_RecursiveDerefZdd(dd, g1);
675  Cudd_RecursiveDerefZdd(dd, g0);
676  Cudd_RecursiveDerefZdd(dd, term1);
677  return(NULL);
678  }
679  Cudd_Ref(term2);
680  term3 = cuddZddUnateProduct(dd, f0, g1);
681  if (term3 == NULL) {
682  Cudd_RecursiveDerefZdd(dd, f1);
683  Cudd_RecursiveDerefZdd(dd, f0);
684  Cudd_RecursiveDerefZdd(dd, g1);
685  Cudd_RecursiveDerefZdd(dd, g0);
686  Cudd_RecursiveDerefZdd(dd, term1);
687  Cudd_RecursiveDerefZdd(dd, term2);
688  return(NULL);
689  }
690  Cudd_Ref(term3);
691  term4 = cuddZddUnateProduct(dd, f0, g0);
692  if (term4 == NULL) {
693  Cudd_RecursiveDerefZdd(dd, f1);
694  Cudd_RecursiveDerefZdd(dd, f0);
695  Cudd_RecursiveDerefZdd(dd, g1);
696  Cudd_RecursiveDerefZdd(dd, g0);
697  Cudd_RecursiveDerefZdd(dd, term1);
698  Cudd_RecursiveDerefZdd(dd, term2);
699  Cudd_RecursiveDerefZdd(dd, term3);
700  return(NULL);
701  }
702  Cudd_Ref(term4);
703  Cudd_RecursiveDerefZdd(dd, f1);
704  Cudd_RecursiveDerefZdd(dd, f0);
705  Cudd_RecursiveDerefZdd(dd, g1);
706  Cudd_RecursiveDerefZdd(dd, g0);
707  sum1 = cuddZddUnion(dd, term1, term2);
708  if (sum1 == NULL) {
709  Cudd_RecursiveDerefZdd(dd, term1);
710  Cudd_RecursiveDerefZdd(dd, term2);
711  Cudd_RecursiveDerefZdd(dd, term3);
712  Cudd_RecursiveDerefZdd(dd, term4);
713  return(NULL);
714  }
715  Cudd_Ref(sum1);
716  Cudd_RecursiveDerefZdd(dd, term1);
717  Cudd_RecursiveDerefZdd(dd, term2);
718  sum2 = cuddZddUnion(dd, sum1, term3);
719  if (sum2 == NULL) {
720  Cudd_RecursiveDerefZdd(dd, term3);
721  Cudd_RecursiveDerefZdd(dd, term4);
722  Cudd_RecursiveDerefZdd(dd, sum1);
723  return(NULL);
724  }
725  Cudd_Ref(sum2);
726  Cudd_RecursiveDerefZdd(dd, sum1);
727  Cudd_RecursiveDerefZdd(dd, term3);
728  r = cuddZddGetNode(dd, v, sum2, term4);
729  if (r == NULL) {
730  Cudd_RecursiveDerefZdd(dd, term4);
731  Cudd_RecursiveDerefZdd(dd, sum2);
732  return(NULL);
733  }
734  Cudd_Ref(r);
735  Cudd_RecursiveDerefZdd(dd, sum2);
736  Cudd_RecursiveDerefZdd(dd, term4);
737 
739  Cudd_Deref(r);
740  return(r);
741 
742 } /* end of cuddZddUnateProduct */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
Definition: cudd.h:270
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1050
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
int cuddZddGetCofactors2(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0)
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddZddUnateProduct(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddZddFuncs.c:613
static DdNode * one
Definition: cuddSat.c:105
DdNode * cuddCacheLookup2Zdd(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:549
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddUnion()

DdNode* cuddZddUnion ( DdManager zdd,
DdNode P,
DdNode Q 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddUnion.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 549 of file cuddZddSetop.c.

553 {
554  int p_top, q_top;
555  DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
556  DdManager *table = zdd;
557 
558  statLine(zdd);
559  if (P == empty)
560  return(Q);
561  if (Q == empty)
562  return(P);
563  if (P == Q)
564  return(P);
565 
566  /* Check cache */
567  res = cuddCacheLookup2Zdd(table, cuddZddUnion, P, Q);
568  if (res != NULL)
569  return(res);
570 
571  if (cuddIsConstant(P))
572  p_top = P->index;
573  else
574  p_top = zdd->permZ[P->index];
575  if (cuddIsConstant(Q))
576  q_top = Q->index;
577  else
578  q_top = zdd->permZ[Q->index];
579  if (p_top < q_top) {
580  e = cuddZddUnion(zdd, cuddE(P), Q);
581  if (e == NULL) return (NULL);
582  cuddRef(e);
583  res = cuddZddGetNode(zdd, P->index, cuddT(P), e);
584  if (res == NULL) {
585  Cudd_RecursiveDerefZdd(table, e);
586  return(NULL);
587  }
588  cuddDeref(e);
589  } else if (p_top > q_top) {
590  e = cuddZddUnion(zdd, P, cuddE(Q));
591  if (e == NULL) return(NULL);
592  cuddRef(e);
593  res = cuddZddGetNode(zdd, Q->index, cuddT(Q), e);
594  if (res == NULL) {
595  Cudd_RecursiveDerefZdd(table, e);
596  return(NULL);
597  }
598  cuddDeref(e);
599  } else {
600  t = cuddZddUnion(zdd, cuddT(P), cuddT(Q));
601  if (t == NULL) return(NULL);
602  cuddRef(t);
603  e = cuddZddUnion(zdd, cuddE(P), cuddE(Q));
604  if (e == NULL) {
605  Cudd_RecursiveDerefZdd(table, t);
606  return(NULL);
607  }
608  cuddRef(e);
609  res = cuddZddGetNode(zdd, P->index, t, e);
610  if (res == NULL) {
611  Cudd_RecursiveDerefZdd(table, t);
612  Cudd_RecursiveDerefZdd(table, e);
613  return(NULL);
614  }
615  cuddDeref(t);
616  cuddDeref(e);
617  }
618 
619  cuddCacheInsert2(table, cuddZddUnion, P, Q, res);
620 
621  return(res);
622 
623 } /* end of cuddZddUnion */
#define cuddRef(n)
Definition: cuddInt.h:557
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:270
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1050
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:549
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddCacheLookup2Zdd(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * empty
Definition: cuddZddLin.c:94
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddUniqueCompare()

int cuddZddUniqueCompare ( int *  ptr_x,
int *  ptr_y 
)

Function********************************************************************

Synopsis [Comparison function used by qsort.]

Description [Comparison function used by qsort to order the variables according to the number of keys in the subtables. Returns the difference in number of keys between the two variables being compared.]

SideEffects [None]

SeeAlso []

Definition at line 455 of file cuddZddReord.c.

458 {
459  return(zdd_entry[*ptr_y] - zdd_entry[*ptr_x]);
460 
461 } /* end of cuddZddUniqueCompare */
int * zdd_entry
Definition: cuddZddReord.c:104

◆ cuddZddWeakDiv()

DdNode* cuddZddWeakDiv ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddWeakDiv.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddWeakDiv]

Definition at line 757 of file cuddZddFuncs.c.

761 {
762  int v;
763  DdNode *one = DD_ONE(dd);
764  DdNode *zero = DD_ZERO(dd);
765  DdNode *f0, *f1, *fd, *g0, *g1, *gd;
766  DdNode *q, *tmp;
767  DdNode *r;
768  int flag;
769 
770  statLine(dd);
771  if (g == one)
772  return(f);
773  if (f == zero || f == one)
774  return(zero);
775  if (f == g)
776  return(one);
777 
778  /* Check cache. */
779  r = cuddCacheLookup2Zdd(dd, cuddZddWeakDiv, f, g);
780  if (r)
781  return(r);
782 
783  v = g->index;
784 
785  flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
786  if (flag == 1)
787  return(NULL);
788  Cudd_Ref(f1);
789  Cudd_Ref(f0);
790  Cudd_Ref(fd);
791  flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd);
792  if (flag == 1) {
793  Cudd_RecursiveDerefZdd(dd, f1);
794  Cudd_RecursiveDerefZdd(dd, f0);
795  Cudd_RecursiveDerefZdd(dd, fd);
796  return(NULL);
797  }
798  Cudd_Ref(g1);
799  Cudd_Ref(g0);
800  Cudd_Ref(gd);
801 
802  q = g;
803 
804  if (g0 != zero) {
805  q = cuddZddWeakDiv(dd, f0, g0);
806  if (q == NULL) {
807  Cudd_RecursiveDerefZdd(dd, f1);
808  Cudd_RecursiveDerefZdd(dd, f0);
809  Cudd_RecursiveDerefZdd(dd, fd);
810  Cudd_RecursiveDerefZdd(dd, g1);
811  Cudd_RecursiveDerefZdd(dd, g0);
812  Cudd_RecursiveDerefZdd(dd, gd);
813  return(NULL);
814  }
815  Cudd_Ref(q);
816  }
817  else
818  Cudd_Ref(q);
819  Cudd_RecursiveDerefZdd(dd, f0);
820  Cudd_RecursiveDerefZdd(dd, g0);
821 
822  if (q == zero) {
823  Cudd_RecursiveDerefZdd(dd, f1);
824  Cudd_RecursiveDerefZdd(dd, g1);
825  Cudd_RecursiveDerefZdd(dd, fd);
826  Cudd_RecursiveDerefZdd(dd, gd);
827  cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero);
828  Cudd_Deref(q);
829  return(zero);
830  }
831 
832  if (g1 != zero) {
833  Cudd_RecursiveDerefZdd(dd, q);
834  tmp = cuddZddWeakDiv(dd, f1, g1);
835  if (tmp == NULL) {
836  Cudd_RecursiveDerefZdd(dd, f1);
837  Cudd_RecursiveDerefZdd(dd, g1);
838  Cudd_RecursiveDerefZdd(dd, fd);
839  Cudd_RecursiveDerefZdd(dd, gd);
840  return(NULL);
841  }
842  Cudd_Ref(tmp);
843  Cudd_RecursiveDerefZdd(dd, f1);
844  Cudd_RecursiveDerefZdd(dd, g1);
845  if (q == g)
846  q = tmp;
847  else {
848  q = cuddZddIntersect(dd, q, tmp);
849  if (q == NULL) {
850  Cudd_RecursiveDerefZdd(dd, fd);
851  Cudd_RecursiveDerefZdd(dd, gd);
852  return(NULL);
853  }
854  Cudd_Ref(q);
855  Cudd_RecursiveDerefZdd(dd, tmp);
856  }
857  }
858  else {
859  Cudd_RecursiveDerefZdd(dd, f1);
860  Cudd_RecursiveDerefZdd(dd, g1);
861  }
862 
863  if (q == zero) {
864  Cudd_RecursiveDerefZdd(dd, fd);
865  Cudd_RecursiveDerefZdd(dd, gd);
866  cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero);
867  Cudd_Deref(q);
868  return(zero);
869  }
870 
871  if (gd != zero) {
872  Cudd_RecursiveDerefZdd(dd, q);
873  tmp = cuddZddWeakDiv(dd, fd, gd);
874  if (tmp == NULL) {
875  Cudd_RecursiveDerefZdd(dd, fd);
876  Cudd_RecursiveDerefZdd(dd, gd);
877  return(NULL);
878  }
879  Cudd_Ref(tmp);
880  Cudd_RecursiveDerefZdd(dd, fd);
881  Cudd_RecursiveDerefZdd(dd, gd);
882  if (q == g)
883  q = tmp;
884  else {
885  q = cuddZddIntersect(dd, q, tmp);
886  if (q == NULL) {
887  Cudd_RecursiveDerefZdd(dd, tmp);
888  return(NULL);
889  }
890  Cudd_Ref(q);
891  Cudd_RecursiveDerefZdd(dd, tmp);
892  }
893  }
894  else {
895  Cudd_RecursiveDerefZdd(dd, fd);
896  Cudd_RecursiveDerefZdd(dd, gd);
897  }
898 
899  cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, q);
900  Cudd_Deref(q);
901  return(q);
902 
903 } /* end of cuddZddWeakDiv */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
Definition: cudd.h:270
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
int cuddZddGetCofactors3(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:638
DdNode * cuddZddWeakDiv(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddZddFuncs.c:757
DdNode * cuddCacheLookup2Zdd(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddWeakDivF()

DdNode* cuddZddWeakDivF ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddWeakDivF.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddWeakDivF]

Definition at line 918 of file cuddZddFuncs.c.

922 {
923  int v, top_f, top_g, vf, vg;
924  DdNode *one = DD_ONE(dd);
925  DdNode *zero = DD_ZERO(dd);
926  DdNode *f0, *f1, *fd, *g0, *g1, *gd;
927  DdNode *q, *tmp;
928  DdNode *r;
929  DdNode *term1, *term0, *termd;
930  int flag;
931  int pv, nv;
932 
933  statLine(dd);
934  if (g == one)
935  return(f);
936  if (f == zero || f == one)
937  return(zero);
938  if (f == g)
939  return(one);
940 
941  /* Check cache. */
942  r = cuddCacheLookup2Zdd(dd, cuddZddWeakDivF, f, g);
943  if (r)
944  return(r);
945 
946  top_f = dd->permZ[f->index];
947  top_g = dd->permZ[g->index];
948  vf = top_f >> 1;
949  vg = top_g >> 1;
950  v = ddMin(top_f, top_g);
951 
952  if (v == top_f && vf < vg) {
953  v = f->index;
954  flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
955  if (flag == 1)
956  return(NULL);
957  Cudd_Ref(f1);
958  Cudd_Ref(f0);
959  Cudd_Ref(fd);
960 
961  pv = cuddZddGetPosVarIndex(dd, v);
962  nv = cuddZddGetNegVarIndex(dd, v);
963 
964  term1 = cuddZddWeakDivF(dd, f1, g);
965  if (term1 == NULL) {
966  Cudd_RecursiveDerefZdd(dd, f1);
967  Cudd_RecursiveDerefZdd(dd, f0);
968  Cudd_RecursiveDerefZdd(dd, fd);
969  return(NULL);
970  }
971  Cudd_Ref(term1);
972  Cudd_RecursiveDerefZdd(dd, f1);
973  term0 = cuddZddWeakDivF(dd, f0, g);
974  if (term0 == NULL) {
975  Cudd_RecursiveDerefZdd(dd, f0);
976  Cudd_RecursiveDerefZdd(dd, fd);
977  Cudd_RecursiveDerefZdd(dd, term1);
978  return(NULL);
979  }
980  Cudd_Ref(term0);
981  Cudd_RecursiveDerefZdd(dd, f0);
982  termd = cuddZddWeakDivF(dd, fd, g);
983  if (termd == NULL) {
984  Cudd_RecursiveDerefZdd(dd, fd);
985  Cudd_RecursiveDerefZdd(dd, term1);
986  Cudd_RecursiveDerefZdd(dd, term0);
987  return(NULL);
988  }
989  Cudd_Ref(termd);
990  Cudd_RecursiveDerefZdd(dd, fd);
991 
992  tmp = cuddZddGetNode(dd, nv, term0, termd); /* nv = zi */
993  if (tmp == NULL) {
994  Cudd_RecursiveDerefZdd(dd, term1);
995  Cudd_RecursiveDerefZdd(dd, term0);
996  Cudd_RecursiveDerefZdd(dd, termd);
997  return(NULL);
998  }
999  Cudd_Ref(tmp);
1000  Cudd_RecursiveDerefZdd(dd, term0);
1001  Cudd_RecursiveDerefZdd(dd, termd);
1002  q = cuddZddGetNode(dd, pv, term1, tmp); /* pv = yi */
1003  if (q == NULL) {
1004  Cudd_RecursiveDerefZdd(dd, term1);
1005  Cudd_RecursiveDerefZdd(dd, tmp);
1006  return(NULL);
1007  }
1008  Cudd_Ref(q);
1009  Cudd_RecursiveDerefZdd(dd, term1);
1010  Cudd_RecursiveDerefZdd(dd, tmp);
1011 
1012  cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q);
1013  Cudd_Deref(q);
1014  return(q);
1015  }
1016 
1017  if (v == top_f)
1018  v = f->index;
1019  else
1020  v = g->index;
1021 
1022  flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
1023  if (flag == 1)
1024  return(NULL);
1025  Cudd_Ref(f1);
1026  Cudd_Ref(f0);
1027  Cudd_Ref(fd);
1028  flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd);
1029  if (flag == 1) {
1030  Cudd_RecursiveDerefZdd(dd, f1);
1031  Cudd_RecursiveDerefZdd(dd, f0);
1032  Cudd_RecursiveDerefZdd(dd, fd);
1033  return(NULL);
1034  }
1035  Cudd_Ref(g1);
1036  Cudd_Ref(g0);
1037  Cudd_Ref(gd);
1038 
1039  q = g;
1040 
1041  if (g0 != zero) {
1042  q = cuddZddWeakDivF(dd, f0, g0);
1043  if (q == NULL) {
1044  Cudd_RecursiveDerefZdd(dd, f1);
1045  Cudd_RecursiveDerefZdd(dd, f0);
1046  Cudd_RecursiveDerefZdd(dd, fd);
1047  Cudd_RecursiveDerefZdd(dd, g1);
1048  Cudd_RecursiveDerefZdd(dd, g0);
1049  Cudd_RecursiveDerefZdd(dd, gd);
1050  return(NULL);
1051  }
1052  Cudd_Ref(q);
1053  }
1054  else
1055  Cudd_Ref(q);
1056  Cudd_RecursiveDerefZdd(dd, f0);
1057  Cudd_RecursiveDerefZdd(dd, g0);
1058 
1059  if (q == zero) {
1060  Cudd_RecursiveDerefZdd(dd, f1);
1061  Cudd_RecursiveDerefZdd(dd, g1);
1062  Cudd_RecursiveDerefZdd(dd, fd);
1063  Cudd_RecursiveDerefZdd(dd, gd);
1064  cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero);
1065  Cudd_Deref(q);
1066  return(zero);
1067  }
1068 
1069  if (g1 != zero) {
1070  Cudd_RecursiveDerefZdd(dd, q);
1071  tmp = cuddZddWeakDivF(dd, f1, g1);
1072  if (tmp == NULL) {
1073  Cudd_RecursiveDerefZdd(dd, f1);
1074  Cudd_RecursiveDerefZdd(dd, g1);
1075  Cudd_RecursiveDerefZdd(dd, fd);
1076  Cudd_RecursiveDerefZdd(dd, gd);
1077  return(NULL);
1078  }
1079  Cudd_Ref(tmp);
1080  Cudd_RecursiveDerefZdd(dd, f1);
1081  Cudd_RecursiveDerefZdd(dd, g1);
1082  if (q == g)
1083  q = tmp;
1084  else {
1085  q = cuddZddIntersect(dd, q, tmp);
1086  if (q == NULL) {
1087  Cudd_RecursiveDerefZdd(dd, fd);
1088  Cudd_RecursiveDerefZdd(dd, gd);
1089  return(NULL);
1090  }
1091  Cudd_Ref(q);
1092  Cudd_RecursiveDerefZdd(dd, tmp);
1093  }
1094  }
1095  else {
1096  Cudd_RecursiveDerefZdd(dd, f1);
1097  Cudd_RecursiveDerefZdd(dd, g1);
1098  }
1099 
1100  if (q == zero) {
1101  Cudd_RecursiveDerefZdd(dd, fd);
1102  Cudd_RecursiveDerefZdd(dd, gd);
1103  cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero);
1104  Cudd_Deref(q);
1105  return(zero);
1106  }
1107 
1108  if (gd != zero) {
1109  Cudd_RecursiveDerefZdd(dd, q);
1110  tmp = cuddZddWeakDivF(dd, fd, gd);
1111  if (tmp == NULL) {
1112  Cudd_RecursiveDerefZdd(dd, fd);
1113  Cudd_RecursiveDerefZdd(dd, gd);
1114  return(NULL);
1115  }
1116  Cudd_Ref(tmp);
1117  Cudd_RecursiveDerefZdd(dd, fd);
1118  Cudd_RecursiveDerefZdd(dd, gd);
1119  if (q == g)
1120  q = tmp;
1121  else {
1122  q = cuddZddIntersect(dd, q, tmp);
1123  if (q == NULL) {
1124  Cudd_RecursiveDerefZdd(dd, tmp);
1125  return(NULL);
1126  }
1127  Cudd_Ref(q);
1128  Cudd_RecursiveDerefZdd(dd, tmp);
1129  }
1130  }
1131  else {
1132  Cudd_RecursiveDerefZdd(dd, fd);
1133  Cudd_RecursiveDerefZdd(dd, gd);
1134  }
1135 
1136  cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q);
1137  Cudd_Deref(q);
1138  return(q);
1139 
1140 } /* end of cuddZddWeakDivF */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
Definition: cudd.h:270
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1050
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
int * permZ
Definition: cuddInt.h:370
int cuddZddGetCofactors3(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)
#define statLine(dd)
Definition: cuddInt.h:990
static DdNode * one
Definition: cuddSat.c:105
int cuddZddGetNegVarIndex(DdManager *dd, int index)
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:638
#define ddMin(x, y)
Definition: cuddInt.h:771
int cuddZddGetPosVarIndex(DdManager *dd, int index)
DdNode * cuddZddWeakDivF(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddZddFuncs.c:918
DdNode * cuddCacheLookup2Zdd(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)
void cuddCacheInsert2(DdManager *table, DdNode *(*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)
DdHalfWord index
Definition: cudd.h:271
static DdNode * zero
Definition: cuddSat.c:105
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880