abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddInt.h File Reference
#include <math.h>
#include "cudd.h"
#include "misc/st/st.h"

Go to the source code of this file.

Data Structures

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.1
 
#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 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 cuddF2L(f)   ((Cudd_Regular(f)->Id << 1) | Cudd_IsComplement(f))
 
#define ddHash(f, g, s)   ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s))
 
#define ddCHash2(o, f, g, s)   (((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s))
 
#define ddCHash2_(o, f, g)   (((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2))
 
#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 ABC_PTRINT_T ptrint
 
typedef ABC_PTRUINT_T 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 *(*)(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)
 
int cuddCheckCube (DdManager *dd, DdNode *g)
 
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)
 
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)
 
DdLevelQueuecuddLevelQueueInit (int levels, int itemSize, int numBuckets)
 
void cuddLevelQueueQuit (DdLevelQueue *queue)
 
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)
 
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)
 
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

#define CUDD_GEN_CUBES   0

Definition at line 192 of file cuddInt.h.

#define CUDD_GEN_EMPTY   0

Definition at line 196 of file cuddInt.h.

#define CUDD_GEN_NODES   2

Definition at line 194 of file cuddInt.h.

#define CUDD_GEN_NONEMPTY   1

Definition at line 197 of file cuddInt.h.

#define CUDD_GEN_PRIMES   1

Definition at line 193 of file cuddInt.h.

#define CUDD_GEN_ZDD_PATHS   3

Definition at line 195 of file cuddInt.h.

#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 979 of file cuddInt.h.

#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 804 of file cuddInt.h.

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

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 564 of file cuddInt.h.

#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 547 of file cuddInt.h.

#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 604 of file cuddInt.h.

#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 652 of file cuddInt.h.

#define cuddF2L (   f)    ((Cudd_Regular(f)->Id << 1) | Cudd_IsComplement(f))

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

Synopsis [Converts pointer into a literal.]

Description []

SideEffects []

SeeAlso []

Definition at line 718 of file cuddInt.h.

#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 686 of file cuddInt.h.

#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 620 of file cuddInt.h.

#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 704 of file cuddInt.h.

#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 584 of file cuddInt.h.

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

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

Synopsis [Saturating decrement operator.]

Description []

SideEffects [none]

SeeAlso [cuddSatInc]

Definition at line 896 of file cuddInt.h.

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

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

Synopsis [Saturating increment operator.]

Description []

SideEffects [none]

SeeAlso [cuddSatDec]

Definition at line 878 of file cuddInt.h.

#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 636 of file cuddInt.h.

#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 668 of file cuddInt.h.

#define DD_ADD_BDD_DO_INTERVAL_TAG   0x22

Definition at line 176 of file cuddInt.h.

#define DD_ADD_COMPOSE_RECUR_TAG   0x42

Definition at line 180 of file cuddInt.h.

#define DD_ADD_EVAL_CONST_TAG   0x66

Definition at line 185 of file cuddInt.h.

#define DD_ADD_ITE_CONSTANT_TAG   0x62

Definition at line 184 of file cuddInt.h.

#define DD_ADD_ITE_TAG   0x02

Definition at line 172 of file cuddInt.h.

#define DD_ADD_NON_SIM_COMPOSE_TAG   0x46

Definition at line 181 of file cuddInt.h.

#define DD_ADD_OUT_SUM_TAG   0x6e

Definition at line 187 of file cuddInt.h.

#define DD_ADD_TRIANGLE_TAG   0x86

Definition at line 189 of file cuddInt.h.

#define DD_BDD_AND_ABSTRACT_TAG   0x06

Definition at line 173 of file cuddInt.h.

#define DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG   0x2a

Definition at line 178 of file cuddInt.h.

#define DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG   0x26

Definition at line 177 of file cuddInt.h.

#define DD_BDD_COMPOSE_RECUR_TAG   0x2e

Definition at line 179 of file cuddInt.h.

#define DD_BDD_ITE_CONSTANT_TAG   0x6a

Definition at line 186 of file cuddInt.h.

#define DD_BDD_ITE_TAG   0x0e

Definition at line 175 of file cuddInt.h.

#define DD_BDD_LEQ_UNLESS_TAG   0x82

Definition at line 188 of file cuddInt.h.

#define DD_BDD_XOR_EXIST_ABSTRACT_TAG   0x0a

Definition at line 174 of file cuddInt.h.

#define DD_CRI_HI_MARK   (10e150)

Definition at line 118 of file cuddInt.h.

#define DD_CRI_LO_MARK   (-(DD_CRI_HI_MARK))

Definition at line 119 of file cuddInt.h.

#define DD_DEFAULT_RECOMB   0

Definition at line 149 of file cuddInt.h.

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

Definition at line 102 of file cuddInt.h.

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

Definition at line 152 of file cuddInt.h.

#define DD_EPSILON   (1.0e-12)

Definition at line 109 of file cuddInt.h.

#define DD_EQUIV_DC_TAG   0x4a

Definition at line 182 of file cuddInt.h.

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

Definition at line 151 of file cuddInt.h.

#define DD_GC_FRAC_HI   DD_MAX_SUBTABLE_DENSITY * 1.0

Definition at line 134 of file cuddInt.h.

#define DD_GC_FRAC_LO   DD_MAX_SUBTABLE_DENSITY * 0.25

Definition at line 133 of file cuddInt.h.

#define DD_GC_FRAC_MIN   0.2

Definition at line 135 of file cuddInt.h.

#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-2004, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Revision [

Id:
cuddInt.h,v 1.139 2009/03/08 02:49:02 fabio Exp

]

Definition at line 90 of file cuddInt.h.

#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 995 of file cuddInt.h.

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

Definition at line 140 of file cuddInt.h.

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

Definition at line 144 of file cuddInt.h.

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

Definition at line 138 of file cuddInt.h.

#define DD_MAX_REORDER_GROWTH   1.1

Definition at line 150 of file cuddInt.h.

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

Definition at line 126 of file cuddInt.h.

#define DD_MAXREF   ((DdHalfWord) ~0)

Definition at line 100 of file cuddInt.h.

#define DD_MEM_CHUNK   1022

Definition at line 104 of file cuddInt.h.

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

Definition at line 136 of file cuddInt.h.

#define DD_MINUS_INF_VAL   (-(DD_PLUS_INF_VAL))

Definition at line 121 of file cuddInt.h.

#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 955 of file cuddInt.h.

#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 1010 of file cuddInt.h.

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

Definition at line 123 of file cuddInt.h.

#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 911 of file cuddInt.h.

#define DD_ONE_VAL   (1.0)

Definition at line 107 of file cuddInt.h.

#define DD_P1   12582917

Definition at line 155 of file cuddInt.h.

#define DD_P2   4256249

Definition at line 156 of file cuddInt.h.

#define DD_P3   741457

Definition at line 157 of file cuddInt.h.

#define DD_P4   1618033999

Definition at line 158 of file cuddInt.h.

#define DD_PLUS_INF_VAL   (10e301)

Definition at line 117 of file cuddInt.h.

#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 941 of file cuddInt.h.

#define DD_SIFT_MAX_SWAPS   2000000

Definition at line 148 of file cuddInt.h.

#define DD_SIFT_MAX_VAR   1000

Definition at line 147 of file cuddInt.h.

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

Definition at line 142 of file cuddInt.h.

#define DD_UNUSED

Definition at line 92 of file cuddInt.h.

#define DD_ZDD_ITE_TAG   0x4e

Definition at line 183 of file cuddInt.h.

#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 927 of file cuddInt.h.

#define DD_ZERO_VAL   (0.0)

Definition at line 108 of file cuddInt.h.

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

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

Synopsis [Computes the absolute value of a number.]

Description []

SideEffects [none]

SeeAlso []

Definition at line 846 of file cuddInt.h.

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

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

Synopsis [Hash function for the cache.]

Description []

SideEffects [none]

SeeAlso [ddHash ddCHash2] Macro***********************************************************************

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

Description []

SideEffects [none]

SeeAlso [ddHash ddCHash]

Definition at line 786 of file cuddInt.h.

#define ddCHash2_ (   o,
  f,
 
)    (((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2))

Definition at line 788 of file cuddInt.h.

#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 861 of file cuddInt.h.

#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 737 of file cuddInt.h.

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

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

Synopsis [Computes the maximum of two numbers.]

Description []

SideEffects [none]

SeeAlso [ddMin]

Definition at line 832 of file cuddInt.h.

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

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

Synopsis [Computes the minimum of two numbers.]

Description []

SideEffects [none]

SeeAlso [ddMax]

Definition at line 818 of file cuddInt.h.

#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 1037 of file cuddInt.h.

Typedef Documentation

typedef struct DdCache DdCache
typedef struct DdHashItem DdHashItem
typedef struct DdHashTable DdHashTable
typedef struct DdHook DdHook
typedef struct DdLevelQueue DdLevelQueue
typedef struct DdLocalCache DdLocalCache
typedef DdNode* DdNodePtr

Definition at line 268 of file cuddInt.h.

typedef struct DdQueueItem DdQueueItem
typedef struct DdSubtable DdSubtable
typedef struct Move Move
typedef ABC_PTRINT_T ptrint

Definition at line 260 of file cuddInt.h.

typedef ABC_PTRUINT_T ptruint

Definition at line 261 of file cuddInt.h.

Function Documentation

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

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

Synopsis [Performs the recursive step for Cudd_addBddPattern.]

Description [Performs the recursive step for Cudd_addBddPattern. Returns a pointer to the resulting BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 493 of file cuddBridge.c.

496 {
497  DdNode *res, *T, *E;
498  DdNode *fv, *fvn;
499  int v;
500 
501  statLine(dd);
502  /* Check terminal case. */
503  if (cuddIsConstant(f)) {
504  return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd)));
505  }
506 
507  /* Check cache. */
509  if (res != NULL) return(res);
510 
511  /* Recursive step. */
512  v = f->index;
513  fv = cuddT(f); fvn = cuddE(f);
514 
515  T = cuddAddBddDoPattern(dd,fv);
516  if (T == NULL) return(NULL);
517  cuddRef(T);
518 
519  E = cuddAddBddDoPattern(dd,fvn);
520  if (E == NULL) {
521  Cudd_RecursiveDeref(dd, T);
522  return(NULL);
523  }
524  cuddRef(E);
525  if (Cudd_IsComplement(T)) {
526  res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E));
527  if (res == NULL) {
528  Cudd_RecursiveDeref(dd, T);
529  Cudd_RecursiveDeref(dd, E);
530  return(NULL);
531  }
532  res = Cudd_Not(res);
533  } else {
534  res = (T == E) ? T : cuddUniqueInter(dd,v,T,E);
535  if (res == NULL) {
536  Cudd_RecursiveDeref(dd, T);
537  Cudd_RecursiveDeref(dd, E);
538  return(NULL);
539  }
540  }
541  cuddDeref(T);
542  cuddDeref(E);
543 
544  /* Store result. */
546 
547  return(res);
548 
549 } /* end of cuddAddBddDoPattern */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define statLine(dd)
Definition: cuddInt.h:1037
#define Cudd_IsComplement(node)
Definition: cudd.h:425
DdNode * cuddCacheLookup1(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddCache.c:556
DdNode * cuddAddBddDoPattern(DdManager *dd, DdNode *f)
Definition: cuddBridge.c:493
#define cuddIsConstant(node)
Definition: cuddInt.h:620
DdNode * Cudd_addBddPattern(DdManager *dd, DdNode *f)
Definition: cuddBridge.c:379
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddCache.c:323
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 562 of file cuddAddIte.c.

565 {
566  DdNode *one,*zero;
567  DdNode *r,*Fv,*Fnv,*t,*e;
568 
569  statLine(dd);
570  one = DD_ONE(dd);
571  zero = DD_ZERO(dd);
572 
573  if (cuddIsConstant(f)) {
574  if (f == zero) {
575  return(one);
576  } else {
577  return(zero);
578  }
579  }
580  r = cuddCacheLookup1(dd,Cudd_addCmpl,f);
581  if (r != NULL) {
582  return(r);
583  }
584  Fv = cuddT(f);
585  Fnv = cuddE(f);
586  t = cuddAddCmplRecur(dd,Fv);
587  if (t == NULL) return(NULL);
588  cuddRef(t);
589  e = cuddAddCmplRecur(dd,Fnv);
590  if (e == NULL) {
591  Cudd_RecursiveDeref(dd,t);
592  return(NULL);
593  }
594  cuddRef(e);
595  r = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e);
596  if (r == NULL) {
597  Cudd_RecursiveDeref(dd, t);
598  Cudd_RecursiveDeref(dd, e);
599  return(NULL);
600  }
601  cuddDeref(t);
602  cuddDeref(e);
604  return(r);
605 
606 } /* end of cuddAddCmplRecur */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
DdNode * Cudd_addCmpl(DdManager *dd, DdNode *f)
Definition: cuddAddIte.c:347
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup1(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddCache.c:556
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddCache.c:323
DdNode * cuddAddCmplRecur(DdManager *dd, DdNode *f)
Definition: cuddAddIte.c:562
#define DD_ZERO(dd)
Definition: cuddInt.h:927
DdNode* cuddAddComposeRecur ( DdManager dd,
DdNode f,
DdNode g,
DdNode proj 
)

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

Synopsis [Performs the recursive step of Cudd_addCompose.]

Description [Performs the recursive step of Cudd_addCompose. Returns the composed BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addCompose]

Definition at line 952 of file cuddCompose.c.

957 {
958  DdNode *f1, *f0, *g1, *g0, *r, *t, *e;
959  unsigned int v, topf, topg, topindex;
960 
961  statLine(dd);
962  v = dd->perm[proj->index];
963  topf = cuddI(dd,f->index);
964 
965  /* Terminal case. Subsumes the test for constant f. */
966  if (topf > v) return(f);
967 
968  /* Check cache. */
969  r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj);
970  if (r != NULL) {
971  return(r);
972  }
973 
974  if (topf == v) {
975  /* Compose. */
976  f1 = cuddT(f);
977  f0 = cuddE(f);
978  r = cuddAddIteRecur(dd, g, f1, f0);
979  if (r == NULL) return(NULL);
980  } else {
981  /* Compute cofactors of f and g. Remember the index of the top
982  ** variable.
983  */
984  topg = cuddI(dd,g->index);
985  if (topf > topg) {
986  topindex = g->index;
987  f1 = f0 = f;
988  } else {
989  topindex = f->index;
990  f1 = cuddT(f);
991  f0 = cuddE(f);
992  }
993  if (topg > topf) {
994  g1 = g0 = g;
995  } else {
996  g1 = cuddT(g);
997  g0 = cuddE(g);
998  }
999  /* Recursive step. */
1000  t = cuddAddComposeRecur(dd, f1, g1, proj);
1001  if (t == NULL) return(NULL);
1002  cuddRef(t);
1003  e = cuddAddComposeRecur(dd, f0, g0, proj);
1004  if (e == NULL) {
1005  Cudd_RecursiveDeref(dd, t);
1006  return(NULL);
1007  }
1008  cuddRef(e);
1009 
1010  if (t == e) {
1011  r = t;
1012  } else {
1013  r = cuddUniqueInter(dd, (int) topindex, t, e);
1014  if (r == NULL) {
1015  Cudd_RecursiveDeref(dd, t);
1016  Cudd_RecursiveDeref(dd, e);
1017  return(NULL);
1018  }
1019  }
1020  cuddDeref(t);
1021  cuddDeref(e);
1022  }
1023 
1025 
1026  return(r);
1027 
1028 } /* end of cuddAddComposeRecur */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define DD_ADD_COMPOSE_RECUR_TAG
Definition: cuddInt.h:180
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddAddComposeRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *proj)
Definition: cuddCompose.c:952
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * cuddAddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddAddIte.c:445
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:369
DdNode* cuddAddConstrainRecur ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Performs the recursive step of Cudd_addConstrain.]

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

SideEffects [None]

SeeAlso [Cudd_addConstrain]

Definition at line 1203 of file cuddGenCof.c.

1207 {
1208  DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r;
1209  DdNode *one, *zero;
1210  unsigned int topf, topc;
1211  int index;
1212 
1213  statLine(dd);
1214  one = DD_ONE(dd);
1215  zero = DD_ZERO(dd);
1216 
1217  /* Trivial cases. */
1218  if (c == one) return(f);
1219  if (c == zero) return(zero);
1220  if (Cudd_IsConstant(f)) return(f);
1221  if (f == c) return(one);
1222 
1223  /* Now f and c are non-constant. */
1224 
1225  /* Check the cache. */
1226  r = cuddCacheLookup2(dd, Cudd_addConstrain, f, c);
1227  if (r != NULL) {
1228  return(r);
1229  }
1230 
1231  /* Recursive step. */
1232  topf = dd->perm[f->index];
1233  topc = dd->perm[c->index];
1234  if (topf <= topc) {
1235  index = f->index;
1236  Fv = cuddT(f); Fnv = cuddE(f);
1237  } else {
1238  index = c->index;
1239  Fv = Fnv = f;
1240  }
1241  if (topc <= topf) {
1242  Cv = cuddT(c); Cnv = cuddE(c);
1243  } else {
1244  Cv = Cnv = c;
1245  }
1246 
1247  if (!Cudd_IsConstant(Cv)) {
1248  t = cuddAddConstrainRecur(dd, Fv, Cv);
1249  if (t == NULL)
1250  return(NULL);
1251  } else if (Cv == one) {
1252  t = Fv;
1253  } else { /* Cv == zero: return Fnv @ Cnv */
1254  if (Cnv == one) {
1255  r = Fnv;
1256  } else {
1257  r = cuddAddConstrainRecur(dd, Fnv, Cnv);
1258  if (r == NULL)
1259  return(NULL);
1260  }
1261  return(r);
1262  }
1263  cuddRef(t);
1264 
1265  if (!Cudd_IsConstant(Cnv)) {
1266  e = cuddAddConstrainRecur(dd, Fnv, Cnv);
1267  if (e == NULL) {
1268  Cudd_RecursiveDeref(dd, t);
1269  return(NULL);
1270  }
1271  } else if (Cnv == one) {
1272  e = Fnv;
1273  } else { /* Cnv == zero: return Fv @ Cv previously computed */
1274  cuddDeref(t);
1275  return(t);
1276  }
1277  cuddRef(e);
1278 
1279  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
1280  if (r == NULL) {
1281  Cudd_RecursiveDeref(dd, e);
1282  Cudd_RecursiveDeref(dd, t);
1283  return(NULL);
1284  }
1285  cuddDeref(t);
1286  cuddDeref(e);
1287 
1288  cuddCacheInsert2(dd, Cudd_addConstrain, f, c, r);
1289  return(r);
1290 
1291 } /* end of cuddAddConstrainRecur */
DdNode * Cudd_addConstrain(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:336
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
static DdNode * one
Definition: cuddDecomp.c:112
DdNode * cuddAddConstrainRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:1203
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
#define DD_ZERO(dd)
Definition: cuddInt.h:927
DdNode* cuddAddExistAbstractRecur ( DdManager manager,
DdNode f,
DdNode cube 
)

AutomaticStart

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

Synopsis [Performs the recursive step of Cudd_addExistAbstract.]

Description [Performs the recursive step of Cudd_addExistAbstract. Returns the ADD obtained by abstracting the variables of cube from f, if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 256 of file cuddAddAbs.c.

260 {
261  DdNode *T, *E, *res, *res1, *res2, *zero;
262 
263  statLine(manager);
264  zero = DD_ZERO(manager);
265 
266  /* Cube is guaranteed to be a cube at this point. */
267  if (f == zero || cuddIsConstant(cube)) {
268  return(f);
269  }
270 
271  /* Abstract a variable that does not appear in f => multiply by 2. */
272  if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
273  res1 = cuddAddExistAbstractRecur(manager, f, cuddT(cube));
274  if (res1 == NULL) return(NULL);
275  cuddRef(res1);
276  /* Use the "internal" procedure to be alerted in case of
277  ** dynamic reordering. If dynamic reordering occurs, we
278  ** have to abort the entire abstraction.
279  */
280  res = cuddAddApplyRecur(manager,Cudd_addTimes,res1,two);
281  if (res == NULL) {
282  Cudd_RecursiveDeref(manager,res1);
283  return(NULL);
284  }
285  cuddRef(res);
286  Cudd_RecursiveDeref(manager,res1);
287  cuddDeref(res);
288  return(res);
289  }
290 
291  if ((res = cuddCacheLookup2(manager, Cudd_addExistAbstract, f, cube)) != NULL) {
292  return(res);
293  }
294 
295  T = cuddT(f);
296  E = cuddE(f);
297 
298  /* If the two indices are the same, so are their levels. */
299  if (f->index == cube->index) {
300  res1 = cuddAddExistAbstractRecur(manager, T, cuddT(cube));
301  if (res1 == NULL) return(NULL);
302  cuddRef(res1);
303  res2 = cuddAddExistAbstractRecur(manager, E, cuddT(cube));
304  if (res2 == NULL) {
305  Cudd_RecursiveDeref(manager,res1);
306  return(NULL);
307  }
308  cuddRef(res2);
309  res = cuddAddApplyRecur(manager, Cudd_addPlus, res1, res2);
310  if (res == NULL) {
311  Cudd_RecursiveDeref(manager,res1);
312  Cudd_RecursiveDeref(manager,res2);
313  return(NULL);
314  }
315  cuddRef(res);
316  Cudd_RecursiveDeref(manager,res1);
317  Cudd_RecursiveDeref(manager,res2);
318  cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res);
319  cuddDeref(res);
320  return(res);
321  } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
322  res1 = cuddAddExistAbstractRecur(manager, T, cube);
323  if (res1 == NULL) return(NULL);
324  cuddRef(res1);
325  res2 = cuddAddExistAbstractRecur(manager, E, cube);
326  if (res2 == NULL) {
327  Cudd_RecursiveDeref(manager,res1);
328  return(NULL);
329  }
330  cuddRef(res2);
331  res = (res1 == res2) ? res1 :
332  cuddUniqueInter(manager, (int) f->index, res1, res2);
333  if (res == NULL) {
334  Cudd_RecursiveDeref(manager,res1);
335  Cudd_RecursiveDeref(manager,res2);
336  return(NULL);
337  }
338  cuddDeref(res1);
339  cuddDeref(res2);
340  cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res);
341  return(res);
342  }
343 
344 } /* end of cuddAddExistAbstractRecur */
#define cuddRef(n)
Definition: cuddInt.h:584
static DdNode * two
Definition: cuddAddAbs.c:92
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
DdNode * cuddAddApplyRecur(DdManager *dd, DD_AOP op, DdNode *f, DdNode *g)
Definition: cuddAddApply.c:809
DdNode * cuddAddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:256
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
DdNode * Cudd_addPlus(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:168
#define cuddIsConstant(node)
Definition: cuddInt.h:620
DdNode * Cudd_addExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:129
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * Cudd_addTimes(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:208
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 445 of file cuddAddIte.c.

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

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

Synopsis [Implements the recursive step of Cudd_addNegate.]

Description [Implements the recursive step of Cudd_addNegate. Returns a pointer to the result.]

SideEffects [None]

Definition at line 180 of file cuddAddNeg.c.

183 {
184  DdNode *res,
185  *fv, *fvn,
186  *T, *E;
187 
188  statLine(dd);
189  /* Check terminal cases. */
190  if (cuddIsConstant(f)) {
191  res = cuddUniqueConst(dd,-cuddV(f));
192  return(res);
193  }
194 
195  /* Check cache */
196  res = cuddCacheLookup1(dd,Cudd_addNegate,f);
197  if (res != NULL) return(res);
198 
199  /* Recursive Step */
200  fv = cuddT(f);
201  fvn = cuddE(f);
202  T = cuddAddNegateRecur(dd,fv);
203  if (T == NULL) return(NULL);
204  cuddRef(T);
205 
206  E = cuddAddNegateRecur(dd,fvn);
207  if (E == NULL) {
208  Cudd_RecursiveDeref(dd,T);
209  return(NULL);
210  }
211  cuddRef(E);
212  res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E);
213  if (res == NULL) {
214  Cudd_RecursiveDeref(dd, T);
215  Cudd_RecursiveDeref(dd, E);
216  return(NULL);
217  }
218  cuddDeref(T);
219  cuddDeref(E);
220 
221  /* Store result. */
223 
224  return(res);
225 
226 } /* end of cuddAddNegateRecur */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
Definition: cuddTable.c:1450
#define statLine(dd)
Definition: cuddInt.h:1037
#define cuddV(node)
Definition: cuddInt.h:668
DdNode * cuddCacheLookup1(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddCache.c:556
DdNode * cuddAddNegateRecur(DdManager *dd, DdNode *f)
Definition: cuddAddNeg.c:180
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * Cudd_addNegate(DdManager *dd, DdNode *f)
Definition: cuddAddNeg.c:120
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddCache.c:323
DdNode* cuddAddOrAbstractRecur ( DdManager manager,
DdNode f,
DdNode cube 
)

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

Synopsis [Performs the recursive step of Cudd_addOrAbstract.]

Description [Performs the recursive step of Cudd_addOrAbstract. Returns the ADD obtained by abstracting the variables of cube from f, if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 469 of file cuddAddAbs.c.

473 {
474  DdNode *T, *E, *res, *res1, *res2, *one;
475 
476  statLine(manager);
477  one = DD_ONE(manager);
478 
479  /* Cube is guaranteed to be a cube at this point. */
480  if (cuddIsConstant(f) || cube == one) {
481  return(f);
482  }
483 
484  /* Abstract a variable that does not appear in f. */
485  if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
486  res = cuddAddOrAbstractRecur(manager, f, cuddT(cube));
487  return(res);
488  }
489 
490  if ((res = cuddCacheLookup2(manager, Cudd_addOrAbstract, f, cube)) != NULL) {
491  return(res);
492  }
493 
494  T = cuddT(f);
495  E = cuddE(f);
496 
497  /* If the two indices are the same, so are their levels. */
498  if (f->index == cube->index) {
499  res1 = cuddAddOrAbstractRecur(manager, T, cuddT(cube));
500  if (res1 == NULL) return(NULL);
501  cuddRef(res1);
502  if (res1 != one) {
503  res2 = cuddAddOrAbstractRecur(manager, E, cuddT(cube));
504  if (res2 == NULL) {
505  Cudd_RecursiveDeref(manager,res1);
506  return(NULL);
507  }
508  cuddRef(res2);
509  res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res2);
510  if (res == NULL) {
511  Cudd_RecursiveDeref(manager,res1);
512  Cudd_RecursiveDeref(manager,res2);
513  return(NULL);
514  }
515  cuddRef(res);
516  Cudd_RecursiveDeref(manager,res1);
517  Cudd_RecursiveDeref(manager,res2);
518  } else {
519  res = res1;
520  }
521  cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res);
522  cuddDeref(res);
523  return(res);
524  } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
525  res1 = cuddAddOrAbstractRecur(manager, T, cube);
526  if (res1 == NULL) return(NULL);
527  cuddRef(res1);
528  res2 = cuddAddOrAbstractRecur(manager, E, cube);
529  if (res2 == NULL) {
530  Cudd_RecursiveDeref(manager,res1);
531  return(NULL);
532  }
533  cuddRef(res2);
534  res = (res1 == res2) ? res1 :
535  cuddUniqueInter(manager, (int) f->index, res1, res2);
536  if (res == NULL) {
537  Cudd_RecursiveDeref(manager,res1);
538  Cudd_RecursiveDeref(manager,res2);
539  return(NULL);
540  }
541  cuddDeref(res1);
542  cuddDeref(res2);
543  cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res);
544  return(res);
545  }
546 
547 } /* end of cuddAddOrAbstractRecur */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
DdNode * Cudd_addOr(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:581
DdNode * cuddAddApplyRecur(DdManager *dd, DD_AOP op, DdNode *f, DdNode *g)
Definition: cuddAddApply.c:809
DdNode * Cudd_addOrAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:216
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
DdNode * cuddAddOrAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:469
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
DdNode* cuddAddRestrictRecur ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Performs the recursive step of Cudd_addRestrict.]

Description [Performs the recursive step of Cudd_addRestrict. Returns the restricted ADD if successful; otherwise NULL.]

SideEffects [None]

SeeAlso [Cudd_addRestrict]

Definition at line 1307 of file cuddGenCof.c.

1311 {
1312  DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero;
1313  unsigned int topf, topc;
1314  int index;
1315 
1316  statLine(dd);
1317  one = DD_ONE(dd);
1318  zero = DD_ZERO(dd);
1319 
1320  /* Trivial cases */
1321  if (c == one) return(f);
1322  if (c == zero) return(zero);
1323  if (Cudd_IsConstant(f)) return(f);
1324  if (f == c) return(one);
1325 
1326  /* Now f and c are non-constant. */
1327 
1328  /* Check the cache. */
1329  r = cuddCacheLookup2(dd, Cudd_addRestrict, f, c);
1330  if (r != NULL) {
1331  return(r);
1332  }
1333 
1334  topf = dd->perm[f->index];
1335  topc = dd->perm[c->index];
1336 
1337  if (topc < topf) { /* abstract top variable from c */
1338  DdNode *d, *s1, *s2;
1339 
1340  /* Find cofactors of c. */
1341  s1 = cuddT(c);
1342  s2 = cuddE(c);
1343  /* Take the OR by applying DeMorgan. */
1344  d = cuddAddApplyRecur(dd, Cudd_addOr, s1, s2);
1345  if (d == NULL) return(NULL);
1346  cuddRef(d);
1347  r = cuddAddRestrictRecur(dd, f, d);
1348  if (r == NULL) {
1349  Cudd_RecursiveDeref(dd, d);
1350  return(NULL);
1351  }
1352  cuddRef(r);
1353  Cudd_RecursiveDeref(dd, d);
1354  cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r);
1355  cuddDeref(r);
1356  return(r);
1357  }
1358 
1359  /* Recursive step. Here topf <= topc. */
1360  index = f->index;
1361  Fv = cuddT(f); Fnv = cuddE(f);
1362  if (topc == topf) {
1363  Cv = cuddT(c); Cnv = cuddE(c);
1364  } else {
1365  Cv = Cnv = c;
1366  }
1367 
1368  if (!Cudd_IsConstant(Cv)) {
1369  t = cuddAddRestrictRecur(dd, Fv, Cv);
1370  if (t == NULL) return(NULL);
1371  } else if (Cv == one) {
1372  t = Fv;
1373  } else { /* Cv == zero: return(Fnv @ Cnv) */
1374  if (Cnv == one) {
1375  r = Fnv;
1376  } else {
1377  r = cuddAddRestrictRecur(dd, Fnv, Cnv);
1378  if (r == NULL) return(NULL);
1379  }
1380  return(r);
1381  }
1382  cuddRef(t);
1383 
1384  if (!Cudd_IsConstant(Cnv)) {
1385  e = cuddAddRestrictRecur(dd, Fnv, Cnv);
1386  if (e == NULL) {
1387  Cudd_RecursiveDeref(dd, t);
1388  return(NULL);
1389  }
1390  } else if (Cnv == one) {
1391  e = Fnv;
1392  } else { /* Cnv == zero: return (Fv @ Cv) previously computed */
1393  cuddDeref(t);
1394  return(t);
1395  }
1396  cuddRef(e);
1397 
1398  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
1399  if (r == NULL) {
1400  Cudd_RecursiveDeref(dd, e);
1401  Cudd_RecursiveDeref(dd, t);
1402  return(NULL);
1403  }
1404  cuddDeref(t);
1405  cuddDeref(e);
1406 
1407  cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r);
1408  return(r);
1409 
1410 } /* end of cuddAddRestrictRecur */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
DdNode * Cudd_addOr(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:581
#define Cudd_IsConstant(node)
Definition: cudd.h:352
DdNode * cuddAddApplyRecur(DdManager *dd, DD_AOP op, DdNode *f, DdNode *g)
Definition: cuddAddApply.c:809
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
static DdNode * one
Definition: cuddDecomp.c:112
static char s1[largest_string]
Definition: set.c:514
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * Cudd_addRestrict(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:431
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * cuddAddRestrictRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:1307
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
#define DD_ZERO(dd)
Definition: cuddInt.h:927
DdNode* cuddAddRoundOffRecur ( DdManager dd,
DdNode f,
double  trunc 
)

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

Synopsis [Implements the recursive step of Cudd_addRoundOff.]

Description [Implements the recursive step of Cudd_addRoundOff. Returns a pointer to the result.]

SideEffects [None]

Definition at line 240 of file cuddAddNeg.c.

244 {
245 
246  DdNode *res, *fv, *fvn, *T, *E;
247  double n;
248  DD_CTFP1 cacheOp;
249 
250  statLine(dd);
251  if (cuddIsConstant(f)) {
252  n = ceil(cuddV(f)*trunc)/trunc;
253  res = cuddUniqueConst(dd,n);
254  return(res);
255  }
256  cacheOp = (DD_CTFP1) Cudd_addRoundOff;
257  res = cuddCacheLookup1(dd,cacheOp,f);
258  if (res != NULL) {
259  return(res);
260  }
261  /* Recursive Step */
262  fv = cuddT(f);
263  fvn = cuddE(f);
264  T = cuddAddRoundOffRecur(dd,fv,trunc);
265  if (T == NULL) {
266  return(NULL);
267  }
268  cuddRef(T);
269  E = cuddAddRoundOffRecur(dd,fvn,trunc);
270  if (E == NULL) {
271  Cudd_RecursiveDeref(dd,T);
272  return(NULL);
273  }
274  cuddRef(E);
275  res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E);
276  if (res == NULL) {
277  Cudd_RecursiveDeref(dd,T);
278  Cudd_RecursiveDeref(dd,E);
279  return(NULL);
280  }
281  cuddDeref(T);
282  cuddDeref(E);
283 
284  /* Store result. */
285  cuddCacheInsert1(dd,cacheOp,f,res);
286  return(res);
287 
288 } /* end of cuddAddRoundOffRecur */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
Definition: cuddTable.c:1450
DdNode *(* DD_CTFP1)(DdManager *, DdNode *)
Definition: cudd.h:322
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * Cudd_addRoundOff(DdManager *dd, DdNode *f, int N)
Definition: cuddAddNeg.c:148
#define cuddV(node)
Definition: cuddInt.h:668
DdNode * cuddCacheLookup1(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddCache.c:556
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
DdNode * cuddAddRoundOffRecur(DdManager *dd, DdNode *f, double trunc)
Definition: cuddAddNeg.c:240
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddCache.c:323
DdNode* cuddAddScalarInverseRecur ( DdManager dd,
DdNode f,
DdNode epsilon 
)

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

Synopsis [Performs the recursive step of addScalarInverse.]

Description [Returns a pointer to the resulting ADD in case of success. Returns NULL if any discriminants smaller than epsilon is encountered.]

SideEffects [None]

Definition at line 156 of file cuddAddInv.c.

160 {
161  DdNode *t, *e, *res;
163 
164  statLine(dd);
165  if (cuddIsConstant(f)) {
166  if (ddAbs(cuddV(f)) < cuddV(epsilon)) return(NULL);
167  value = 1.0 / cuddV(f);
168  res = cuddUniqueConst(dd,value);
169  return(res);
170  }
171 
172  res = cuddCacheLookup2(dd,Cudd_addScalarInverse,f,epsilon);
173  if (res != NULL) return(res);
174 
175  t = cuddAddScalarInverseRecur(dd,cuddT(f),epsilon);
176  if (t == NULL) return(NULL);
177  cuddRef(t);
178 
179  e = cuddAddScalarInverseRecur(dd,cuddE(f),epsilon);
180  if (e == NULL) {
181  Cudd_RecursiveDeref(dd, t);
182  return(NULL);
183  }
184  cuddRef(e);
185 
186  res = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e);
187  if (res == NULL) {
188  Cudd_RecursiveDeref(dd, t);
189  Cudd_RecursiveDeref(dd, e);
190  return(NULL);
191  }
192  cuddDeref(t);
193  cuddDeref(e);
194 
195  cuddCacheInsert2(dd,Cudd_addScalarInverse,f,epsilon,res);
196 
197  return(res);
198 
199 } /* end of cuddAddScalarInverseRecur */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
Definition: cuddTable.c:1450
#define statLine(dd)
Definition: cuddInt.h:1037
#define cuddV(node)
Definition: cuddInt.h:668
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define ddAbs(x)
Definition: cuddInt.h:846
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
#define CUDD_VALUE_TYPE
Definition: cudd.h:94
DdNode * cuddAddScalarInverseRecur(DdManager *dd, DdNode *f, DdNode *epsilon)
Definition: cuddAddInv.c:156
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
int value
DdNode * Cudd_addScalarInverse(DdManager *dd, DdNode *f, DdNode *epsilon)
Definition: cuddAddInv.c:120
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
DdNode* cuddAddUnivAbstractRecur ( DdManager manager,
DdNode f,
DdNode cube 
)

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

Synopsis [Performs the recursive step of Cudd_addUnivAbstract.]

Description [Performs the recursive step of Cudd_addUnivAbstract. Returns the ADD obtained by abstracting the variables of cube from f, if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 361 of file cuddAddAbs.c.

365 {
366  DdNode *T, *E, *res, *res1, *res2, *one, *zero;
367 
368  statLine(manager);
369  one = DD_ONE(manager);
370  zero = DD_ZERO(manager);
371 
372  /* Cube is guaranteed to be a cube at this point.
373  ** zero and one are the only constatnts c such that c*c=c.
374  */
375  if (f == zero || f == one || cube == one) {
376  return(f);
377  }
378 
379  /* Abstract a variable that does not appear in f. */
380  if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
381  res1 = cuddAddUnivAbstractRecur(manager, f, cuddT(cube));
382  if (res1 == NULL) return(NULL);
383  cuddRef(res1);
384  /* Use the "internal" procedure to be alerted in case of
385  ** dynamic reordering. If dynamic reordering occurs, we
386  ** have to abort the entire abstraction.
387  */
388  res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res1);
389  if (res == NULL) {
390  Cudd_RecursiveDeref(manager,res1);
391  return(NULL);
392  }
393  cuddRef(res);
394  Cudd_RecursiveDeref(manager,res1);
395  cuddDeref(res);
396  return(res);
397  }
398 
399  if ((res = cuddCacheLookup2(manager, Cudd_addUnivAbstract, f, cube)) != NULL) {
400  return(res);
401  }
402 
403  T = cuddT(f);
404  E = cuddE(f);
405 
406  /* If the two indices are the same, so are their levels. */
407  if (f->index == cube->index) {
408  res1 = cuddAddUnivAbstractRecur(manager, T, cuddT(cube));
409  if (res1 == NULL) return(NULL);
410  cuddRef(res1);
411  res2 = cuddAddUnivAbstractRecur(manager, E, cuddT(cube));
412  if (res2 == NULL) {
413  Cudd_RecursiveDeref(manager,res1);
414  return(NULL);
415  }
416  cuddRef(res2);
417  res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res2);
418  if (res == NULL) {
419  Cudd_RecursiveDeref(manager,res1);
420  Cudd_RecursiveDeref(manager,res2);
421  return(NULL);
422  }
423  cuddRef(res);
424  Cudd_RecursiveDeref(manager,res1);
425  Cudd_RecursiveDeref(manager,res2);
426  cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res);
427  cuddDeref(res);
428  return(res);
429  } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
430  res1 = cuddAddUnivAbstractRecur(manager, T, cube);
431  if (res1 == NULL) return(NULL);
432  cuddRef(res1);
433  res2 = cuddAddUnivAbstractRecur(manager, E, cube);
434  if (res2 == NULL) {
435  Cudd_RecursiveDeref(manager,res1);
436  return(NULL);
437  }
438  cuddRef(res2);
439  res = (res1 == res2) ? res1 :
440  cuddUniqueInter(manager, (int) f->index, res1, res2);
441  if (res == NULL) {
442  Cudd_RecursiveDeref(manager,res1);
443  Cudd_RecursiveDeref(manager,res2);
444  return(NULL);
445  }
446  cuddDeref(res1);
447  cuddDeref(res2);
448  cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res);
449  return(res);
450  }
451 
452 } /* end of cuddAddUnivAbstractRecur */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
DdNode * cuddAddUnivAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:361
DdNode * cuddAddApplyRecur(DdManager *dd, DD_AOP op, DdNode *f, DdNode *g)
Definition: cuddAddApply.c:809
DdNode * Cudd_addUnivAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddAddAbs.c:178
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * Cudd_addTimes(DdManager *dd, DdNode **f, DdNode **g)
Definition: cuddAddApply.c:208
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 235 of file cuddTable.c.

237 {
238  int i;
239  DdNodePtr *mem;
240  DdNode *list, *node;
241  extern DD_OOMFP MMoutOfMemory;
242  DD_OOMFP saveHandler;
243 
244  if (unique->nextFree == NULL) { /* free list is empty */
245  /* Check for exceeded limits. */
246  if ((unique->keys - unique->dead) + (unique->keysZ - unique->deadZ) >
247  unique->maxLive) {
248  unique->errorCode = CUDD_TOO_MANY_NODES;
249  return(NULL);
250  }
251  if (unique->stash == NULL || unique->memused > unique->maxmemhard) {
252  (void) cuddGarbageCollect(unique,1);
253  mem = NULL;
254  }
255  if (unique->nextFree == NULL) {
256  if (unique->memused > unique->maxmemhard) {
258  return(NULL);
259  }
260  /* Try to allocate a new block. */
261  saveHandler = MMoutOfMemory;
262  MMoutOfMemory = Cudd_OutOfMem;
263 // mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1);
264  mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 2);
265  MMoutOfMemory = saveHandler;
266  if (mem == NULL) {
267  /* No more memory: Try collecting garbage. If this succeeds,
268  ** we end up with mem still NULL, but unique->nextFree !=
269  ** NULL. */
270  if (cuddGarbageCollect(unique,1) == 0) {
271  /* Last resort: Free the memory stashed away, if there
272  ** any. If this succeeeds, mem != NULL and
273  ** unique->nextFree still NULL. */
274  if (unique->stash != NULL) {
275  ABC_FREE(unique->stash);
276  unique->stash = NULL;
277  /* Inhibit resizing of tables. */
278  cuddSlowTableGrowth(unique);
279  /* Now try again. */
280 // mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1);
281  mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 2);
282  }
283  if (mem == NULL) {
284  /* Out of luck. Call the default handler to do
285  ** whatever it specifies for a failed malloc.
286  ** If this handler returns, then set error code,
287  ** print warning, and return. */
288  (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1));
289  unique->errorCode = CUDD_MEMORY_OUT;
290 #ifdef DD_VERBOSE
291  (void) fprintf(unique->err,
292  "cuddAllocNode: out of memory");
293  (void) fprintf(unique->err, "Memory in use = %lu\n",
294  unique->memused);
295 #endif
296  return(NULL);
297  }
298  }
299  }
300  if (mem != NULL) { /* successful allocation; slice memory */
301  ptruint offset;
302  unique->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode);
303  mem[0] = (DdNodePtr) unique->memoryList;
304  unique->memoryList = mem;
305 
306  /* Here we rely on the fact that a DdNode is as large as 4 pointers. */
307 // offset = (ptruint) mem & (sizeof(DdNode) - 1);
308 // mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr);
309 // assert(((ptruint) mem & (sizeof(DdNode) - 1)) == 0);
310 // list = (DdNode *) mem;
311  offset = (ptruint) mem & (32 - 1);
312  mem += (32 - offset) / sizeof(DdNodePtr);
313  assert(((ptruint) mem & (32 - 1)) == 0);
314  list = (DdNode *) mem;
315 
316  i = 1;
317  do {
318  list[i - 1].ref = 0;
319  list[i - 1].next = &list[i];
320  } while (++i < DD_MEM_CHUNK);
321 
322  list[DD_MEM_CHUNK-1].ref = 0;
323  list[DD_MEM_CHUNK-1].next = NULL;
324 
325  unique->nextFree = &list[0];
326  }
327  }
328  }
329  unique->allocated++;
330  node = unique->nextFree;
331  unique->nextFree = node->next;
332  node->Id = (unique->allocated<<4);
333  return(node);
334 
335 } /* end of cuddAllocNode */
DdHalfWord ref
Definition: cudd.h:280
ABC_INT64_T allocated
Definition: cuddInt.h:382
void(* DD_OOMFP)(long)
Definition: cudd.h:324
ABC_INT64_T Id
Definition: cudd.h:286
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2837
Definition: cudd.h:278
unsigned int deadZ
Definition: cuddInt.h:372
FILE * err
Definition: cuddInt.h:442
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdNode * DdNodePtr
Definition: cuddInt.h:268
struct DdNode DdNode
Definition: cudd.h:270
ABC_PTRUINT_T ptruint
Definition: cuddInt.h:261
unsigned int dead
Definition: cuddInt.h:371
unsigned int maxLive
Definition: cuddInt.h:373
char * stash
Definition: cuddInt.h:399
unsigned int keys
Definition: cuddInt.h:369
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:729
DdNode * next
Definition: cudd.h:281
DdNode ** memoryList
Definition: cuddInt.h:397
void cuddSlowTableGrowth(DdManager *unique)
Definition: cuddTable.c:2385
unsigned long memused
Definition: cuddInt.h:449
DdNode * nextFree
Definition: cuddInt.h:398
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned long maxmemhard
Definition: cuddInt.h:451
#define assert(ex)
Definition: util_old.h:213
#define DD_MEM_CHUNK
Definition: cuddInt.h:104
unsigned int keysZ
Definition: cuddInt.h:370
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
#define MMoutOfMemory
Definition: util_hack.h:38
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 158 of file cuddAnneal.c.

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

1253 {
1254  int *invperm; /* permutation array */
1255  int M; /* ratio of ZDD variables to BDD variables */
1256  int i; /* loop index */
1257  int result; /* return value */
1258 
1259  /* We assume that a ratio of 0 is OK. */
1260  if (table->size == 0)
1261  return(1);
1262 
1263  M = table->sizeZ / table->size;
1264  /* Check whether the number of ZDD variables is a multiple of the
1265  ** number of BDD variables.
1266  */
1267  if (M * table->size != table->sizeZ)
1268  return(0);
1269  /* Create and initialize the inverse permutation array. */
1270  invperm = ABC_ALLOC(int,table->size);
1271  if (invperm == NULL) {
1272  table->errorCode = CUDD_MEMORY_OUT;
1273  return(0);
1274  }
1275  for (i = 0; i < table->sizeZ; i += M) {
1276  int indexZ = table->invpermZ[i];
1277  int index = indexZ / M;
1278  invperm[i / M] = index;
1279  }
1280  /* Eliminate dead nodes. Do not scan the cache again, because we
1281  ** assume that Cudd_zddReduceHeap has already cleared it.
1282  */
1283  cuddGarbageCollect(table,0);
1284 
1285  /* Initialize number of isolated projection functions. */
1286  table->isolated = 0;
1287  for (i = 0; i < table->size; i++) {
1288  if (table->vars[i]->ref == 1) table->isolated++;
1289  }
1290 
1291  /* Initialize the interaction matrix. */
1292  result = cuddInitInteract(table);
1293  if (result == 0) return(0);
1294 
1295  result = ddShuffle(table, invperm);
1296  ABC_FREE(invperm);
1297  /* Free interaction matrix. */
1298  ABC_FREE(table->interact);
1299  /* Fix the BDD variable group tree. */
1300  bddFixTree(table,table->tree);
1301  return(result);
1302 
1303 } /* end of cuddBddAlignToZdd */
DdHalfWord ref
Definition: cudd.h:280
int * invpermZ
Definition: cuddInt.h:389
int size
Definition: cuddInt.h:361
int cuddInitInteract(DdManager *table)
Definition: cuddInteract.c:237
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
MtrNode * tree
Definition: cuddInt.h:424
static void bddFixTree(DdManager *table, MtrNode *treenode)
Definition: cuddReorder.c:2010
word M(word f1, word f2, int n)
Definition: kitPerm.c:240
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:729
long * interact
Definition: cuddInt.h:394
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdNode ** vars
Definition: cuddInt.h:390
static int ddShuffle(DdManager *table, int *permutation)
Definition: cuddReorder.c:1897
static int result
Definition: cuddGenetic.c:125
int isolated
Definition: cuddInt.h:385
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdNode* cuddBddAndAbstractRecur ( DdManager manager,
DdNode f,
DdNode g,
DdNode cube 
)

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

Synopsis [Takes the AND of two BDDs and simultaneously abstracts the variables in cube.]

Description [Takes the AND of two BDDs and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the result is successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddAndAbstract]

Definition at line 200 of file cuddAndAbs.c.

205 {
206  DdNode *F, *ft, *fe, *G, *gt, *ge;
207  DdNode *one, *zero, *r, *t, *e;
208  unsigned int topf, topg, topcube, top, index;
209 
210  statLine(manager);
211  one = DD_ONE(manager);
212  zero = Cudd_Not(one);
213 
214  /* Terminal cases. */
215  if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
216  if (f == one && g == one) return(one);
217 
218  if (cube == one) {
219  return(cuddBddAndRecur(manager, f, g));
220  }
221  if (f == one || f == g) {
222  return(cuddBddExistAbstractRecur(manager, g, cube));
223  }
224  if (g == one) {
225  return(cuddBddExistAbstractRecur(manager, f, cube));
226  }
227  /* At this point f, g, and cube are not constant. */
228 
229  if (f > g) { /* Try to increase cache efficiency. */
230  DdNode *tmp = f;
231  f = g;
232  g = tmp;
233  }
234 
235  /* Here we can skip the use of cuddI, because the operands are known
236  ** to be non-constant.
237  */
238  F = Cudd_Regular(f);
239  G = Cudd_Regular(g);
240  topf = manager->perm[F->index];
241  topg = manager->perm[G->index];
242  top = ddMin(topf, topg);
243  topcube = manager->perm[cube->index];
244 
245  while (topcube < top) {
246  cube = cuddT(cube);
247  if (cube == one) {
248  return(cuddBddAndRecur(manager, f, g));
249  }
250  topcube = manager->perm[cube->index];
251  }
252  /* Now, topcube >= top. */
253 
254  /* Check cache. */
255  if (F->ref != 1 || G->ref != 1) {
256  r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube);
257  if (r != NULL) {
258  return(r);
259  }
260  }
261 
262  if ( manager->TimeStop && Abc_Clock() > manager->TimeStop )
263  return NULL;
264 
265  if (topf == top) {
266  index = F->index;
267  ft = cuddT(F);
268  fe = cuddE(F);
269  if (Cudd_IsComplement(f)) {
270  ft = Cudd_Not(ft);
271  fe = Cudd_Not(fe);
272  }
273  } else {
274  index = G->index;
275  ft = fe = f;
276  }
277 
278  if (topg == top) {
279  gt = cuddT(G);
280  ge = cuddE(G);
281  if (Cudd_IsComplement(g)) {
282  gt = Cudd_Not(gt);
283  ge = Cudd_Not(ge);
284  }
285  } else {
286  gt = ge = g;
287  }
288 
289  if (topcube == top) { /* quantify */
290  DdNode *Cube = cuddT(cube);
291  t = cuddBddAndAbstractRecur(manager, ft, gt, Cube);
292  if (t == NULL) return(NULL);
293  /* Special case: 1 OR anything = 1. Hence, no need to compute
294  ** the else branch if t is 1. Likewise t + t * anything == t.
295  ** Notice that t == fe implies that fe does not depend on the
296  ** variables in Cube. Likewise for t == ge.
297  */
298  if (t == one || t == fe || t == ge) {
299  if (F->ref != 1 || G->ref != 1)
301  f, g, cube, t);
302  return(t);
303  }
304  cuddRef(t);
305  /* Special case: t + !t * anything == t + anything. */
306  if (t == Cudd_Not(fe)) {
307  e = cuddBddExistAbstractRecur(manager, ge, Cube);
308  } else if (t == Cudd_Not(ge)) {
309  e = cuddBddExistAbstractRecur(manager, fe, Cube);
310  } else {
311  e = cuddBddAndAbstractRecur(manager, fe, ge, Cube);
312  }
313  if (e == NULL) {
314  Cudd_IterDerefBdd(manager, t);
315  return(NULL);
316  }
317  if (t == e) {
318  r = t;
319  cuddDeref(t);
320  } else {
321  cuddRef(e);
322  r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e));
323  if (r == NULL) {
324  Cudd_IterDerefBdd(manager, t);
325  Cudd_IterDerefBdd(manager, e);
326  return(NULL);
327  }
328  r = Cudd_Not(r);
329  cuddRef(r);
330  Cudd_DelayedDerefBdd(manager, t);
331  Cudd_DelayedDerefBdd(manager, e);
332  cuddDeref(r);
333  }
334  } else {
335  t = cuddBddAndAbstractRecur(manager, ft, gt, cube);
336  if (t == NULL) return(NULL);
337  cuddRef(t);
338  e = cuddBddAndAbstractRecur(manager, fe, ge, cube);
339  if (e == NULL) {
340  Cudd_IterDerefBdd(manager, t);
341  return(NULL);
342  }
343  if (t == e) {
344  r = t;
345  cuddDeref(t);
346  } else {
347  cuddRef(e);
348  if (Cudd_IsComplement(t)) {
349  r = cuddUniqueInter(manager, (int) index,
350  Cudd_Not(t), Cudd_Not(e));
351  if (r == NULL) {
352  Cudd_IterDerefBdd(manager, t);
353  Cudd_IterDerefBdd(manager, e);
354  return(NULL);
355  }
356  r = Cudd_Not(r);
357  } else {
358  r = cuddUniqueInter(manager,(int)index,t,e);
359  if (r == NULL) {
360  Cudd_IterDerefBdd(manager, t);
361  Cudd_IterDerefBdd(manager, e);
362  return(NULL);
363  }
364  }
365  cuddDeref(e);
366  cuddDeref(t);
367  }
368  }
369 
370  if (F->ref != 1 || G->ref != 1)
371  cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r);
372  return (r);
373 
374 } /* end of cuddBddAndAbstractRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
DdHalfWord ref
Definition: cudd.h:280
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:352
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
abctime TimeStop
Definition: cuddInt.h:489
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
DdNode * cuddBddAndAbstractRecur(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
Definition: cuddAndAbs.c:200
static abctime Abc_Clock()
Definition: abc_global.h:279
#define statLine(dd)
Definition: cuddInt.h:1037
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define ddMin(x, y)
Definition: cuddInt.h:818
#define cuddT(node)
Definition: cuddInt.h:636
#define DD_BDD_AND_ABSTRACT_TAG
Definition: cuddInt.h:173
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
void Cudd_DelayedDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:274
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:369
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 886 of file cuddBddIte.c.

890 {
891  DdNode *F, *fv, *fnv, *G, *gv, *gnv;
892  DdNode *one, *r, *t, *e;
893  unsigned int topf, topg, index;
894 
895  statLine(manager);
896  one = DD_ONE(manager);
897 
898  /* Terminal cases. */
899  F = Cudd_Regular(f);
900  G = Cudd_Regular(g);
901  if (F == G) {
902  if (f == g) return(f);
903  else return(Cudd_Not(one));
904  }
905  if (F == one) {
906  if (f == one) return(g);
907  else return(f);
908  }
909  if (G == one) {
910  if (g == one) return(f);
911  else return(g);
912  }
913 
914  /* At this point f and g are not constant. */
915  if (cuddF2L(f) > cuddF2L(g)) { /* Try to increase cache efficiency. */
916  DdNode *tmp = f;
917  f = g;
918  g = tmp;
919  F = Cudd_Regular(f);
920  G = Cudd_Regular(g);
921  }
922 
923  /* Check cache. */
924  if (F->ref != 1 || G->ref != 1) {
925  r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g);
926  if (r != NULL) return(r);
927  }
928 
929  if ( manager->TimeStop && Abc_Clock() > manager->TimeStop )
930  return NULL;
931 
932  /* Here we can skip the use of cuddI, because the operands are known
933  ** to be non-constant.
934  */
935  topf = manager->perm[F->index];
936  topg = manager->perm[G->index];
937 
938  /* Compute cofactors. */
939  if (topf <= topg) {
940  index = F->index;
941  fv = cuddT(F);
942  fnv = cuddE(F);
943  if (Cudd_IsComplement(f)) {
944  fv = Cudd_Not(fv);
945  fnv = Cudd_Not(fnv);
946  }
947  } else {
948  index = G->index;
949  fv = fnv = f;
950  }
951 
952  if (topg <= topf) {
953  gv = cuddT(G);
954  gnv = cuddE(G);
955  if (Cudd_IsComplement(g)) {
956  gv = Cudd_Not(gv);
957  gnv = Cudd_Not(gnv);
958  }
959  } else {
960  gv = gnv = g;
961  }
962 
963  t = cuddBddAndRecur(manager, fv, gv);
964  if (t == NULL) return(NULL);
965  cuddRef(t);
966 
967  e = cuddBddAndRecur(manager, fnv, gnv);
968  if (e == NULL) {
969  Cudd_IterDerefBdd(manager, t);
970  return(NULL);
971  }
972  cuddRef(e);
973 
974  if (t == e) {
975  r = t;
976  } else {
977  if (Cudd_IsComplement(t)) {
978  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
979  if (r == NULL) {
980  Cudd_IterDerefBdd(manager, t);
981  Cudd_IterDerefBdd(manager, e);
982  return(NULL);
983  }
984  r = Cudd_Not(r);
985  } else {
986  r = cuddUniqueInter(manager,(int)index,t,e);
987  if (r == NULL) {
988  Cudd_IterDerefBdd(manager, t);
989  Cudd_IterDerefBdd(manager, e);
990  return(NULL);
991  }
992  }
993  }
994  cuddDeref(e);
995  cuddDeref(t);
996  if (F->ref != 1 || G->ref != 1)
997  cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r);
998  return(r);
999 
1000 } /* end of cuddBddAndRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
DdHalfWord ref
Definition: cudd.h:280
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
abctime TimeStop
Definition: cuddInt.h:489
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
static abctime Abc_Clock()
Definition: abc_global.h:279
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddF2L(f)
Definition: cuddInt.h:718
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:314
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
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 636 of file cuddBddAbs.c.

640 {
641  DdNode *T, *E, *res, *res1, *res2;
642 
643  statLine(manager);
644  if (cuddI(manager,f->index) > manager->perm[var->index]) {
645  /* f does not depend on var. */
646  return(Cudd_Not(DD_ONE(manager)));
647  }
648 
649  /* From now on, f is non-constant. */
650 
651  /* If the two indices are the same, so are their levels. */
652  if (f->index == var->index) {
653  res = cuddBddXorRecur(manager, cuddT(f), cuddE(f));
654  return(res);
655  }
656 
657  /* From now on, cuddI(manager,f->index) < cuddI(manager,cube->index). */
658 
659  /* Check the cache. */
660  res = cuddCacheLookup2(manager, cuddBddBooleanDiffRecur, f, var);
661  if (res != NULL) {
662  return(res);
663  }
664 
665  /* Compute the cofactors of f. */
666  T = cuddT(f); E = cuddE(f);
667 
668  res1 = cuddBddBooleanDiffRecur(manager, T, var);
669  if (res1 == NULL) return(NULL);
670  cuddRef(res1);
671  res2 = cuddBddBooleanDiffRecur(manager, Cudd_Regular(E), var);
672  if (res2 == NULL) {
673  Cudd_IterDerefBdd(manager, res1);
674  return(NULL);
675  }
676  cuddRef(res2);
677  /* ITE takes care of possible complementation of res1 and of the
678  ** case in which res1 == res2. */
679  res = cuddBddIteRecur(manager, manager->vars[f->index], res1, res2);
680  if (res == NULL) {
681  Cudd_IterDerefBdd(manager, res1);
682  Cudd_IterDerefBdd(manager, res2);
683  return(NULL);
684  }
685  cuddDeref(res1);
686  cuddDeref(res2);
687  cuddCacheInsert2(manager, cuddBddBooleanDiffRecur, f, var, res);
688  return(res);
689 
690 } /* end of cuddBddBooleanDiffRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
DdNode * cuddBddBooleanDiffRecur(DdManager *manager, DdNode *f, DdNode *var)
Definition: cuddBddAbs.c:636
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
DdNode ** vars
Definition: cuddInt.h:390
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1017
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633
DdNode* cuddBddClippingAnd ( DdManager dd,
DdNode f,
DdNode g,
int  maxDepth,
int  direction 
)

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

Synopsis [Approximates the conjunction of two BDDs f and g.]

Description [Approximates the conjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_bddClippingAnd]

Definition at line 201 of file cuddClip.c.

207 {
208  DdNode *res;
209 
210  res = cuddBddClippingAndRecur(dd,f,g,maxDepth,direction);
211 
212  return(res);
213 
214 } /* end of cuddBddClippingAnd */
Definition: cudd.h:278
static DdNode * cuddBddClippingAndRecur(DdManager *manager, DdNode *f, DdNode *g, int distance, int direction)
Definition: cuddClip.c:269
DdNode* cuddBddClippingAndAbstract ( DdManager dd,
DdNode f,
DdNode g,
DdNode cube,
int  maxDepth,
int  direction 
)

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

Synopsis [Approximates the conjunction of two BDDs f and g and simultaneously abstracts the variables in cube.]

Description [Approximates the conjunction of two BDDs f and g and simultaneously abstracts the variables in cube. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_bddClippingAndAbstract]

Definition at line 233 of file cuddClip.c.

240 {
241  DdNode *res;
242 
243  res = cuddBddClipAndAbsRecur(dd,f,g,cube,maxDepth,direction);
244 
245  return(res);
246 
247 } /* end of cuddBddClippingAndAbstract */
Definition: cudd.h:278
static DdNode * cuddBddClipAndAbsRecur(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int distance, int direction)
Definition: cuddClip.c:405
DdNode* cuddBddClosestCube ( DdManager dd,
DdNode f,
DdNode g,
CUDD_VALUE_TYPE  bound 
)

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

Synopsis [Performs the recursive step of Cudd_bddClosestCube.]

Description [Performs the recursive step of Cudd_bddClosestCube. Returns the cube if succesful; NULL otherwise. The procedure uses a four-way recursion to examine all four combinations of cofactors of f and g according to the following formula.

  H(f,g) = min(H(ft,gt), H(fe,ge), H(ft,ge)+1, H(fe,gt)+1)

Bounding is based on the following observations.

  • If we already found two points at distance 0, there is no point in continuing. Furthermore,
  • If F == not(G) then the best we can hope for is a minimum distance of 1. If we have already found two points at distance 1, there is no point in continuing. (Indeed, H(F,G) == 1 in this case. We have to continue, though, to find the cube.)

The variable bound is set at the largest value of the distance that we are still interested in. Therefore, we desist when

  (bound == -1) and (F != not(G)) or (bound == 0) and (F == not(G)).

If we were maximally aggressive in using the bound, we would always set the bound to the minimum distance seen thus far minus one. That is, we would maintain the invariant

  bound < minD,

except at the very beginning, when we have no value for minD.

However, we do not use bound < minD when examining the two negative cofactors, because we try to find a large cube at minimum distance. To do so, we try to find a cube in the negative cofactors at the same or smaller distance from the cube found in the positive cofactors.

When we compute H(ft,ge) and H(fe,gt) we know that we are going to add 1 to the result of the recursive call to account for the difference in the splitting variable. Therefore, we decrease the bound correspondingly.

Another important observation concerns the need of examining all four pairs of cofators only when both f and g depend on the top variable.

Suppose gt == ge == g. (That is, g does not depend on the top variable.) Then

  H(f,g) = min(H(ft,g), H(fe,g), H(ft,g)+1, H(fe,g)+1)
         = min(H(ft,g), H(fe,g)) .

Therefore, under these circumstances, we skip the two "cross" cases.

An interesting feature of this function is the scheme used for caching the results in the global computed table. Since we have a cube and a distance, we combine them to form an ADD. The combination replaces the zero child of the top node of the cube with the negative of the distance. (The use of the negative is to avoid ambiguity with 1.) The degenerate cases (zero and one) are treated specially because the distance is known (0 for one, and infinity for zero).]

SideEffects [None]

SeeAlso [Cudd_bddClosestCube]

Definition at line 1646 of file cuddPriority.c.

1651 {
1652  DdNode *res, *F, *G, *ft, *fe, *gt, *ge, *tt, *ee;
1653  DdNode *ctt, *cee, *cte, *cet;
1654  CUDD_VALUE_TYPE minD, dtt, dee, dte, det;
1655  DdNode *one = DD_ONE(dd);
1656  DdNode *lzero = Cudd_Not(one);
1657  DdNode *azero = DD_ZERO(dd);
1658  unsigned int topf, topg, index;
1659 
1660  statLine(dd);
1661  if (bound < (int)(f == Cudd_Not(g))) return(azero);
1662  /* Terminal cases. */
1663  if (g == lzero || f == lzero) return(azero);
1664  if (f == one && g == one) return(one);
1665 
1666  /* Check cache. */
1667  F = Cudd_Regular(f);
1668  G = Cudd_Regular(g);
1669  if (F->ref != 1 || G->ref != 1) {
1670  res = cuddCacheLookup2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g);
1671  if (res != NULL) return(res);
1672  }
1673 
1674  topf = cuddI(dd,F->index);
1675  topg = cuddI(dd,G->index);
1676 
1677  /* Compute cofactors. */
1678  if (topf <= topg) {
1679  index = F->index;
1680  ft = cuddT(F);
1681  fe = cuddE(F);
1682  if (Cudd_IsComplement(f)) {
1683  ft = Cudd_Not(ft);
1684  fe = Cudd_Not(fe);
1685  }
1686  } else {
1687  index = G->index;
1688  ft = fe = f;
1689  }
1690 
1691  if (topg <= topf) {
1692  gt = cuddT(G);
1693  ge = cuddE(G);
1694  if (Cudd_IsComplement(g)) {
1695  gt = Cudd_Not(gt);
1696  ge = Cudd_Not(ge);
1697  }
1698  } else {
1699  gt = ge = g;
1700  }
1701 
1702  tt = cuddBddClosestCube(dd,ft,gt,bound);
1703  if (tt == NULL) return(NULL);
1704  cuddRef(tt);
1705  ctt = separateCube(dd,tt,&dtt);
1706  if (ctt == NULL) {
1707  Cudd_RecursiveDeref(dd, tt);
1708  return(NULL);
1709  }
1710  cuddRef(ctt);
1711  Cudd_RecursiveDeref(dd, tt);
1712  minD = dtt;
1713  bound = ddMin(bound,minD);
1714 
1715  ee = cuddBddClosestCube(dd,fe,ge,bound);
1716  if (ee == NULL) {
1717  Cudd_RecursiveDeref(dd, ctt);
1718  return(NULL);
1719  }
1720  cuddRef(ee);
1721  cee = separateCube(dd,ee,&dee);
1722  if (cee == NULL) {
1723  Cudd_RecursiveDeref(dd, ctt);
1724  Cudd_RecursiveDeref(dd, ee);
1725  return(NULL);
1726  }
1727  cuddRef(cee);
1728  Cudd_RecursiveDeref(dd, ee);
1729  minD = ddMin(dtt, dee);
1730  if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1);
1731 
1732  if (minD > 0 && topf == topg) {
1733  DdNode *te = cuddBddClosestCube(dd,ft,ge,bound-1);
1734  if (te == NULL) {
1735  Cudd_RecursiveDeref(dd, ctt);
1736  Cudd_RecursiveDeref(dd, cee);
1737  return(NULL);
1738  }
1739  cuddRef(te);
1740  cte = separateCube(dd,te,&dte);
1741  if (cte == NULL) {
1742  Cudd_RecursiveDeref(dd, ctt);
1743  Cudd_RecursiveDeref(dd, cee);
1744  Cudd_RecursiveDeref(dd, te);
1745  return(NULL);
1746  }
1747  cuddRef(cte);
1748  Cudd_RecursiveDeref(dd, te);
1749  dte += 1.0;
1750  minD = ddMin(minD, dte);
1751  } else {
1752  cte = azero;
1753  cuddRef(cte);
1754  dte = CUDD_CONST_INDEX + 1.0;
1755  }
1756  if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1);
1757 
1758  if (minD > 0 && topf == topg) {
1759  DdNode *et = cuddBddClosestCube(dd,fe,gt,bound-1);
1760  if (et == NULL) {
1761  Cudd_RecursiveDeref(dd, ctt);
1762  Cudd_RecursiveDeref(dd, cee);
1763  Cudd_RecursiveDeref(dd, cte);
1764  return(NULL);
1765  }
1766  cuddRef(et);
1767  cet = separateCube(dd,et,&det);
1768  if (cet == NULL) {
1769  Cudd_RecursiveDeref(dd, ctt);
1770  Cudd_RecursiveDeref(dd, cee);
1771  Cudd_RecursiveDeref(dd, cte);
1772  Cudd_RecursiveDeref(dd, et);
1773  return(NULL);
1774  }
1775  cuddRef(cet);
1776  Cudd_RecursiveDeref(dd, et);
1777  det += 1.0;
1778  minD = ddMin(minD, det);
1779  } else {
1780  cet = azero;
1781  cuddRef(cet);
1782  det = CUDD_CONST_INDEX + 1.0;
1783  }
1784 
1785  if (minD == dtt) {
1786  if (dtt == dee && ctt == cee) {
1787  res = createResult(dd,CUDD_CONST_INDEX,1,ctt,dtt);
1788  } else {
1789  res = createResult(dd,index,1,ctt,dtt);
1790  }
1791  } else if (minD == dee) {
1792  res = createResult(dd,index,0,cee,dee);
1793  } else if (minD == dte) {
1794 #ifdef DD_DEBUG
1795  assert(topf == topg);
1796 #endif
1797  res = createResult(dd,index,1,cte,dte);
1798  } else {
1799 #ifdef DD_DEBUG
1800  assert(topf == topg);
1801 #endif
1802  res = createResult(dd,index,0,cet,det);
1803  }
1804  if (res == NULL) {
1805  Cudd_RecursiveDeref(dd, ctt);
1806  Cudd_RecursiveDeref(dd, cee);
1807  Cudd_RecursiveDeref(dd, cte);
1808  Cudd_RecursiveDeref(dd, cet);
1809  return(NULL);
1810  }
1811  cuddRef(res);
1812  Cudd_RecursiveDeref(dd, ctt);
1813  Cudd_RecursiveDeref(dd, cee);
1814  Cudd_RecursiveDeref(dd, cte);
1815  Cudd_RecursiveDeref(dd, cet);
1816 
1817  /* Only cache results that are different from azero to avoid
1818  ** storing results that depend on the value of the bound. */
1819  if ((F->ref != 1 || G->ref != 1) && res != azero)
1820  cuddCacheInsert2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g, res);
1821 
1822  cuddDeref(res);
1823  return(res);
1824 
1825 } /* end of cuddBddClosestCube */
DdHalfWord ref
Definition: cudd.h:280
DdNode * Cudd_bddClosestCube(DdManager *dd, DdNode *f, DdNode *g, int *distance)
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:321
#define statLine(dd)
Definition: cuddInt.h:1037
static DdNode * separateCube(DdManager *dd, DdNode *f, CUDD_VALUE_TYPE *distance)
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define CUDD_CONST_INDEX
Definition: cudd.h:117
#define ddMin(x, y)
Definition: cuddInt.h:818
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
#define CUDD_VALUE_TYPE
Definition: cudd.h:94
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * cuddBddClosestCube(DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE bound)
#define assert(ex)
Definition: util_old.h:213
#define DD_ONE(dd)
Definition: cuddInt.h:911
static DdNode * createResult(DdManager *dd, unsigned int index, unsigned int phase, DdNode *cube, CUDD_VALUE_TYPE distance)
#define DD_ZERO(dd)
Definition: cuddInt.h:927
DdNode* cuddBddComposeRecur ( DdManager dd,
DdNode f,
DdNode g,
DdNode proj 
)

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

Synopsis [Performs the recursive step of Cudd_bddCompose.]

Description [Performs the recursive step of Cudd_bddCompose. Exploits the fact that the composition of f' with g produces the complement of the composition of f with g to better utilize the cache. Returns the composed BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddCompose]

Definition at line 850 of file cuddCompose.c.

855 {
856  DdNode *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e;
857  unsigned int v, topf, topg, topindex;
858  int comple;
859 
860  statLine(dd);
861  v = dd->perm[proj->index];
862  F = Cudd_Regular(f);
863  topf = cuddI(dd,F->index);
864 
865  /* Terminal case. Subsumes the test for constant f. */
866  if (topf > v) return(f);
867 
868  /* We solve the problem for a regular pointer, and then complement
869  ** the result if the pointer was originally complemented.
870  */
871  comple = Cudd_IsComplement(f);
872 
873  /* Check cache. */
874  r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj);
875  if (r != NULL) {
876  return(Cudd_NotCond(r,comple));
877  }
878 
879  if (topf == v) {
880  /* Compose. */
881  f1 = cuddT(F);
882  f0 = cuddE(F);
883  r = cuddBddIteRecur(dd, g, f1, f0);
884  if (r == NULL) return(NULL);
885  } else {
886  /* Compute cofactors of f and g. Remember the index of the top
887  ** variable.
888  */
889  G = Cudd_Regular(g);
890  topg = cuddI(dd,G->index);
891  if (topf > topg) {
892  topindex = G->index;
893  f1 = f0 = F;
894  } else {
895  topindex = F->index;
896  f1 = cuddT(F);
897  f0 = cuddE(F);
898  }
899  if (topg > topf) {
900  g1 = g0 = g;
901  } else {
902  g1 = cuddT(G);
903  g0 = cuddE(G);
904  if (g != G) {
905  g1 = Cudd_Not(g1);
906  g0 = Cudd_Not(g0);
907  }
908  }
909  /* Recursive step. */
910  t = cuddBddComposeRecur(dd, f1, g1, proj);
911  if (t == NULL) return(NULL);
912  cuddRef(t);
913  e = cuddBddComposeRecur(dd, f0, g0, proj);
914  if (e == NULL) {
915  Cudd_IterDerefBdd(dd, t);
916  return(NULL);
917  }
918  cuddRef(e);
919 
920  r = cuddBddIteRecur(dd, dd->vars[topindex], t, e);
921  if (r == NULL) {
922  Cudd_IterDerefBdd(dd, t);
923  Cudd_IterDerefBdd(dd, e);
924  return(NULL);
925  }
926  cuddRef(r);
927  Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */
928  Cudd_IterDerefBdd(dd, e);
929  cuddDeref(r);
930  }
931 
933 
934  return(Cudd_NotCond(r,comple));
935 
936 } /* end of cuddBddComposeRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
DdNode * cuddBddComposeRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *proj)
Definition: cuddCompose.c:850
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
#define statLine(dd)
Definition: cuddInt.h:1037
#define Cudd_IsComplement(node)
Definition: cudd.h:425
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
DdNode ** vars
Definition: cuddInt.h:390
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define DD_BDD_COMPOSE_RECUR_TAG
Definition: cuddInt.h:179
int * perm
Definition: cuddInt.h:386
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:369
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633
DdNode* cuddBddConstrainRecur ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Performs the recursive step of Cudd_bddConstrain.]

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

SideEffects [None]

SeeAlso [Cudd_bddConstrain]

Definition at line 783 of file cuddGenCof.c.

787 {
788  DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r;
789  DdNode *one, *zero;
790  unsigned int topf, topc;
791  int index;
792  int comple = 0;
793 
794  statLine(dd);
795  one = DD_ONE(dd);
796  zero = Cudd_Not(one);
797 
798  /* Trivial cases. */
799  if (c == one) return(f);
800  if (c == zero) return(zero);
801  if (Cudd_IsConstant(f)) return(f);
802  if (f == c) return(one);
803  if (f == Cudd_Not(c)) return(zero);
804 
805  /* Make canonical to increase the utilization of the cache. */
806  if (Cudd_IsComplement(f)) {
807  f = Cudd_Not(f);
808  comple = 1;
809  }
810  /* Now f is a regular pointer to a non-constant node; c is also
811  ** non-constant, but may be complemented.
812  */
813 
814  /* Check the cache. */
815  r = cuddCacheLookup2(dd, Cudd_bddConstrain, f, c);
816  if (r != NULL) {
817  return(Cudd_NotCond(r,comple));
818  }
819 
820  /* Recursive step. */
821  topf = dd->perm[f->index];
822  topc = dd->perm[Cudd_Regular(c)->index];
823  if (topf <= topc) {
824  index = f->index;
825  Fv = cuddT(f); Fnv = cuddE(f);
826  } else {
827  index = Cudd_Regular(c)->index;
828  Fv = Fnv = f;
829  }
830  if (topc <= topf) {
831  Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c));
832  if (Cudd_IsComplement(c)) {
833  Cv = Cudd_Not(Cv);
834  Cnv = Cudd_Not(Cnv);
835  }
836  } else {
837  Cv = Cnv = c;
838  }
839 
840  if (!Cudd_IsConstant(Cv)) {
841  t = cuddBddConstrainRecur(dd, Fv, Cv);
842  if (t == NULL)
843  return(NULL);
844  } else if (Cv == one) {
845  t = Fv;
846  } else { /* Cv == zero: return Fnv @ Cnv */
847  if (Cnv == one) {
848  r = Fnv;
849  } else {
850  r = cuddBddConstrainRecur(dd, Fnv, Cnv);
851  if (r == NULL)
852  return(NULL);
853  }
854  return(Cudd_NotCond(r,comple));
855  }
856  cuddRef(t);
857 
858  if (!Cudd_IsConstant(Cnv)) {
859  e = cuddBddConstrainRecur(dd, Fnv, Cnv);
860  if (e == NULL) {
861  Cudd_IterDerefBdd(dd, t);
862  return(NULL);
863  }
864  } else if (Cnv == one) {
865  e = Fnv;
866  } else { /* Cnv == zero: return Fv @ Cv previously computed */
867  cuddDeref(t);
868  return(Cudd_NotCond(t,comple));
869  }
870  cuddRef(e);
871 
872  if (Cudd_IsComplement(t)) {
873  t = Cudd_Not(t);
874  e = Cudd_Not(e);
875  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
876  if (r == NULL) {
877  Cudd_IterDerefBdd(dd, e);
878  Cudd_IterDerefBdd(dd, t);
879  return(NULL);
880  }
881  r = Cudd_Not(r);
882  } else {
883  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
884  if (r == NULL) {
885  Cudd_IterDerefBdd(dd, e);
886  Cudd_IterDerefBdd(dd, t);
887  return(NULL);
888  }
889  }
890  cuddDeref(t);
891  cuddDeref(e);
892 
893  cuddCacheInsert2(dd, Cudd_bddConstrain, f, c, r);
894  return(Cudd_NotCond(r,comple));
895 
896 } /* end of cuddBddConstrainRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
DdNode * cuddBddConstrainRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:783
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * Cudd_bddConstrain(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:180
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
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 352 of file cuddBddAbs.c.

356 {
357  DdNode *F, *T, *E, *res, *res1, *res2, *one;
358 
359  statLine(manager);
360  one = DD_ONE(manager);
361  F = Cudd_Regular(f);
362 
363  /* Cube is guaranteed to be a cube at this point. */
364  if (cube == one || F == one) {
365  return(f);
366  }
367  /* From now on, f and cube are non-constant. */
368 
369  /* Abstract a variable that does not appear in f. */
370  while (manager->perm[F->index] > manager->perm[cube->index]) {
371  cube = cuddT(cube);
372  if (cube == one) return(f);
373  }
374 
375  /* Check the cache. */
376  if (F->ref != 1 && (res = cuddCacheLookup2(manager, Cudd_bddExistAbstract, f, cube)) != NULL) {
377  return(res);
378  }
379 
380  /* Compute the cofactors of f. */
381  T = cuddT(F); E = cuddE(F);
382  if (f != F) {
383  T = Cudd_Not(T); E = Cudd_Not(E);
384  }
385 
386  /* If the two indices are the same, so are their levels. */
387  if (F->index == cube->index) {
388  if (T == one || E == one || T == Cudd_Not(E)) {
389  return(one);
390  }
391  res1 = cuddBddExistAbstractRecur(manager, T, cuddT(cube));
392  if (res1 == NULL) return(NULL);
393  if (res1 == one) {
394  if (F->ref != 1)
395  cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, one);
396  return(one);
397  }
398  cuddRef(res1);
399  res2 = cuddBddExistAbstractRecur(manager, E, cuddT(cube));
400  if (res2 == NULL) {
401  Cudd_IterDerefBdd(manager,res1);
402  return(NULL);
403  }
404  cuddRef(res2);
405  res = cuddBddAndRecur(manager, Cudd_Not(res1), Cudd_Not(res2));
406  if (res == NULL) {
407  Cudd_IterDerefBdd(manager, res1);
408  Cudd_IterDerefBdd(manager, res2);
409  return(NULL);
410  }
411  res = Cudd_Not(res);
412  cuddRef(res);
413  Cudd_IterDerefBdd(manager, res1);
414  Cudd_IterDerefBdd(manager, res2);
415  if (F->ref != 1)
416  cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res);
417  cuddDeref(res);
418  return(res);
419  } else { /* if (cuddI(manager,F->index) < cuddI(manager,cube->index)) */
420  res1 = cuddBddExistAbstractRecur(manager, T, cube);
421  if (res1 == NULL) return(NULL);
422  cuddRef(res1);
423  res2 = cuddBddExistAbstractRecur(manager, E, cube);
424  if (res2 == NULL) {
425  Cudd_IterDerefBdd(manager, res1);
426  return(NULL);
427  }
428  cuddRef(res2);
429  /* ITE takes care of possible complementation of res1 and of the
430  ** case in which res1 == res2. */
431  res = cuddBddIteRecur(manager, manager->vars[F->index], res1, res2);
432  if (res == NULL) {
433  Cudd_IterDerefBdd(manager, res1);
434  Cudd_IterDerefBdd(manager, res2);
435  return(NULL);
436  }
437  cuddRef(res); //Added
438  Cudd_IterDerefBdd(manager, res1); //cuddDeref(res1);
439  Cudd_IterDerefBdd(manager, res2); //cuddDeref(res2);
440  cuddDeref(res); //Added
441  if (F->ref != 1)
442  cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res);
443  return(res);
444  }
445 
446 } /* end of cuddBddExistAbstractRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
DdHalfWord ref
Definition: cudd.h:280
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:352
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * Cudd_bddExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:130
DdHalfWord index
Definition: cudd.h:279
DdNode ** vars
Definition: cuddInt.h:390
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
int * perm
Definition: cuddInt.h:386
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633
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 771 of file cuddBddIte.c.

775 {
776  DdNode *res;
777  DdNode *F, *G, *t, *e;
778  DdNode *fv, *fnv, *gv, *gnv;
779  DdNode *one, *zero;
780  unsigned int index, topf, topg;
781 
782  statLine(dd);
783  one = DD_ONE(dd);
784  zero = Cudd_Not(one);
785 
786  /* Terminal cases. */
787  if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
788  if (f == g || g == one) return(f);
789  if (f == one) return(g);
790 
791  /* At this point f and g are not constant. */
792  if (cuddF2L(f) > cuddF2L(g)) { DdNode *tmp = f; f = g; g = tmp; }
793  res = cuddCacheLookup2(dd,Cudd_bddIntersect,f,g);
794  if (res != NULL) return(res);
795 
796  /* Find splitting variable. Here we can skip the use of cuddI,
797  ** because the operands are known to be non-constant.
798  */
799  F = Cudd_Regular(f);
800  topf = dd->perm[F->index];
801  G = Cudd_Regular(g);
802  topg = dd->perm[G->index];
803 
804  /* Compute cofactors. */
805  if (topf <= topg) {
806  index = F->index;
807  fv = cuddT(F);
808  fnv = cuddE(F);
809  if (Cudd_IsComplement(f)) {
810  fv = Cudd_Not(fv);
811  fnv = Cudd_Not(fnv);
812  }
813  } else {
814  index = G->index;
815  fv = fnv = f;
816  }
817 
818  if (topg <= topf) {
819  gv = cuddT(G);
820  gnv = cuddE(G);
821  if (Cudd_IsComplement(g)) {
822  gv = Cudd_Not(gv);
823  gnv = Cudd_Not(gnv);
824  }
825  } else {
826  gv = gnv = g;
827  }
828 
829  /* Compute partial results. */
830  t = cuddBddIntersectRecur(dd,fv,gv);
831  if (t == NULL) return(NULL);
832  cuddRef(t);
833  if (t != zero) {
834  e = zero;
835  } else {
836  e = cuddBddIntersectRecur(dd,fnv,gnv);
837  if (e == NULL) {
838  Cudd_IterDerefBdd(dd, t);
839  return(NULL);
840  }
841  }
842  cuddRef(e);
843 
844  if (t == e) { /* both equal zero */
845  res = t;
846  } else if (Cudd_IsComplement(t)) {
847  res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e));
848  if (res == NULL) {
849  Cudd_IterDerefBdd(dd, t);
850  Cudd_IterDerefBdd(dd, e);
851  return(NULL);
852  }
853  res = Cudd_Not(res);
854  } else {
855  res = cuddUniqueInter(dd,(int)index,t,e);
856  if (res == NULL) {
857  Cudd_IterDerefBdd(dd, t);
858  Cudd_IterDerefBdd(dd, e);
859  return(NULL);
860  }
861  }
862  cuddDeref(e);
863  cuddDeref(t);
864 
866 
867  return(res);
868 
869 } /* end of cuddBddIntersectRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
DdNode * Cudd_bddIntersect(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:282
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddF2L(f)
Definition: cuddInt.h:718
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
DdNode * cuddBddIntersectRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:771
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
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 575 of file cuddZddIsop.c.

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

638 {
639  DdNode *one, *zero, *res;
640  DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
641  unsigned int topf, topg, toph, v;
642  int index = -1;
643  int comple;
644 
645  statLine(dd);
646  /* Terminal cases. */
647 
648  /* One variable cases. */
649  if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */
650  return(g);
651 
652  if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */
653  return(h);
654 
655  /* From now on, f is known not to be a constant. */
656  if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
657  if (h == zero) { /* ITE(F,1,0) = F */
658  return(f);
659  } else {
660  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h));
661  return(Cudd_NotCond(res,res != NULL));
662  }
663  } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */
664  if (h == one) { /* ITE(F,0,1) = !F */
665  return(Cudd_Not(f));
666  } else {
667  res = cuddBddAndRecur(dd,Cudd_Not(f),h);
668  return(res);
669  }
670  }
671  if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
672  res = cuddBddAndRecur(dd,f,g);
673  return(res);
674  } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */
675  res = cuddBddAndRecur(dd,f,Cudd_Not(g));
676  return(Cudd_NotCond(res,res != NULL));
677  }
678 
679  /* Check remaining one variable case. */
680  if (g == h) { /* ITE(F,G,G) = G */
681  return(g);
682  } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */
683  res = cuddBddXorRecur(dd,f,h);
684  return(res);
685  }
686 
687  /* From here, there are no constants. */
688  comple = bddVarToCanonicalSimple(dd, &f, &g, &h, &topf, &topg, &toph);
689 
690  /* f & g are now regular pointers */
691 
692  v = ddMin(topg, toph);
693 
694  /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */
695  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
696  r = cuddUniqueInter(dd, (int) f->index, g, h);
697  return(Cudd_NotCond(r,comple && r != NULL));
698  }
699 
700  /* Check cache. */
701  r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h);
702  if (r != NULL) {
703  return(Cudd_NotCond(r,comple));
704  }
705 
706  /* Compute cofactors. */
707  if (topf <= v) {
708  v = ddMin(topf, v); /* v = top_var(F,G,H) */
709  index = f->index;
710  Fv = cuddT(f); Fnv = cuddE(f);
711  } else {
712  Fv = Fnv = f;
713  }
714  if (topg == v) {
715  index = g->index;
716  Gv = cuddT(g); Gnv = cuddE(g);
717  } else {
718  Gv = Gnv = g;
719  }
720  if (toph == v) {
721  H = Cudd_Regular(h);
722  index = H->index;
723  Hv = cuddT(H); Hnv = cuddE(H);
724  if (Cudd_IsComplement(h)) {
725  Hv = Cudd_Not(Hv);
726  Hnv = Cudd_Not(Hnv);
727  }
728  } else {
729  Hv = Hnv = h;
730  }
731 
732  /* Recursive step. */
733  t = cuddBddIteRecur(dd,Fv,Gv,Hv);
734  if (t == NULL) return(NULL);
735  cuddRef(t);
736 
737  e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv);
738  if (e == NULL) {
739  Cudd_IterDerefBdd(dd,t);
740  return(NULL);
741  }
742  cuddRef(e);
743 
744  r = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
745  if (r == NULL) {
746  Cudd_IterDerefBdd(dd,t);
747  Cudd_IterDerefBdd(dd,e);
748  return(NULL);
749  }
750  cuddDeref(t);
751  cuddDeref(e);
752 
753  cuddCacheInsert(dd, DD_BDD_ITE_TAG, f, g, h, r);
754  return(Cudd_NotCond(r,comple));
755 
756 } /* end of cuddBddIteRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
static int bddVarToCanonicalSimple(DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
Definition: cuddBddIte.c:1275
#define statLine(dd)
Definition: cuddInt.h:1037
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define ddMin(x, y)
Definition: cuddInt.h:818
#define DD_BDD_ITE_TAG
Definition: cuddInt.h:175
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1017
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:369
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633
DdNode* cuddBddLICompaction ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Performs safe minimization of a BDD.]

Description [Performs safe minimization of a BDD. Given the BDD f of a function to be minimized and a BDD c representing the care set, Cudd_bddLICompaction produces the BDD of a function that agrees with f wherever c is 1. Safe minimization means that the size of the result is guaranteed not to exceed the size of f. This function is based on the DAC97 paper by Hong et al.. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddLICompaction]

Definition at line 1434 of file cuddGenCof.c.

1438 {
1439  st__table *marktable, *markcache, *buildcache;
1440  DdNode *res, *zero;
1441 
1442  zero = Cudd_Not(DD_ONE(dd));
1443  if (c == zero) return(zero);
1444 
1445  /* We need to use local caches for both steps of this operation.
1446  ** The results of the edge marking step are only valid as long as the
1447  ** edge markings themselves are available. However, the edge markings
1448  ** are lost at the end of one invocation of Cudd_bddLICompaction.
1449  ** Hence, the cache entries for the edge marking step must be
1450  ** invalidated at the end of this function.
1451  ** For the result of the building step we argue as follows. The result
1452  ** for a node and a given constrain depends on the BDD in which the node
1453  ** appears. Hence, the same node and constrain may give different results
1454  ** in successive invocations.
1455  */
1456  marktable = st__init_table( st__ptrcmp, st__ptrhash);
1457  if (marktable == NULL) {
1458  return(NULL);
1459  }
1461  if (markcache == NULL) {
1462  st__free_table(marktable);
1463  return(NULL);
1464  }
1465  if (cuddBddLICMarkEdges(dd,f,c,marktable,markcache) == CUDD_OUT_OF_MEM) {
1466  st__foreach(markcache, MarkCacheCleanUp, NULL);
1467  st__free_table(marktable);
1468  st__free_table(markcache);
1469  return(NULL);
1470  }
1471  st__foreach(markcache, MarkCacheCleanUp, NULL);
1472  st__free_table(markcache);
1473  buildcache = st__init_table( st__ptrcmp, st__ptrhash);
1474  if (buildcache == NULL) {
1475  st__free_table(marktable);
1476  return(NULL);
1477  }
1478  res = cuddBddLICBuildResult(dd,f,buildcache,marktable);
1479  st__free_table(buildcache);
1480  st__free_table(marktable);
1481  return(res);
1482 
1483 } /* end of cuddBddLICompaction */
void st__free_table(st__table *table)
Definition: st.c:81
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
static enum st__retval MarkCacheCleanUp(char *key, char *value, char *arg)
Definition: cuddGenCof.c:1936
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
static DdNode * cuddBddLICBuildResult(DdManager *dd, DdNode *f, st__table *cache, st__table *table)
Definition: cuddGenCof.c:1766
Definition: st.h:52
static int MarkCacheHash(const char *ptr, int modulus)
Definition: cuddGenCof.c:1875
int st__foreach(st__table *table, enum st__retval(*func)(char *, char *, char *), char *arg)
Definition: st.c:421
static int cuddBddLICMarkEdges(DdManager *dd, DdNode *f, DdNode *c, st__table *table, st__table *cache)
Definition: cuddGenCof.c:1647
#define DD_ONE(dd)
Definition: cuddInt.h:911
int st__ptrhash(const char *, int)
Definition: st.c:468
static DdNode * zero
Definition: cuddApa.c:100
static int MarkCacheCompare(const char *ptr1, const char *ptr2)
Definition: cuddGenCof.c:1907
DdNode* cuddBddLiteralSetIntersectionRecur ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Performs the recursive step of Cudd_bddLiteralSetIntersection.]

Description [Performs the recursive step of Cudd_bddLiteralSetIntersection. Scans the cubes for common variables, and checks whether they agree in phase. Returns a pointer to the resulting cube if successful; NULL otherwise.]

SideEffects [None]

Definition at line 153 of file cuddLiteral.c.

157 {
158  DdNode *res, *tmp;
159  DdNode *F, *G;
160  DdNode *fc, *gc;
161  DdNode *one;
162  DdNode *zero;
163  unsigned int topf, topg, comple;
164  int phasef, phaseg;
165 
166  statLine(dd);
167  if (f == g) return(f);
168 
169  F = Cudd_Regular(f);
170  G = Cudd_Regular(g);
171  one = DD_ONE(dd);
172 
173  /* Here f != g. If F == G, then f and g are complementary.
174  ** Since they are two cubes, this case only occurs when f == v,
175  ** g == v', and v is a variable or its complement.
176  */
177  if (F == G) return(one);
178 
179  zero = Cudd_Not(one);
180  topf = cuddI(dd,F->index);
181  topg = cuddI(dd,G->index);
182  /* Look for a variable common to both cubes. If there are none, this
183  ** loop will stop when the constant node is reached in both cubes.
184  */
185  while (topf != topg) {
186  if (topf < topg) { /* move down on f */
187  comple = f != F;
188  f = cuddT(F);
189  if (comple) f = Cudd_Not(f);
190  if (f == zero) {
191  f = cuddE(F);
192  if (comple) f = Cudd_Not(f);
193  }
194  F = Cudd_Regular(f);
195  topf = cuddI(dd,F->index);
196  } else if (topg < topf) {
197  comple = g != G;
198  g = cuddT(G);
199  if (comple) g = Cudd_Not(g);
200  if (g == zero) {
201  g = cuddE(G);
202  if (comple) g = Cudd_Not(g);
203  }
204  G = Cudd_Regular(g);
205  topg = cuddI(dd,G->index);
206  }
207  }
208 
209  /* At this point, f == one <=> g == 1. It suffices to test one of them. */
210  if (f == one) return(one);
211 
213  if (res != NULL) {
214  return(res);
215  }
216 
217  /* Here f and g are both non constant and have the same top variable. */
218  comple = f != F;
219  fc = cuddT(F);
220  phasef = 1;
221  if (comple) fc = Cudd_Not(fc);
222  if (fc == zero) {
223  fc = cuddE(F);
224  phasef = 0;
225  if (comple) fc = Cudd_Not(fc);
226  }
227  comple = g != G;
228  gc = cuddT(G);
229  phaseg = 1;
230  if (comple) gc = Cudd_Not(gc);
231  if (gc == zero) {
232  gc = cuddE(G);
233  phaseg = 0;
234  if (comple) gc = Cudd_Not(gc);
235  }
236 
237  tmp = cuddBddLiteralSetIntersectionRecur(dd,fc,gc);
238  if (tmp == NULL) {
239  return(NULL);
240  }
241 
242  if (phasef != phaseg) {
243  res = tmp;
244  } else {
245  cuddRef(tmp);
246  if (phasef == 0) {
247  res = cuddBddAndRecur(dd,Cudd_Not(dd->vars[F->index]),tmp);
248  } else {
249  res = cuddBddAndRecur(dd,dd->vars[F->index],tmp);
250  }
251  if (res == NULL) {
252  Cudd_RecursiveDeref(dd,tmp);
253  return(NULL);
254  }
255  cuddDeref(tmp); /* Just cuddDeref, because it is included in result */
256  }
257 
259 
260  return(res);
261 
262 } /* end of cuddBddLiteralSetIntersectionRecur */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
DdNode * cuddBddLiteralSetIntersectionRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddLiteral.c:153
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
DdNode ** vars
Definition: cuddInt.h:390
#define cuddE(node)
Definition: cuddInt.h:652
DdNode * Cudd_bddLiteralSetIntersection(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddLiteral.c:118
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
static DdNode * zero
Definition: cuddApa.c:100
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 900 of file cuddSat.c.

904 {
905  DdNode *scan;
906  DdNode *t, *e;
907  DdNode *res = cube;
908  DdNode *zero = Cudd_Not(DD_ONE(dd));
909 
910  Cudd_Ref(res);
911  scan = cube;
912  while (!Cudd_IsConstant(scan)) {
913  DdNode *reg = Cudd_Regular(scan);
914  DdNode *var = dd->vars[reg->index];
915  DdNode *expanded = Cudd_bddExistAbstract(dd,res,var);
916  if (expanded == NULL) {
917  return(NULL);
918  }
919  Cudd_Ref(expanded);
920  if (Cudd_bddLeq(dd,expanded,f)) {
921  Cudd_RecursiveDeref(dd,res);
922  res = expanded;
923  } else {
924  Cudd_RecursiveDeref(dd,expanded);
925  }
926  cuddGetBranches(scan,&t,&e);
927  if (t == zero) {
928  scan = e;
929  } else if (e == zero) {
930  scan = t;
931  } else {
932  Cudd_RecursiveDeref(dd,res);
933  return(NULL); /* cube is not a cube */
934  }
935  }
936 
937  if (scan == DD_ONE(dd)) {
938  Cudd_Deref(res);
939  return(res);
940  } else {
941  Cudd_RecursiveDeref(dd,res);
942  return(NULL);
943  }
944 
945 } /* end of cuddBddMakePrime */
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
int var(Lit p)
Definition: SolverTypes.h:62
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * Cudd_bddExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:130
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
Definition: cuddCof.c:162
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
DdHalfWord index
Definition: cudd.h:279
DdNode ** vars
Definition: cuddInt.h:390
static DdNode * zero
Definition: cuddSat.c:106
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode* cuddBddNPAndRecur ( DdManager manager,
DdNode f,
DdNode g 
)

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

Synopsis [Implements the recursive step of Cudd_bddAnd.]

Description [Implements the recursive step of Cudd_bddNPAnd. Returns a pointer to the result is successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddNPAnd]

Definition at line 1062 of file cuddGenCof.c.

1066 {
1067  DdNode *F, *ft, *fe, *G, *gt, *ge;
1068  DdNode *one, *r, *t, *e;
1069  unsigned int topf, topg, index;
1070 
1071  statLine(manager);
1072  one = DD_ONE(manager);
1073 
1074  /* Terminal cases. */
1075  F = Cudd_Regular(f);
1076  G = Cudd_Regular(g);
1077  if (F == G) {
1078  if (f == g) return(one);
1079  else return(Cudd_Not(one));
1080  }
1081  if (G == one) {
1082  if (g == one) return(f);
1083  else return(g);
1084  }
1085  if (F == one) {
1086  return(f);
1087  }
1088 
1089  /* At this point f and g are not constant. */
1090  /* Check cache. */
1091  if (F->ref != 1 || G->ref != 1) {
1092  r = cuddCacheLookup2(manager, Cudd_bddNPAnd, f, g);
1093  if (r != NULL) return(r);
1094  }
1095 
1096  /* Here we can skip the use of cuddI, because the operands are known
1097  ** to be non-constant.
1098  */
1099  topf = manager->perm[F->index];
1100  topg = manager->perm[G->index];
1101 
1102  if (topg < topf) { /* abstract top variable from g */
1103  DdNode *d;
1104 
1105  /* Find complements of cofactors of g. */
1106  if (Cudd_IsComplement(g)) {
1107  gt = cuddT(G);
1108  ge = cuddE(G);
1109  } else {
1110  gt = Cudd_Not(cuddT(g));
1111  ge = Cudd_Not(cuddE(g));
1112  }
1113  /* Take the OR by applying DeMorgan. */
1114  d = cuddBddAndRecur(manager, gt, ge);
1115  if (d == NULL) return(NULL);
1116  d = Cudd_Not(d);
1117  cuddRef(d);
1118  r = cuddBddNPAndRecur(manager, f, d);
1119  if (r == NULL) {
1120  Cudd_IterDerefBdd(manager, d);
1121  return(NULL);
1122  }
1123  cuddRef(r);
1124  Cudd_IterDerefBdd(manager, d);
1125  cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r);
1126  cuddDeref(r);
1127  return(r);
1128  }
1129 
1130  /* Compute cofactors. */
1131  index = F->index;
1132  ft = cuddT(F);
1133  fe = cuddE(F);
1134  if (Cudd_IsComplement(f)) {
1135  ft = Cudd_Not(ft);
1136  fe = Cudd_Not(fe);
1137  }
1138 
1139  if (topg == topf) {
1140  gt = cuddT(G);
1141  ge = cuddE(G);
1142  if (Cudd_IsComplement(g)) {
1143  gt = Cudd_Not(gt);
1144  ge = Cudd_Not(ge);
1145  }
1146  } else {
1147  gt = ge = g;
1148  }
1149 
1150  t = cuddBddAndRecur(manager, ft, gt);
1151  if (t == NULL) return(NULL);
1152  cuddRef(t);
1153 
1154  e = cuddBddAndRecur(manager, fe, ge);
1155  if (e == NULL) {
1156  Cudd_IterDerefBdd(manager, t);
1157  return(NULL);
1158  }
1159  cuddRef(e);
1160 
1161  if (t == e) {
1162  r = t;
1163  } else {
1164  if (Cudd_IsComplement(t)) {
1165  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
1166  if (r == NULL) {
1167  Cudd_IterDerefBdd(manager, t);
1168  Cudd_IterDerefBdd(manager, e);
1169  return(NULL);
1170  }
1171  r = Cudd_Not(r);
1172  } else {
1173  r = cuddUniqueInter(manager,(int)index,t,e);
1174  if (r == NULL) {
1175  Cudd_IterDerefBdd(manager, t);
1176  Cudd_IterDerefBdd(manager, e);
1177  return(NULL);
1178  }
1179  }
1180  }
1181  cuddDeref(e);
1182  cuddDeref(t);
1183  if (F->ref != 1 || G->ref != 1)
1184  cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r);
1185  return(r);
1186 
1187 } /* end of cuddBddNPAndRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
DdHalfWord ref
Definition: cudd.h:280
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * cuddBddNPAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddGenCof.c:1062
DdNode * Cudd_bddNPAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddGenCof.c:299
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
DdNode* cuddBddRestrictRecur ( DdManager dd,
DdNode f,
DdNode c 
)

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

Synopsis [Performs the recursive step of Cudd_bddRestrict.]

Description [Performs the recursive step of Cudd_bddRestrict. Returns the restricted BDD if successful; otherwise NULL.]

SideEffects [None]

SeeAlso [Cudd_bddRestrict]

Definition at line 912 of file cuddGenCof.c.

916 {
917  DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero;
918  unsigned int topf, topc;
919  int index;
920  int comple = 0;
921 
922  statLine(dd);
923  one = DD_ONE(dd);
924  zero = Cudd_Not(one);
925 
926  /* Trivial cases */
927  if (c == one) return(f);
928  if (c == zero) return(zero);
929  if (Cudd_IsConstant(f)) return(f);
930  if (f == c) return(one);
931  if (f == Cudd_Not(c)) return(zero);
932 
933  /* Make canonical to increase the utilization of the cache. */
934  if (Cudd_IsComplement(f)) {
935  f = Cudd_Not(f);
936  comple = 1;
937  }
938  /* Now f is a regular pointer to a non-constant node; c is also
939  ** non-constant, but may be complemented.
940  */
941 
942  /* Check the cache. */
943  r = cuddCacheLookup2(dd, Cudd_bddRestrict, f, c);
944  if (r != NULL) {
945  return(Cudd_NotCond(r,comple));
946  }
947 
948  topf = dd->perm[f->index];
949  topc = dd->perm[Cudd_Regular(c)->index];
950 
951  if (topc < topf) { /* abstract top variable from c */
952  DdNode *d, *s1, *s2;
953 
954  /* Find complements of cofactors of c. */
955  if (Cudd_IsComplement(c)) {
956  s1 = cuddT(Cudd_Regular(c));
957  s2 = cuddE(Cudd_Regular(c));
958  } else {
959  s1 = Cudd_Not(cuddT(c));
960  s2 = Cudd_Not(cuddE(c));
961  }
962  /* Take the OR by applying DeMorgan. */
963  d = cuddBddAndRecur(dd, s1, s2);
964  if (d == NULL) return(NULL);
965  d = Cudd_Not(d);
966  cuddRef(d);
967  r = cuddBddRestrictRecur(dd, f, d);
968  if (r == NULL) {
969  Cudd_IterDerefBdd(dd, d);
970  return(NULL);
971  }
972  cuddRef(r);
973  Cudd_IterDerefBdd(dd, d);
974  cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r);
975  cuddDeref(r);
976  return(Cudd_NotCond(r,comple));
977  }
978 
979  /* Recursive step. Here topf <= topc. */
980  index = f->index;
981  Fv = cuddT(f); Fnv = cuddE(f);
982  if (topc == topf) {
983  Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c));
984  if (Cudd_IsComplement(c)) {
985  Cv = Cudd_Not(Cv);
986  Cnv = Cudd_Not(Cnv);
987  }
988  } else {
989  Cv = Cnv = c;
990  }
991 
992  if (!Cudd_IsConstant(Cv)) {
993  t = cuddBddRestrictRecur(dd, Fv, Cv);
994  if (t == NULL) return(NULL);
995  } else if (Cv == one) {
996  t = Fv;
997  } else { /* Cv == zero: return(Fnv @ Cnv) */
998  if (Cnv == one) {
999  r = Fnv;
1000  } else {
1001  r = cuddBddRestrictRecur(dd, Fnv, Cnv);
1002  if (r == NULL) return(NULL);
1003  }
1004  return(Cudd_NotCond(r,comple));
1005  }
1006  cuddRef(t);
1007 
1008  if (!Cudd_IsConstant(Cnv)) {
1009  e = cuddBddRestrictRecur(dd, Fnv, Cnv);
1010  if (e == NULL) {
1011  Cudd_IterDerefBdd(dd, t);
1012  return(NULL);
1013  }
1014  } else if (Cnv == one) {
1015  e = Fnv;
1016  } else { /* Cnv == zero: return (Fv @ Cv) previously computed */
1017  cuddDeref(t);
1018  return(Cudd_NotCond(t,comple));
1019  }
1020  cuddRef(e);
1021 
1022  if (Cudd_IsComplement(t)) {
1023  t = Cudd_Not(t);
1024  e = Cudd_Not(e);
1025  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
1026  if (r == NULL) {
1027  Cudd_IterDerefBdd(dd, e);
1028  Cudd_IterDerefBdd(dd, t);
1029  return(NULL);
1030  }
1031  r = Cudd_Not(r);
1032  } else {
1033  r = (t == e) ? t : cuddUniqueInter(dd, index, t, e);
1034  if (r == NULL) {
1035  Cudd_IterDerefBdd(dd, e);
1036  Cudd_IterDerefBdd(dd, t);
1037  return(NULL);
1038  }
1039  }
1040  cuddDeref(t);
1041  cuddDeref(e);
1042 
1043  cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r);
1044  return(Cudd_NotCond(r,comple));
1045 
1046 } /* end of cuddBddRestrictRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * Cudd_bddRestrict(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:212
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
static char s1[largest_string]
Definition: set.c:514
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
DdNode * cuddBddRestrictRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:912
static DdNode * zero
Definition: cuddApa.c:100
DdNode* cuddBddTransfer ( DdManager ddS,
DdManager ddD,
DdNode f 
)

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

Synopsis [Convert a BDD from a manager to another one.]

Description [Convert a BDD from a manager to another one. Returns a pointer to the BDD in the destination manager if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddTransfer]

Definition at line 443 of file cuddBridge.c.

447 {
448  DdNode *res;
449  st__table *table = NULL;
450  st__generator *gen = NULL;
451  DdNode *key, *value;
452 
454  if (table == NULL) goto failure;
455  res = cuddBddTransferRecur(ddS, ddD, f, table);
456  if (res != NULL) cuddRef(res);
457 
458  /* Dereference all elements in the table and dispose of the table.
459  ** This must be done also if res is NULL to avoid leaks in case of
460  ** reordering. */
461  gen = st__init_gen(table);
462  if (gen == NULL) goto failure;
463  while ( st__gen(gen, (const char **)&key, (char **)&value)) {
464  Cudd_RecursiveDeref(ddD, value);
465  }
466  st__free_gen(gen); gen = NULL;
467  st__free_table(table); table = NULL;
468 
469  if (res != NULL) cuddDeref(res);
470  return(res);
471 
472 failure:
473  /* No need to free gen because it is always NULL here. */
474  if (table != NULL) st__free_table(table);
475  return(NULL);
476 
477 } /* end of cuddBddTransfer */
void st__free_table(st__table *table)
Definition: st.c:81
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void st__free_gen(st__generator *gen)
Definition: st.c:556
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
Definition: st.h:52
st__generator * st__init_gen(st__table *table)
Definition: st.c:486
enum keys key
int value
int st__ptrhash(const char *, int)
Definition: st.c:468
static DdNode * cuddBddTransferRecur(DdManager *ddS, DdManager *ddD, DdNode *f, st__table *table)
Definition: cuddBridge.c:953
int st__gen(st__generator *gen, const char **key_p, char **value_p)
Definition: st.c:502
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 464 of file cuddBddAbs.c.

469 {
470  DdNode *F, *fv, *fnv, *G, *gv, *gnv;
471  DdNode *one, *zero, *r, *t, *e, *Cube;
472  unsigned int topf, topg, topcube, top, index;
473 
474  statLine(manager);
475  one = DD_ONE(manager);
476  zero = Cudd_Not(one);
477 
478  /* Terminal cases. */
479  if (f == g) {
480  return(zero);
481  }
482  if (f == Cudd_Not(g)) {
483  return(one);
484  }
485  if (cube == one) {
486  return(cuddBddXorRecur(manager, f, g));
487  }
488  if (f == one) {
489  return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube));
490  }
491  if (g == one) {
492  return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube));
493  }
494  if (f == zero) {
495  return(cuddBddExistAbstractRecur(manager, g, cube));
496  }
497  if (g == zero) {
498  return(cuddBddExistAbstractRecur(manager, f, cube));
499  }
500 
501  /* At this point f, g, and cube are not constant. */
502 
503  if (cuddF2L(f) > cuddF2L(g)) { /* Try to increase cache efficiency. */
504  DdNode *tmp = f;
505  f = g;
506  g = tmp;
507  }
508 
509  /* Check cache. */
510  r = cuddCacheLookup(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube);
511  if (r != NULL) {
512  return(r);
513  }
514 
515  /* Here we can skip the use of cuddI, because the operands are known
516  ** to be non-constant.
517  */
518  F = Cudd_Regular(f);
519  topf = manager->perm[F->index];
520  G = Cudd_Regular(g);
521  topg = manager->perm[G->index];
522  top = ddMin(topf, topg);
523  topcube = manager->perm[cube->index];
524 
525  if (topcube < top) {
526  return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube)));
527  }
528  /* Now, topcube >= top. */
529 
530  if (topf == top) {
531  index = F->index;
532  fv = cuddT(F);
533  fnv = cuddE(F);
534  if (Cudd_IsComplement(f)) {
535  fv = Cudd_Not(fv);
536  fnv = Cudd_Not(fnv);
537  }
538  } else {
539  index = G->index;
540  fv = fnv = f;
541  }
542 
543  if (topg == top) {
544  gv = cuddT(G);
545  gnv = cuddE(G);
546  if (Cudd_IsComplement(g)) {
547  gv = Cudd_Not(gv);
548  gnv = Cudd_Not(gnv);
549  }
550  } else {
551  gv = gnv = g;
552  }
553 
554  if (topcube == top) {
555  Cube = cuddT(cube);
556  } else {
557  Cube = cube;
558  }
559 
560  t = cuddBddXorExistAbstractRecur(manager, fv, gv, Cube);
561  if (t == NULL) return(NULL);
562 
563  /* Special case: 1 OR anything = 1. Hence, no need to compute
564  ** the else branch if t is 1.
565  */
566  if (t == one && topcube == top) {
567  cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, one);
568  return(one);
569  }
570  cuddRef(t);
571 
572  e = cuddBddXorExistAbstractRecur(manager, fnv, gnv, Cube);
573  if (e == NULL) {
574  Cudd_IterDerefBdd(manager, t);
575  return(NULL);
576  }
577  cuddRef(e);
578 
579  if (topcube == top) { /* abstract */
580  r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e));
581  if (r == NULL) {
582  Cudd_IterDerefBdd(manager, t);
583  Cudd_IterDerefBdd(manager, e);
584  return(NULL);
585  }
586  r = Cudd_Not(r);
587  cuddRef(r);
588  Cudd_IterDerefBdd(manager, t);
589  Cudd_IterDerefBdd(manager, e);
590  cuddDeref(r);
591  } else if (t == e) {
592  r = t;
593  cuddDeref(t);
594  cuddDeref(e);
595  } else {
596  if (Cudd_IsComplement(t)) {
597  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
598  if (r == NULL) {
599  Cudd_IterDerefBdd(manager, t);
600  Cudd_IterDerefBdd(manager, e);
601  return(NULL);
602  }
603  r = Cudd_Not(r);
604  } else {
605  r = cuddUniqueInter(manager,(int)index,t,e);
606  if (r == NULL) {
607  Cudd_IterDerefBdd(manager, t);
608  Cudd_IterDerefBdd(manager, e);
609  return(NULL);
610  }
611  }
612  cuddDeref(e);
613  cuddDeref(t);
614  }
615  cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, r);
616  return (r);
617 
618 } /* end of cuddBddXorExistAbstractRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:352
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
#define statLine(dd)
Definition: cuddInt.h:1037
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
#define DD_BDD_XOR_EXIST_ABSTRACT_TAG
Definition: cuddInt.h:174
#define cuddF2L(f)
Definition: cuddInt.h:718
#define ddMin(x, y)
Definition: cuddInt.h:818
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * cuddBddXorExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
Definition: cuddBddAbs.c:464
DdHalfWord index
Definition: cudd.h:279
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1017
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:369
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 1017 of file cuddBddIte.c.

1021 {
1022  DdNode *fv, *fnv, *G, *gv, *gnv;
1023  DdNode *one, *zero, *r, *t, *e;
1024  unsigned int topf, topg, index;
1025 
1026  statLine(manager);
1027  one = DD_ONE(manager);
1028  zero = Cudd_Not(one);
1029 
1030  /* Terminal cases. */
1031  if (f == g) return(zero);
1032  if (f == Cudd_Not(g)) return(one);
1033  if (cuddF2L(f) > cuddF2L(g)) { /* Try to increase cache efficiency and simplify tests. */
1034  DdNode *tmp = f;
1035  f = g;
1036  g = tmp;
1037  }
1038  if (g == zero) return(f);
1039  if (g == one) return(Cudd_Not(f));
1040  if (Cudd_IsComplement(f)) {
1041  f = Cudd_Not(f);
1042  g = Cudd_Not(g);
1043  }
1044  /* Now the first argument is regular. */
1045  if (f == one) return(Cudd_Not(g));
1046 
1047  /* At this point f and g are not constant. */
1048 
1049  /* Check cache. */
1050  r = cuddCacheLookup2(manager, Cudd_bddXor, f, g);
1051  if (r != NULL) return(r);
1052 
1053  /* Here we can skip the use of cuddI, because the operands are known
1054  ** to be non-constant.
1055  */
1056  topf = manager->perm[f->index];
1057  G = Cudd_Regular(g);
1058  topg = manager->perm[G->index];
1059 
1060  /* Compute cofactors. */
1061  if (topf <= topg) {
1062  index = f->index;
1063  fv = cuddT(f);
1064  fnv = cuddE(f);
1065  } else {
1066  index = G->index;
1067  fv = fnv = f;
1068  }
1069 
1070  if (topg <= topf) {
1071  gv = cuddT(G);
1072  gnv = cuddE(G);
1073  if (Cudd_IsComplement(g)) {
1074  gv = Cudd_Not(gv);
1075  gnv = Cudd_Not(gnv);
1076  }
1077  } else {
1078  gv = gnv = g;
1079  }
1080 
1081  t = cuddBddXorRecur(manager, fv, gv);
1082  if (t == NULL) return(NULL);
1083  cuddRef(t);
1084 
1085  e = cuddBddXorRecur(manager, fnv, gnv);
1086  if (e == NULL) {
1087  Cudd_IterDerefBdd(manager, t);
1088  return(NULL);
1089  }
1090  cuddRef(e);
1091 
1092  if (t == e) {
1093  r = t;
1094  } else {
1095  if (Cudd_IsComplement(t)) {
1096  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
1097  if (r == NULL) {
1098  Cudd_IterDerefBdd(manager, t);
1099  Cudd_IterDerefBdd(manager, e);
1100  return(NULL);
1101  }
1102  r = Cudd_Not(r);
1103  } else {
1104  r = cuddUniqueInter(manager,(int)index,t,e);
1105  if (r == NULL) {
1106  Cudd_IterDerefBdd(manager, t);
1107  Cudd_IterDerefBdd(manager, e);
1108  return(NULL);
1109  }
1110  }
1111  }
1112  cuddDeref(e);
1113  cuddDeref(t);
1114  cuddCacheInsert2(manager, Cudd_bddXor, f, g, r);
1115  return(r);
1116 
1117 } /* end of cuddBddXorRecur */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
DdNode * Cudd_bddXor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:476
#define cuddF2L(f)
Definition: cuddInt.h:718
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:1017
#define cuddE(node)
Definition: cuddInt.h:652
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
DdNode* cuddBiasedUnderApprox ( DdManager dd,
DdNode f,
DdNode b,
int  numVars,
int  threshold,
double  quality1,
double  quality0 
)

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

Synopsis [Applies the biased remapping underappoximation algorithm.]

Description [Applies the biased remapping underappoximation algorithm. Proceeds in three phases:

  • collect information on each node in the BDD; this is done via DFS.
  • traverse the BDD in top-down fashion and compute for each node whether remapping increases density.
  • traverse the BDD via DFS and actually perform the elimination.

Returns the approximated BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_BiasedUnderApprox]

Definition at line 691 of file cuddApprox.c.

699 {
700  ApproxInfo *info;
701  DdNode *subset;
702  int result;
703  DdHashTable *cache;
704 
705  if (f == NULL) {
706  fprintf(dd->err, "Cannot subset, nil object\n");
708  return(NULL);
709  }
710 
711  if (Cudd_IsConstant(f)) {
712  return(f);
713  }
714 
715  /* Create table where node data are accessible via a hash table. */
716  info = gatherInfo(dd, f, numVars, TRUE);
717  if (info == NULL) {
718  (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
720  return(NULL);
721  }
722 
723  cache = cuddHashTableInit(dd,2,2);
724  result = BAapplyBias(dd, Cudd_Regular(f), b, info, cache);
725  if (result == CARE_ERROR) {
726  (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
727  cuddHashTableQuit(cache);
728  ABC_FREE(info->page);
729  st__free_table(info->table);
730  ABC_FREE(info);
732  return(NULL);
733  }
734  cuddHashTableQuit(cache);
735 
736  /* Mark nodes that should be replaced by zero. */
737  result = BAmarkNodes(dd, f, info, threshold, quality1, quality0);
738  if (result == 0) {
739  (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
740  ABC_FREE(info->page);
741  st__free_table(info->table);
742  ABC_FREE(info);
744  return(NULL);
745  }
746 
747  /* Build the result. */
748  subset = RAbuildSubset(dd, f, info);
749 #if 1
750  if (subset && info->size < Cudd_DagSize(subset))
751  (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n",
752  info->size, Cudd_DagSize(subset));
753 #endif
754  ABC_FREE(info->page);
755  st__free_table(info->table);
756  ABC_FREE(info);
757 
758 #ifdef DD_DEBUG
759  if (subset != NULL) {
760  cuddRef(subset);
761 #if 0
762  (void) Cudd_DebugCheck(dd);
763  (void) Cudd_CheckKeys(dd);
764 #endif
765  if (!Cudd_bddLeq(dd, subset, f)) {
766  (void) fprintf(dd->err, "Wrong subset\n");
767  }
768  cuddDeref(subset);
770  }
771 #endif
772  return(subset);
773 
774 } /* end of cuddBiasedUnderApprox */
void st__free_table(st__table *table)
Definition: st.c:81
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
static int BAapplyBias(DdManager *dd, DdNode *f, DdNode *b, ApproxInfo *info, DdHashTable *cache)
Definition: cuddApprox.c:2138
#define CARE_ERROR
Definition: cuddApprox.c:102
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
FILE * err
Definition: cuddInt.h:442
static ApproxInfo * gatherInfo(DdManager *dd, DdNode *node, int numVars, int parity)
Definition: cuddApprox.c:907
static int BAmarkNodes(DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality1, double quality0)
Definition: cuddApprox.c:1673
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:142
st__table * table
Definition: cuddApprox.c:135
void cuddHashTableQuit(DdHashTable *hash)
Definition: cuddLCache.c:595
#define TRUE
Definition: cudd.h:88
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
#define ABC_FREE(obj)
Definition: abc_global.h:232
int Cudd_CheckKeys(DdManager *table)
Definition: cuddCheck.c:458
static DdNode * RAbuildSubset(DdManager *dd, DdNode *node, ApproxInfo *info)
Definition: cuddApprox.c:1990
DdHashTable * cuddHashTableInit(DdManager *manager, unsigned int keySize, unsigned int initSize)
Definition: cuddLCache.c:538
NodeData * page
Definition: cuddApprox.c:134
static int result
Definition: cuddGenetic.c:125
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
void cuddCacheFlush ( DdManager table)

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

Synopsis [Flushes the cache.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1047 of file cuddCache.c.

1049 {
1050  int i, slots;
1051  DdCache *cache;
1052 
1053  slots = table->cacheSlots;
1054  cache = table->cache;
1055  for (i = 0; i < slots; i++) {
1056  table->cachedeletions += cache[i].data != NULL;
1057  cache[i].data = NULL;
1058  }
1059  table->cacheLastInserts = table->cacheinserts;
1060 
1061  return;
1062 
1063 } /* end of cuddCacheFlush */
DdNode * data
Definition: cuddInt.h:319
double cacheinserts
Definition: cuddInt.h:458
unsigned int cacheSlots
Definition: cuddInt.h:353
DdCache * cache
Definition: cuddInt.h:352
double cacheLastInserts
Definition: cuddInt.h:459
double cachedeletions
Definition: cuddInt.h:460
void cuddCacheInsert ( DdManager table,
ptruint  op,
DdNode f,
DdNode g,
DdNode h,
DdNode data 
)

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

Synopsis [Inserts a result in the cache.]

Description []

SideEffects [None]

SeeAlso [cuddCacheInsert2 cuddCacheInsert1]

Definition at line 222 of file cuddCache.c.

229 {
230  int posn;
231  unsigned hash;
232  register DdCache *entry;
233  ptruint uf, ug, uh;
234  ptruint ufc, ugc, uhc;
235 
236  uf = (ptruint) f | (op & 0xe);
237  ug = (ptruint) g | (op >> 4);
238  uh = (ptruint) h;
239 
240  ufc = (ptruint) cuddF2L(f) | (op & 0xe);
241  ugc = (ptruint) cuddF2L(g) | (op >> 4);
242  uhc = (ptruint) cuddF2L(h);
243 
244  hash = ddCHash2_(uhc,ufc,ugc);
245 // posn = ddCHash2(uhc,ufc,ugc,table->cacheShift);
246  posn = hash >> table->cacheShift;
247  entry = &table->cache[posn];
248 
249  table->cachecollisions += entry->data != NULL;
250  table->cacheinserts++;
251 
252  entry->f = (DdNode *) uf;
253  entry->g = (DdNode *) ug;
254  entry->h = uh;
255  entry->data = data;
256 #ifdef DD_CACHE_PROFILE
257  entry->count++;
258 #endif
259  entry->hash = hash;
260 
261 } /* end of cuddCacheInsert */
DdNode * f
Definition: cuddInt.h:317
Definition: cudd.h:278
DdNode * data
Definition: cuddInt.h:319
ptruint h
Definition: cuddInt.h:318
DdNode * g
Definition: cuddInt.h:317
double cachecollisions
Definition: cuddInt.h:457
double cacheinserts
Definition: cuddInt.h:458
static int * entry
Definition: cuddGroup.c:122
ABC_PTRUINT_T ptruint
Definition: cuddInt.h:261
DdCache * cache
Definition: cuddInt.h:352
static uint32_t hash(uint32_t x)
Definition: Map.h:38
#define cuddF2L(f)
Definition: cuddInt.h:718
unsigned hash
Definition: cuddInt.h:323
#define ddCHash2_(o, f, g)
Definition: cuddInt.h:788
int cacheShift
Definition: cuddInt.h:354
void cuddCacheInsert1 ( DdManager table,
DdNode *)(DdManager *, DdNode *,
DdNode f,
DdNode data 
)
void cuddCacheInsert2 ( DdManager table,
DdNode *)(DdManager *, DdNode *, DdNode *,
DdNode f,
DdNode g,
DdNode data 
)
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 369 of file cuddCache.c.

375 {
376  int posn;
377  DdCache *en,*cache;
378  DdNode *data;
379  ptruint uf, ug, uh;
380  ptruint ufc, ugc, uhc;
381 
382  uf = (ptruint) f | (op & 0xe);
383  ug = (ptruint) g | (op >> 4);
384  uh = (ptruint) h;
385 
386  ufc = (ptruint) cuddF2L(f) | (op & 0xe);
387  ugc = (ptruint) cuddF2L(g) | (op >> 4);
388  uhc = (ptruint) cuddF2L(h);
389 
390  cache = table->cache;
391 #ifdef DD_DEBUG
392  if (cache == NULL) {
393  return(NULL);
394  }
395 #endif
396 
397  posn = ddCHash2(uhc,ufc,ugc,table->cacheShift);
398  en = &cache[posn];
399  if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && en->h==uh) {
400  data = Cudd_Regular(en->data);
401  table->cacheHits++;
402  if (data->ref == 0) {
403  cuddReclaim(table,data);
404  }
405  return(en->data);
406  }
407 
408  /* Cache miss: decide whether to resize. */
409  table->cacheMisses++;
410 
411  if (table->cacheSlack >= 0 &&
412  table->cacheHits > table->cacheMisses * table->minHit) {
413  cuddCacheResize(table);
414  }
415 
416  return(NULL);
417 
418 } /* end of cuddCacheLookup */
DdHalfWord ref
Definition: cudd.h:280
DdNode * f
Definition: cuddInt.h:317
Definition: cudd.h:278
DdNode * data
Definition: cuddInt.h:319
ptruint h
Definition: cuddInt.h:318
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddRef.c:584
DdNode * g
Definition: cuddInt.h:317
ABC_PTRUINT_T ptruint
Definition: cuddInt.h:261
DdCache * cache
Definition: cuddInt.h:352
double cacheHits
Definition: cuddInt.h:356
#define cuddF2L(f)
Definition: cuddInt.h:718
int cacheSlack
Definition: cuddInt.h:358
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:786
double cacheMisses
Definition: cuddInt.h:355
double minHit
Definition: cuddInt.h:357
int cacheShift
Definition: cuddInt.h:354
void cuddCacheResize(DdManager *table)
Definition: cuddCache.c:925
DdNode* cuddCacheLookup1 ( DdManager table,
DdNode *)(DdManager *, DdNode *,
DdNode f 
)
DdNode* cuddCacheLookup1Zdd ( DdManager table,
DdNode *)(DdManager *, DdNode *,
DdNode f 
)
DdNode* cuddCacheLookup2 ( DdManager table,
DdNode *)(DdManager *, DdNode *, DdNode *,
DdNode f,
DdNode g 
)
DdNode* cuddCacheLookup2Zdd ( DdManager table,
DdNode *)(DdManager *, DdNode *, DdNode *,
DdNode f,
DdNode g 
)
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 435 of file cuddCache.c.

441 {
442  int posn;
443  DdCache *en,*cache;
444  DdNode *data;
445  ptruint uf, ug, uh;
446  ptruint ufc, ugc, uhc;
447 
448  uf = (ptruint) f | (op & 0xe);
449  ug = (ptruint) g | (op >> 4);
450  uh = (ptruint) h;
451 
452  ufc = (ptruint) cuddF2L(f) | (op & 0xe);
453  ugc = (ptruint) cuddF2L(g) | (op >> 4);
454  uhc = (ptruint) cuddF2L(h);
455 
456  cache = table->cache;
457 #ifdef DD_DEBUG
458  if (cache == NULL) {
459  return(NULL);
460  }
461 #endif
462 
463  posn = ddCHash2(uhc,ufc,ugc,table->cacheShift);
464  en = &cache[posn];
465  if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug &&
466  en->h==uh) {
467  data = Cudd_Regular(en->data);
468  table->cacheHits++;
469  if (data->ref == 0) {
470  cuddReclaimZdd(table,data);
471  }
472  return(en->data);
473  }
474 
475  /* Cache miss: decide whether to resize. */
476  table->cacheMisses++;
477 
478  if (table->cacheSlack >= 0 &&
479  table->cacheHits > table->cacheMisses * table->minHit) {
480  cuddCacheResize(table);
481  }
482 
483  return(NULL);
484 
485 } /* end of cuddCacheLookupZdd */
DdHalfWord ref
Definition: cudd.h:280
DdNode * f
Definition: cuddInt.h:317
Definition: cudd.h:278
DdNode * data
Definition: cuddInt.h:319
ptruint h
Definition: cuddInt.h:318
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * g
Definition: cuddInt.h:317
ABC_PTRUINT_T ptruint
Definition: cuddInt.h:261
DdCache * cache
Definition: cuddInt.h:352
double cacheHits
Definition: cuddInt.h:356
#define cuddF2L(f)
Definition: cuddInt.h:718
int cacheSlack
Definition: cuddInt.h:358
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:786
void cuddReclaimZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:638
double cacheMisses
Definition: cuddInt.h:355
double minHit
Definition: cuddInt.h:357
int cacheShift
Definition: cuddInt.h:354
void cuddCacheResize(DdManager *table)
Definition: cuddCache.c:925
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 785 of file cuddCache.c.

788 {
789  DdCache *cache = table->cache;
790  int slots = table->cacheSlots;
791  int nzeroes = 0;
792  int i, retval;
793  double exUsed;
794 
795 #ifdef DD_CACHE_PROFILE
796  double count, mean, meansq, stddev, expected;
797  long max, min;
798  int imax, imin;
799  double *hystogramQ, *hystogramR; /* histograms by quotient and remainder */
800  int nbins = DD_HYSTO_BINS;
801  int bin;
802  long thiscount;
803  double totalcount, exStddev;
804 
805  meansq = mean = expected = 0.0;
806  max = min = (long) cache[0].count;
807  imax = imin = 0;
808  totalcount = 0.0;
809 
810  hystogramQ = ABC_ALLOC(double, nbins);
811  if (hystogramQ == NULL) {
812  table->errorCode = CUDD_MEMORY_OUT;
813  return(0);
814  }
815  hystogramR = ABC_ALLOC(double, nbins);
816  if (hystogramR == NULL) {
817  ABC_FREE(hystogramQ);
818  table->errorCode = CUDD_MEMORY_OUT;
819  return(0);
820  }
821  for (i = 0; i < nbins; i++) {
822  hystogramQ[i] = 0;
823  hystogramR[i] = 0;
824  }
825 
826  for (i = 0; i < slots; i++) {
827  thiscount = (long) cache[i].count;
828  if (thiscount > max) {
829  max = thiscount;
830  imax = i;
831  }
832  if (thiscount < min) {
833  min = thiscount;
834  imin = i;
835  }
836  if (thiscount == 0) {
837  nzeroes++;
838  }
839  count = (double) thiscount;
840  mean += count;
841  meansq += count * count;
842  totalcount += count;
843  expected += count * (double) i;
844  bin = (i * nbins) / slots;
845  hystogramQ[bin] += (double) thiscount;
846  bin = i % nbins;
847  hystogramR[bin] += (double) thiscount;
848  }
849  mean /= (double) slots;
850  meansq /= (double) slots;
851 
852  /* Compute the standard deviation from both the data and the
853  ** theoretical model for a random distribution. */
854  stddev = sqrt(meansq - mean*mean);
855  exStddev = sqrt((1 - 1/(double) slots) * totalcount / (double) slots);
856 
857  retval = fprintf(fp,"Cache average accesses = %g\n", mean);
858  if (retval == EOF) return(0);
859  retval = fprintf(fp,"Cache access standard deviation = %g ", stddev);
860  if (retval == EOF) return(0);
861  retval = fprintf(fp,"(expected = %g)\n", exStddev);
862  if (retval == EOF) return(0);
863  retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax);
864  if (retval == EOF) return(0);
865  retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin);
866  if (retval == EOF) return(0);
867  exUsed = 100.0 * (1.0 - exp(-totalcount / (double) slots));
868  retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n",
869  100.0 - (double) nzeroes * 100.0 / (double) slots,
870  exUsed);
871  if (retval == EOF) return(0);
872 
873  if (totalcount > 0) {
874  expected /= totalcount;
875  retval = fprintf(fp,"Cache access hystogram for %d bins", nbins);
876  if (retval == EOF) return(0);
877  retval = fprintf(fp," (expected bin value = %g)\nBy quotient:",
878  expected);
879  if (retval == EOF) return(0);
880  for (i = nbins - 1; i>=0; i--) {
881  retval = fprintf(fp," %.0f", hystogramQ[i]);
882  if (retval == EOF) return(0);
883  }
884  retval = fprintf(fp,"\nBy residue: ");
885  if (retval == EOF) return(0);
886  for (i = nbins - 1; i>=0; i--) {
887  retval = fprintf(fp," %.0f", hystogramR[i]);
888  if (retval == EOF) return(0);
889  }
890  retval = fprintf(fp,"\n");
891  if (retval == EOF) return(0);
892  }
893 
894  ABC_FREE(hystogramQ);
895  ABC_FREE(hystogramR);
896 #else
897  for (i = 0; i < slots; i++) {
898  nzeroes += cache[i].h == 0;
899  }
900  exUsed = 100.0 *
901  (1.0 - exp(-(table->cacheinserts - table->cacheLastInserts) /
902  (double) slots));
903  retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n",
904  100.0 - (double) nzeroes * 100.0 / (double) slots,
905  exUsed);
906  if (retval == EOF) return(0);
907 #endif
908  return(1);
909 
910 } /* end of cuddCacheProfile */
ptruint h
Definition: cuddInt.h:318
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
double cacheinserts
Definition: cuddInt.h:458
unsigned int cacheSlots
Definition: cuddInt.h:353
DdCache * cache
Definition: cuddInt.h:352
static double max
Definition: cuddSubsetHB.c:134
double cacheLastInserts
Definition: cuddInt.h:459
#define ABC_FREE(obj)
Definition: abc_global.h:232
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
void cuddCacheResize ( DdManager table)

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

Synopsis [Resizes the cache.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 925 of file cuddCache.c.

927 {
928  DdCache *cache, *oldcache, *oldacache, *entry, *old;
929  int i;
930  int posn, shift;
931  unsigned int slots, oldslots;
932  double offset;
933  int moved = 0;
934  extern DD_OOMFP MMoutOfMemory;
935  DD_OOMFP saveHandler;
936 #ifndef DD_CACHE_PROFILE
937  ptruint misalignment;
938  DdNodePtr *mem;
939 #endif
940 
941  oldcache = table->cache;
942  oldacache = table->acache;
943  oldslots = table->cacheSlots;
944  slots = table->cacheSlots = oldslots << 1;
945 
946 #ifdef DD_VERBOSE
947  (void) fprintf(table->err,"Resizing the cache from %d to %d entries\n",
948  oldslots, slots);
949  (void) fprintf(table->err,
950  "\thits = %g\tmisses = %g\thit ratio = %5.3f\n",
951  table->cacheHits, table->cacheMisses,
952  table->cacheHits / (table->cacheHits + table->cacheMisses));
953 #endif
954 
955  saveHandler = MMoutOfMemory;
956  MMoutOfMemory = Cudd_OutOfMem;
957 // table->acache = cache = ABC_ALLOC(DdCache,slots+1);
958  table->acache = cache = ABC_ALLOC(DdCache,slots+2);
959  MMoutOfMemory = saveHandler;
960  /* If we fail to allocate the new table we just give up. */
961  if (cache == NULL) {
962 #ifdef DD_VERBOSE
963  (void) fprintf(table->err,"Resizing failed. Giving up.\n");
964 #endif
965  table->cacheSlots = oldslots;
966  table->acache = oldacache;
967  /* Do not try to resize again. */
968  table->maxCacheHard = oldslots - 1;
969  table->cacheSlack = - (int) (oldslots + 1);
970  return;
971  }
972  /* If the size of the cache entry is a power of 2, we want to
973  ** enforce alignment to that power of two. This happens when
974  ** DD_CACHE_PROFILE is not defined. */
975 #ifdef DD_CACHE_PROFILE
976  table->cache = cache;
977 #else
978  mem = (DdNodePtr *) cache;
979 // misalignment = (ptruint) mem & (sizeof(DdCache) - 1);
980 // mem += (sizeof(DdCache) - misalignment) / sizeof(DdNodePtr);
981 // table->cache = cache = (DdCache *) mem;
982 // assert(((ptruint) table->cache & (sizeof(DdCache) - 1)) == 0);
983  misalignment = (ptruint) mem & (32 - 1);
984  mem += (32 - misalignment) / sizeof(DdNodePtr);
985  table->cache = cache = (DdCache *) mem;
986  assert(((ptruint) table->cache & (32 - 1)) == 0);
987 #endif
988  shift = --(table->cacheShift);
989  table->memused += (slots - oldslots) * sizeof(DdCache);
990  table->cacheSlack -= slots; /* need these many slots to double again */
991 
992  /* Clear new cache. */
993  for (i = 0; (unsigned) i < slots; i++) {
994  cache[i].data = NULL;
995  cache[i].h = 0;
996 #ifdef DD_CACHE_PROFILE
997  cache[i].count = 0;
998 #endif
999  }
1000 
1001  /* Copy from old cache to new one. */
1002  for (i = 0; (unsigned) i < oldslots; i++) {
1003  old = &oldcache[i];
1004  if (old->data != NULL) {
1005 // posn = ddCHash2(old->h,old->f,old->g,shift);
1006  posn = old->hash >> shift;
1007  entry = &cache[posn];
1008  entry->f = old->f;
1009  entry->g = old->g;
1010  entry->h = old->h;
1011  entry->data = old->data;
1012 #ifdef DD_CACHE_PROFILE
1013  entry->count = 1;
1014 #endif
1015  entry->hash = old->hash;
1016  moved++;
1017  }
1018  }
1019 
1020  ABC_FREE(oldacache);
1021 
1022  /* Reinitialize measurements so as to avoid division by 0 and
1023  ** immediate resizing.
1024  */
1025  offset = (double) (int) (slots * table->minHit + 1);
1026  table->totCacheMisses += table->cacheMisses - offset;
1027  table->cacheMisses = offset;
1028  table->totCachehits += table->cacheHits;
1029  table->cacheHits = 0;
1030  table->cacheLastInserts = table->cacheinserts - (double) moved;
1031 
1032 } /* end of cuddCacheResize */
void(* DD_OOMFP)(long)
Definition: cudd.h:324
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2837
DdNode * f
Definition: cuddInt.h:317
Definition: cudd.h:278
DdNode * data
Definition: cuddInt.h:319
unsigned int maxCacheHard
Definition: cuddInt.h:359
ptruint h
Definition: cuddInt.h:318
FILE * err
Definition: cuddInt.h:442
DdNode * g
Definition: cuddInt.h:317
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
double cacheinserts
Definition: cuddInt.h:458
static int * entry
Definition: cuddGroup.c:122
ABC_PTRUINT_T ptruint
Definition: cuddInt.h:261
unsigned int cacheSlots
Definition: cuddInt.h:353
DdCache * cache
Definition: cuddInt.h:352
double totCacheMisses
Definition: cuddInt.h:456
double cacheLastInserts
Definition: cuddInt.h:459
double cacheHits
Definition: cuddInt.h:356
int cacheSlack
Definition: cuddInt.h:358
unsigned long memused
Definition: cuddInt.h:449
unsigned hash
Definition: cuddInt.h:323
#define ABC_FREE(obj)
Definition: abc_global.h:232
double cacheMisses
Definition: cuddInt.h:355
double minHit
Definition: cuddInt.h:357
int cacheShift
Definition: cuddInt.h:354
#define assert(ex)
Definition: util_old.h:213
DdCache * acache
Definition: cuddInt.h:351
#define MMoutOfMemory
Definition: util_hack.h:38
double totCachehits
Definition: cuddInt.h:455
int cuddCheckCube ( DdManager dd,
DdNode g 
)

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

Synopsis [Checks whether g is the BDD of a cube.]

Description [Checks whether g is the BDD of a cube. Returns 1 in case of success; 0 otherwise. The constant 1 is a valid cube, but all other constant functions cause cuddCheckCube to return 0.]

SideEffects [None]

SeeAlso []

Definition at line 193 of file cuddCof.c.

196 {
197  DdNode *g1,*g0,*one,*zero;
198 
199  one = DD_ONE(dd);
200  if (g == one) return(1);
201  if (Cudd_IsConstant(g)) return(0);
202 
203  zero = Cudd_Not(one);
204  cuddGetBranches(g,&g1,&g0);
205 
206  if (g0 == zero) {
207  return(cuddCheckCube(dd, g1));
208  }
209  if (g1 == zero) {
210  return(cuddCheckCube(dd, g0));
211  }
212  return(0);
213 
214 } /* end of cuddCheckCube */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_IsConstant(node)
Definition: cudd.h:352
int cuddCheckCube(DdManager *dd, DdNode *g)
Definition: cuddCof.c:193
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
Definition: cuddCof.c:162
static DdNode * one
Definition: cuddDecomp.c:112
#define DD_ONE(dd)
Definition: cuddInt.h:911
static DdNode * zero
Definition: cuddApa.c:100
void cuddClearDeathRow ( DdManager table)

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

Synopsis [Clears the death row.]

Description []

SideEffects [None]

SeeAlso [Cudd_DelayedDerefBdd Cudd_IterDerefBdd Cudd_CheckZeroRef cuddGarbageCollect]

Definition at line 726 of file cuddRef.c.

728 {
729 #ifndef DD_NO_DEATH_ROW
730  int i;
731 
732  for (i = 0; i < table->deathRowDepth; i++) {
733  if (table->deathRow[i] == NULL) break;
734  Cudd_IterDerefBdd(table,table->deathRow[i]);
735  table->deathRow[i] = NULL;
736  }
737 #ifdef DD_DEBUG
738  for (; i < table->deathRowDepth; i++) {
739  assert(table->deathRow[i] == NULL);
740  }
741 #endif
742  table->nextDead = 0;
743 #endif
744 
745 } /* end of cuddClearDeathRow */
DdNode ** deathRow
Definition: cuddInt.h:401
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
int nextDead
Definition: cuddInt.h:403
int deathRowDepth
Definition: cuddInt.h:402
#define assert(ex)
Definition: util_old.h:213
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 230 of file cuddCof.c.

234 {
235  DdNode *one,*zero,*F,*G,*g1,*g0,*f1,*f0,*t,*e,*r;
236  unsigned int topf,topg;
237  int comple;
238 
239  statLine(dd);
240  F = Cudd_Regular(f);
241  if (cuddIsConstant(F)) return(f);
242 
243  one = DD_ONE(dd);
244 
245  /* The invariant g != 0 is true on entry to this procedure and is
246  ** recursively maintained by it. Therefore it suffices to test g
247  ** against one to make sure it is not constant.
248  */
249  if (g == one) return(f);
250  /* From now on, f and g are known not to be constants. */
251 
252  comple = f != F;
253  r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g);
254  if (r != NULL) {
255  return(Cudd_NotCond(r,comple));
256  }
257 
258  topf = dd->perm[F->index];
259  G = Cudd_Regular(g);
260  topg = dd->perm[G->index];
261 
262  /* We take the cofactors of F because we are going to rely on
263  ** the fact that the cofactors of the complement are the complements
264  ** of the cofactors to better utilize the cache. Variable comple
265  ** remembers whether we have to complement the result or not.
266  */
267  if (topf <= topg) {
268  f1 = cuddT(F); f0 = cuddE(F);
269  } else {
270  f1 = f0 = F;
271  }
272  if (topg <= topf) {
273  g1 = cuddT(G); g0 = cuddE(G);
274  if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); }
275  } else {
276  g1 = g0 = g;
277  }
278 
279  zero = Cudd_Not(one);
280  if (topf >= topg) {
281  if (g0 == zero || g0 == DD_ZERO(dd)) {
282  r = cuddCofactorRecur(dd, f1, g1);
283  } else if (g1 == zero || g1 == DD_ZERO(dd)) {
284  r = cuddCofactorRecur(dd, f0, g0);
285  } else {
286  (void) fprintf(dd->out,
287  "Cudd_Cofactor: Invalid restriction 2\n");
289  return(NULL);
290  }
291  if (r == NULL) return(NULL);
292  } else /* if (topf < topg) */ {
293  t = cuddCofactorRecur(dd, f1, g);
294  if (t == NULL) return(NULL);
295  cuddRef(t);
296  e = cuddCofactorRecur(dd, f0, g);
297  if (e == NULL) {
298  Cudd_RecursiveDeref(dd, t);
299  return(NULL);
300  }
301  cuddRef(e);
302 
303  if (t == e) {
304  r = t;
305  } else if (Cudd_IsComplement(t)) {
306  r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e));
307  if (r != NULL)
308  r = Cudd_Not(r);
309  } else {
310  r = cuddUniqueInter(dd,(int)F->index,t,e);
311  }
312  if (r == NULL) {
313  Cudd_RecursiveDeref(dd ,e);
314  Cudd_RecursiveDeref(dd ,t);
315  return(NULL);
316  }
317  cuddDeref(t);
318  cuddDeref(e);
319  }
320 
322 
323  return(Cudd_NotCond(r,comple));
324 
325 } /* end of cuddCofactorRecur */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * Cudd_Cofactor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddCof.c:123
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
#define Cudd_IsComplement(node)
Definition: cudd.h:425
static DdNode * one
Definition: cuddDecomp.c:112
FILE * out
Definition: cuddInt.h:441
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * cuddCofactorRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddCof.c:230
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
#define DD_ONE(dd)
Definition: cuddInt.h:911
int * perm
Definition: cuddInt.h:386
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
static DdNode * zero
Definition: cuddApa.c:100
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 1079 of file cuddCache.c.

1081 {
1082  int floorLog = 0;
1083 #ifdef DD_DEBUG
1084  assert(value > 0);
1085 #endif
1086  while (value > 1) {
1087  floorLog++;
1088  value >>= 1;
1089  }
1090  return(floorLog);
1091 
1092 } /* end of cuddComputeFloorLog2 */
int value
#define assert(ex)
Definition: util_old.h:213
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 721 of file cuddCache.c.

727 {
728  int posn;
729  DdCache *en,*cache;
730  ptruint uf, ug, uh;
731  ptruint ufc, ugc, uhc;
732 
733  uf = (ptruint) f | (op & 0xe);
734  ug = (ptruint) g | (op >> 4);
735  uh = (ptruint) h;
736 
737  ufc = (ptruint) cuddF2L(f) | (op & 0xe);
738  ugc = (ptruint) cuddF2L(g) | (op >> 4);
739  uhc = (ptruint) cuddF2L(h);
740 
741  cache = table->cache;
742 #ifdef DD_DEBUG
743  if (cache == NULL) {
744  return(NULL);
745  }
746 #endif
747  posn = ddCHash2(uhc,ufc,ugc,table->cacheShift);
748  en = &cache[posn];
749 
750  /* We do not reclaim here because the result should not be
751  * referenced, but only tested for being a constant.
752  */
753  if (en->data != NULL &&
754  en->f == (DdNodePtr)uf && en->g == (DdNodePtr)ug && en->h == uh) {
755  table->cacheHits++;
756  return(en->data);
757  }
758 
759  /* Cache miss: decide whether to resize. */
760  table->cacheMisses++;
761 
762  if (table->cacheSlack >= 0 &&
763  table->cacheHits > table->cacheMisses * table->minHit) {
764  cuddCacheResize(table);
765  }
766 
767  return(NULL);
768 
769 } /* end of cuddConstantLookup */
DdNode * f
Definition: cuddInt.h:317
Definition: cudd.h:278
DdNode * data
Definition: cuddInt.h:319
ptruint h
Definition: cuddInt.h:318
DdNode * g
Definition: cuddInt.h:317
ABC_PTRUINT_T ptruint
Definition: cuddInt.h:261
DdCache * cache
Definition: cuddInt.h:352
double cacheHits
Definition: cuddInt.h:356
#define cuddF2L(f)
Definition: cuddInt.h:718
int cacheSlack
Definition: cuddInt.h:358
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:786
double cacheMisses
Definition: cuddInt.h:355
double minHit
Definition: cuddInt.h:357
int cacheShift
Definition: cuddInt.h:354
void cuddCacheResize(DdManager *table)
Definition: cuddCache.c:925
DdNode* cuddCProjectionRecur ( DdManager dd,
DdNode R,
DdNode Y,
DdNode Ysupp 
)

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

Synopsis [Performs the recursive step of Cudd_CProjection.]

Description [Performs the recursive step of Cudd_CProjection. Returns the projection if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_CProjection]

Definition at line 1425 of file cuddPriority.c.

1430 {
1431  DdNode *res, *res1, *res2, *resA;
1432  DdNode *r, *y, *RT, *RE, *YT, *YE, *Yrest, *Ra, *Ran, *Gamma, *Alpha;
1433  unsigned int topR, topY, top, index = 0;
1434  DdNode *one = DD_ONE(dd);
1435 
1436  statLine(dd);
1437  if (Y == one) return(R);
1438 
1439 #ifdef DD_DEBUG
1440  assert(!Cudd_IsConstant(Y));
1441 #endif
1442 
1443  if (R == Cudd_Not(one)) return(R);
1444 
1445  res = cuddCacheLookup2(dd, Cudd_CProjection, R, Y);
1446  if (res != NULL) return(res);
1447 
1448  r = Cudd_Regular(R);
1449  topR = cuddI(dd,r->index);
1450  y = Cudd_Regular(Y);
1451  topY = cuddI(dd,y->index);
1452 
1453  top = ddMin(topR, topY);
1454 
1455  /* Compute the cofactors of R */
1456  if (topR == top) {
1457  index = r->index;
1458  RT = cuddT(r);
1459  RE = cuddE(r);
1460  if (r != R) {
1461  RT = Cudd_Not(RT); RE = Cudd_Not(RE);
1462  }
1463  } else {
1464  RT = RE = R;
1465  }
1466 
1467  if (topY > top) {
1468  /* Y does not depend on the current top variable.
1469  ** We just need to compute the results on the two cofactors of R
1470  ** and make them the children of a node labeled r->index.
1471  */
1472  res1 = cuddCProjectionRecur(dd,RT,Y,Ysupp);
1473  if (res1 == NULL) return(NULL);
1474  cuddRef(res1);
1475  res2 = cuddCProjectionRecur(dd,RE,Y,Ysupp);
1476  if (res2 == NULL) {
1477  Cudd_RecursiveDeref(dd,res1);
1478  return(NULL);
1479  }
1480  cuddRef(res2);
1481  res = cuddBddIteRecur(dd, dd->vars[index], res1, res2);
1482  if (res == NULL) {
1483  Cudd_RecursiveDeref(dd,res1);
1484  Cudd_RecursiveDeref(dd,res2);
1485  return(NULL);
1486  }
1487  /* If we have reached this point, res1 and res2 are now
1488  ** incorporated in res. cuddDeref is therefore sufficient.
1489  */
1490  cuddDeref(res1);
1491  cuddDeref(res2);
1492  } else {
1493  /* Compute the cofactors of Y */
1494  index = y->index;
1495  YT = cuddT(y);
1496  YE = cuddE(y);
1497  if (y != Y) {
1498  YT = Cudd_Not(YT); YE = Cudd_Not(YE);
1499  }
1500  if (YT == Cudd_Not(one)) {
1501  Alpha = Cudd_Not(dd->vars[index]);
1502  Yrest = YE;
1503  Ra = RE;
1504  Ran = RT;
1505  } else {
1506  Alpha = dd->vars[index];
1507  Yrest = YT;
1508  Ra = RT;
1509  Ran = RE;
1510  }
1511  Gamma = cuddBddExistAbstractRecur(dd,Ra,cuddT(Ysupp));
1512  if (Gamma == NULL) return(NULL);
1513  if (Gamma == one) {
1514  res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp));
1515  if (res1 == NULL) return(NULL);
1516  cuddRef(res1);
1517  res = cuddBddAndRecur(dd, Alpha, res1);
1518  if (res == NULL) {
1519  Cudd_RecursiveDeref(dd,res1);
1520  return(NULL);
1521  }
1522  cuddDeref(res1);
1523  } else if (Gamma == Cudd_Not(one)) {
1524  res1 = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp));
1525  if (res1 == NULL) return(NULL);
1526  cuddRef(res1);
1527  res = cuddBddAndRecur(dd, Cudd_Not(Alpha), res1);
1528  if (res == NULL) {
1529  Cudd_RecursiveDeref(dd,res1);
1530  return(NULL);
1531  }
1532  cuddDeref(res1);
1533  } else {
1534  cuddRef(Gamma);
1535  resA = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp));
1536  if (resA == NULL) {
1537  Cudd_RecursiveDeref(dd,Gamma);
1538  return(NULL);
1539  }
1540  cuddRef(resA);
1541  res2 = cuddBddAndRecur(dd, Cudd_Not(Gamma), resA);
1542  if (res2 == NULL) {
1543  Cudd_RecursiveDeref(dd,Gamma);
1544  Cudd_RecursiveDeref(dd,resA);
1545  return(NULL);
1546  }
1547  cuddRef(res2);
1548  Cudd_RecursiveDeref(dd,Gamma);
1549  Cudd_RecursiveDeref(dd,resA);
1550  res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp));
1551  if (res1 == NULL) {
1552  Cudd_RecursiveDeref(dd,res2);
1553  return(NULL);
1554  }
1555  cuddRef(res1);
1556  res = cuddBddIteRecur(dd, Alpha, res1, res2);
1557  if (res == NULL) {
1558  Cudd_RecursiveDeref(dd,res1);
1559  Cudd_RecursiveDeref(dd,res2);
1560  return(NULL);
1561  }
1562  cuddDeref(res1);
1563  cuddDeref(res2);
1564  }
1565  }
1566 
1567  cuddCacheInsert2(dd,Cudd_CProjection,R,Y,res);
1568 
1569  return(res);
1570 
1571 } /* end of cuddCProjectionRecur */
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:352
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddCProjectionRecur(DdManager *dd, DdNode *R, DdNode *Y, DdNode *Ysupp)
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:502
static DdNode * one
Definition: cuddDecomp.c:112
#define ddMin(x, y)
Definition: cuddInt.h:818
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
DdNode ** vars
Definition: cuddInt.h:390
DdNode * Cudd_CProjection(DdManager *dd, DdNode *R, DdNode *Y)
#define cuddE(node)
Definition: cuddInt.h:652
#define assert(ex)
Definition: util_old.h:213
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633
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 2108 of file cuddTable.c.

2111 {
2112  DdSubtable *subtables;
2113  DdNodePtr *nodelist;
2114  DdNodePtr *vars;
2115  int firstIndex, lastIndex;
2116  int index, level, newlevel;
2117  int lowestLevel;
2118  int shift;
2119  int found;
2120 
2121  /* Sanity check and set up. */
2122  if (n <= 0) return(0);
2123  if (n > unique->size) n = unique->size;
2124 
2125  subtables = unique->subtables;
2126  vars = unique->vars;
2127  firstIndex = unique->size - n;
2128  lastIndex = unique->size;
2129 
2130  /* Check for nodes labeled by the variables being destroyed
2131  ** that may still be in use. It is allowed to destroy a variable
2132  ** only if there are no such nodes. Also, find the lowest level
2133  ** among the variables being destroyed. This will make further
2134  ** processing more efficient.
2135  */
2136  lowestLevel = unique->size;
2137  for (index = firstIndex; index < lastIndex; index++) {
2138  level = unique->perm[index];
2139  if (level < lowestLevel) lowestLevel = level;
2140  nodelist = subtables[level].nodelist;
2141  if (subtables[level].keys - subtables[level].dead != 1) return(0);
2142  /* The projection function should be isolated. If the ref count
2143  ** is 1, everything is OK. If the ref count is saturated, then
2144  ** we need to make sure that there are no nodes pointing to it.
2145  ** As for the external references, we assume the application is
2146  ** responsible for them.
2147  */
2148  if (vars[index]->ref != 1) {
2149  if (vars[index]->ref != DD_MAXREF) return(0);
2150  found = cuddFindParent(unique,vars[index]);
2151  if (found) {
2152  return(0);
2153  } else {
2154  vars[index]->ref = 1;
2155  }
2156  }
2157  Cudd_RecursiveDeref(unique,vars[index]);
2158  }
2159 
2160  /* Collect garbage, because we cannot afford having dead nodes pointing
2161  ** to the dead nodes in the subtables being destroyed.
2162  */
2163  (void) cuddGarbageCollect(unique,1);
2164 
2165  /* Here we know we can destroy our subtables. */
2166  for (index = firstIndex; index < lastIndex; index++) {
2167  level = unique->perm[index];
2168  nodelist = subtables[level].nodelist;
2169 #ifdef DD_DEBUG
2170  assert(subtables[level].keys == 0);
2171 #endif
2172  ABC_FREE(nodelist);
2173  unique->memused -= sizeof(DdNodePtr) * subtables[level].slots;
2174  unique->slots -= subtables[level].slots;
2175  unique->dead -= subtables[level].dead;
2176  }
2177 
2178  /* Here all subtables to be destroyed have their keys field == 0 and
2179  ** their hash tables have been freed.
2180  ** We now scan the subtables from level lowestLevel + 1 to level size - 1,
2181  ** shifting the subtables as required. We keep a running count of
2182  ** how many subtables have been moved, so that we know by how many
2183  ** positions each subtable should be shifted.
2184  */
2185  shift = 1;
2186  for (level = lowestLevel + 1; level < unique->size; level++) {
2187  if (subtables[level].keys == 0) {
2188  shift++;
2189  continue;
2190  }
2191  newlevel = level - shift;
2192  subtables[newlevel].slots = subtables[level].slots;
2193  subtables[newlevel].shift = subtables[level].shift;
2194  subtables[newlevel].keys = subtables[level].keys;
2195  subtables[newlevel].maxKeys = subtables[level].maxKeys;
2196  subtables[newlevel].dead = subtables[level].dead;
2197  subtables[newlevel].nodelist = subtables[level].nodelist;
2198  index = unique->invperm[level];
2199  unique->perm[index] = newlevel;
2200  unique->invperm[newlevel] = index;
2201  subtables[newlevel].bindVar = subtables[level].bindVar;
2202  subtables[newlevel].varType = subtables[level].varType;
2203  subtables[newlevel].pairIndex = subtables[level].pairIndex;
2204  subtables[newlevel].varHandled = subtables[level].varHandled;
2205  subtables[newlevel].varToBeGrouped = subtables[level].varToBeGrouped;
2206  }
2207  /* Destroy the map. If a surviving variable is
2208  ** mapped to a dying variable, and the map were used again,
2209  ** an out-of-bounds access to unique->vars would result. */
2210  if (unique->map != NULL) {
2211  cuddCacheFlush(unique);
2212  ABC_FREE(unique->map);
2213  unique->map = NULL;
2214  }
2215 
2216  unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots);
2217  unique->size -= n;
2218 
2219  return(1);
2220 
2221 } /* end of cuddDestroySubtables */
DdHalfWord ref
Definition: cudd.h:280
#define DD_MAXREF
Definition: cuddInt.h:100
unsigned int keys
Definition: cuddInt.h:330
void cuddCacheFlush(DdManager *table)
Definition: cuddCache.c:1047
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
int * map
Definition: cuddInt.h:391
Definition: cudd.h:278
int size
Definition: cuddInt.h:361
double gcFrac
Definition: cuddInt.h:375
unsigned int slots
Definition: cuddInt.h:368
int bindVar
Definition: cuddInt.h:334
DdSubtable * subtables
Definition: cuddInt.h:365
DdNode * DdNodePtr
Definition: cuddInt.h:268
Cudd_VariableType varType
Definition: cuddInt.h:336
unsigned int dead
Definition: cuddInt.h:371
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:729
unsigned int dead
Definition: cuddInt.h:332
Cudd_LazyGroupType varToBeGrouped
Definition: cuddInt.h:339
static int cuddFindParent(DdManager *table, DdNode *node)
Definition: cuddTable.c:2758
unsigned int maxKeys
Definition: cuddInt.h:331
DdNode ** nodelist
Definition: cuddInt.h:327
int varHandled
Definition: cuddInt.h:338
unsigned long memused
Definition: cuddInt.h:449
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int slots
Definition: cuddInt.h:329
DdNode ** vars
Definition: cuddInt.h:390
int pairIndex
Definition: cuddInt.h:337
#define assert(ex)
Definition: util_old.h:213
int * invperm
Definition: cuddInt.h:388
int shift
Definition: cuddInt.h:328
int * perm
Definition: cuddInt.h:386
unsigned int minDead
Definition: cuddInt.h:374
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 406 of file cuddReorder.c.

408 {
409  int i;
410  DdNodePtr *mem;
411  DdNode *list, *node;
412  extern DD_OOMFP MMoutOfMemory;
413  DD_OOMFP saveHandler;
414 
415  if (table->nextFree == NULL) { /* free list is empty */
416  /* Try to allocate a new block. */
417  saveHandler = MMoutOfMemory;
418  MMoutOfMemory = Cudd_OutOfMem;
419 // mem = (DdNodePtr *) ABC_ALLOC(DdNode, DD_MEM_CHUNK + 1);
420  mem = (DdNodePtr *) ABC_ALLOC(DdNode, DD_MEM_CHUNK + 2);
421  MMoutOfMemory = saveHandler;
422  if (mem == NULL && table->stash != NULL) {
423  ABC_FREE(table->stash);
424  table->stash = NULL;
425  /* Inhibit resizing of tables. */
426  table->maxCacheHard = table->cacheSlots - 1;
427  table->cacheSlack = - (int) (table->cacheSlots + 1);
428  for (i = 0; i < table->size; i++) {
429  table->subtables[i].maxKeys <<= 2;
430  }
431 // mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1);
432  mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 2);
433  }
434  if (mem == NULL) {
435  /* Out of luck. Call the default handler to do
436  ** whatever it specifies for a failed malloc. If this
437  ** handler returns, then set error code, print
438  ** warning, and return. */
439  (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1));
440  table->errorCode = CUDD_MEMORY_OUT;
441 #ifdef DD_VERBOSE
442  (void) fprintf(table->err,
443  "cuddDynamicAllocNode: out of memory");
444  (void) fprintf(table->err,"Memory in use = %lu\n",
445  table->memused);
446 #endif
447  return(NULL);
448  } else { /* successful allocation; slice memory */
449  unsigned long offset;
450  table->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode);
451  mem[0] = (DdNode *) table->memoryList;
452  table->memoryList = mem;
453 
454  /* Here we rely on the fact that the size of a DdNode is a
455  ** power of 2 and a multiple of the size of a pointer.
456  ** If we align one node, all the others will be aligned
457  ** as well. */
458 // offset = (unsigned long) mem & (sizeof(DdNode) - 1);
459 // mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr);
460  offset = (unsigned long) mem & (32 - 1);
461  mem += (32 - offset) / sizeof(DdNodePtr);
462 #ifdef DD_DEBUG
463 // assert(((unsigned long) mem & (sizeof(DdNode) - 1)) == 0);
464  assert(((unsigned long) mem & (32 - 1)) == 0);
465 #endif
466  list = (DdNode *) mem;
467 
468  i = 1;
469  do {
470  list[i - 1].ref = 0;
471  list[i - 1].next = &list[i];
472  } while (++i < DD_MEM_CHUNK);
473 
474  list[DD_MEM_CHUNK-1].ref = 0;
475  list[DD_MEM_CHUNK - 1].next = NULL;
476 
477  table->nextFree = &list[0];
478  }
479  } /* if free list empty */
480 
481  node = table->nextFree;
482  table->nextFree = node->next;
483  return (node);
484 
485 } /* end of cuddDynamicAllocNode */
DdHalfWord ref
Definition: cudd.h:280
void(* DD_OOMFP)(long)
Definition: cudd.h:324
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2837
Definition: cudd.h:278
int size
Definition: cuddInt.h:361
unsigned int maxCacheHard
Definition: cuddInt.h:359
FILE * err
Definition: cuddInt.h:442
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdSubtable * subtables
Definition: cuddInt.h:365
struct DdNode DdNode
Definition: cudd.h:270
unsigned int cacheSlots
Definition: cuddInt.h:353
char * stash
Definition: cuddInt.h:399
DdNode * next
Definition: cudd.h:281
unsigned int maxKeys
Definition: cuddInt.h:331
int cacheSlack
Definition: cuddInt.h:358
DdNode ** memoryList
Definition: cuddInt.h:397
unsigned long memused
Definition: cuddInt.h:449
DdNode * nextFree
Definition: cuddInt.h:398
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define assert(ex)
Definition: util_old.h:213
#define DD_MEM_CHUNK
Definition: cuddInt.h:104
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
#define MMoutOfMemory
Definition: util_hack.h:38
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 153 of file cuddExact.c.

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

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

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

Description []

SideEffects [None]

SeeAlso [cuddInitTable]

Definition at line 659 of file cuddTable.c.

661 {
662  DdNodePtr *next;
663  DdNodePtr *memlist = unique->memoryList;
664  int i;
665 
666  if (unique->univ != NULL) cuddZddFreeUniv(unique);
667  while (memlist != NULL) {
668  next = (DdNodePtr *) memlist[0]; /* link to next block */
669  ABC_FREE(memlist);
670  memlist = next;
671  }
672  unique->nextFree = NULL;
673  unique->memoryList = NULL;
674 
675  for (i = 0; i < unique->size; i++) {
676  ABC_FREE(unique->subtables[i].nodelist);
677  }
678  for (i = 0; i < unique->sizeZ; i++) {
679  ABC_FREE(unique->subtableZ[i].nodelist);
680  }
681  ABC_FREE(unique->constants.nodelist);
682  ABC_FREE(unique->subtables);
683  ABC_FREE(unique->subtableZ);
684  ABC_FREE(unique->acache);
685  ABC_FREE(unique->perm);
686  ABC_FREE(unique->permZ);
687  ABC_FREE(unique->invperm);
688  ABC_FREE(unique->invpermZ);
689  ABC_FREE(unique->vars);
690  if (unique->map != NULL) ABC_FREE(unique->map);
691  ABC_FREE(unique->stack);
692 #ifndef DD_NO_DEATH_ROW
693  ABC_FREE(unique->deathRow);
694 #endif
695  if (unique->tree != NULL) Mtr_FreeTree(unique->tree);
696  if (unique->treeZ != NULL) Mtr_FreeTree(unique->treeZ);
697  if (unique->linear != NULL) ABC_FREE(unique->linear);
698  while (unique->preGCHook != NULL)
699  Cudd_RemoveHook(unique,unique->preGCHook->f,CUDD_PRE_GC_HOOK);
700  while (unique->postGCHook != NULL)
702  while (unique->preReorderingHook != NULL)
703  Cudd_RemoveHook(unique,unique->preReorderingHook->f,
705  while (unique->postReorderingHook != NULL)
706  Cudd_RemoveHook(unique,unique->postReorderingHook->f,
708  ABC_FREE(unique);
709 
710 } /* end of cuddFreeTable */
int * map
Definition: cuddInt.h:391
Definition: cudd.h:278
DdHook * preReorderingHook
Definition: cuddInt.h:439
int * invpermZ
Definition: cuddInt.h:389
int size
Definition: cuddInt.h:361
void Mtr_FreeTree(MtrNode *node)
Definition: mtrBasic.c:188
DdSubtable * subtables
Definition: cuddInt.h:365
int * permZ
Definition: cuddInt.h:387
MtrNode * tree
Definition: cuddInt.h:424
DD_HFP f
Definition: cuddInt.h:246
DdNode ** deathRow
Definition: cuddInt.h:401
DdNode ** stack
Definition: cuddInt.h:380
DdHook * postReorderingHook
Definition: cuddInt.h:440
void cuddZddFreeUniv(DdManager *zdd)
Definition: cuddInit.c:301
long * linear
Definition: cuddInt.h:395
DdNode ** nodelist
Definition: cuddInt.h:327
int Cudd_RemoveHook(DdManager *dd, DD_HFP f, Cudd_HookType where)
Definition: cuddAPI.c:3306
DdNode ** memoryList
Definition: cuddInt.h:397
DdNode * nextFree
Definition: cuddInt.h:398
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdNode ** vars
Definition: cuddInt.h:390
DdHook * postGCHook
Definition: cuddInt.h:438
MtrNode * treeZ
Definition: cuddInt.h:425
int * invperm
Definition: cuddInt.h:388
DdSubtable constants
Definition: cuddInt.h:367
DdCache * acache
Definition: cuddInt.h:351
DdHook * preGCHook
Definition: cuddInt.h:437
int * perm
Definition: cuddInt.h:386
DdSubtable * subtableZ
Definition: cuddInt.h:366
DdNode ** univ
Definition: cuddInt.h:392
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 192 of file cuddGenetic.c.

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

732 {
733  DdHook *hook;
734  DdCache *cache = unique->cache;
735  DdNode *sentinel = &(unique->sentinel);
736  DdNodePtr *nodelist;
737  int i, j, deleted, totalDeleted, totalDeletedZ;
738  DdCache *c;
739  DdNode *node,*next;
740  DdNodePtr *lastP;
741  int slots;
742  long localTime;
743 #ifndef DD_UNSORTED_FREE_LIST
744 #ifdef DD_RED_BLACK_FREE_LIST
745  DdNodePtr tree;
746 #else
747  DdNodePtr *memListTrav, *nxtNode;
748  DdNode *downTrav, *sentry;
749  int k;
750 #endif
751 #endif
752 
753 #ifndef DD_NO_DEATH_ROW
754  cuddClearDeathRow(unique);
755 #endif
756 
757  hook = unique->preGCHook;
758  while (hook != NULL) {
759  int res = (hook->f)(unique,"DD",NULL);
760  if (res == 0) return(0);
761  hook = hook->next;
762  }
763 
764  if (unique->dead + unique->deadZ == 0) {
765  hook = unique->postGCHook;
766  while (hook != NULL) {
767  int res = (hook->f)(unique,"DD",NULL);
768  if (res == 0) return(0);
769  hook = hook->next;
770  }
771  return(0);
772  }
773 
774  /* If many nodes are being reclaimed, we want to resize the tables
775  ** more aggressively, to reduce the frequency of garbage collection.
776  */
777  if (clearCache && unique->gcFrac == DD_GC_FRAC_LO &&
778  unique->slots <= unique->looseUpTo && unique->stash != NULL) {
779  unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots);
780 #ifdef DD_VERBOSE
781  (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_HI);
782  (void) fprintf(unique->err,"minDead = %d\n", unique->minDead);
783 #endif
784  unique->gcFrac = DD_GC_FRAC_HI;
785  return(0);
786  }
787 
788  localTime = util_cpu_time();
789 
790  unique->garbageCollections++;
791 #ifdef DD_VERBOSE
792  (void) fprintf(unique->err,
793  "garbage collecting (%d dead BDD nodes out of %d, min %d)...",
794  unique->dead, unique->keys, unique->minDead);
795  (void) fprintf(unique->err,
796  " (%d dead ZDD nodes out of %d)...",
797  unique->deadZ, unique->keysZ);
798 #endif
799 
800  /* Remove references to garbage collected nodes from the cache. */
801  if (clearCache) {
802  slots = unique->cacheSlots;
803  for (i = 0; i < slots; i++) {
804  c = &cache[i];
805  if (c->data != NULL) {
806  if (cuddClean(c->f)->ref == 0 ||
807  cuddClean(c->g)->ref == 0 ||
808  (((ptruint)c->f & 0x2) && Cudd_Regular(c->h)->ref == 0) ||
809  (c->data != DD_NON_CONSTANT &&
810  Cudd_Regular(c->data)->ref == 0)) {
811  c->data = NULL;
812  unique->cachedeletions++;
813  }
814  }
815  }
816  cuddLocalCacheClearDead(unique);
817  }
818 
819  /* Now return dead nodes to free list. Count them for sanity check. */
820  totalDeleted = 0;
821 #ifndef DD_UNSORTED_FREE_LIST
822 #ifdef DD_RED_BLACK_FREE_LIST
823  tree = NULL;
824 #endif
825 #endif
826 
827  for (i = 0; i < unique->size; i++) {
828  if (unique->subtables[i].dead == 0) continue;
829  nodelist = unique->subtables[i].nodelist;
830 
831  deleted = 0;
832  slots = unique->subtables[i].slots;
833  for (j = 0; j < slots; j++) {
834  lastP = &(nodelist[j]);
835  node = *lastP;
836  while (node != sentinel) {
837  next = node->next;
838  if (node->ref == 0) {
839  deleted++;
840 #ifndef DD_UNSORTED_FREE_LIST
841 #ifdef DD_RED_BLACK_FREE_LIST
842 #ifdef __osf__
843 #pragma pointer_size save
844 #pragma pointer_size short
845 #endif
846  cuddOrderedInsert(&tree,node);
847 #ifdef __osf__
848 #pragma pointer_size restore
849 #endif
850 #endif
851 #else
852  cuddDeallocNode(unique,node);
853 #endif
854  } else {
855  *lastP = node;
856  lastP = &(node->next);
857  }
858  node = next;
859  }
860  *lastP = sentinel;
861  }
862  if ((unsigned) deleted != unique->subtables[i].dead) {
863  ddReportRefMess(unique, i, "cuddGarbageCollect");
864  }
865  totalDeleted += deleted;
866  unique->subtables[i].keys -= deleted;
867  unique->subtables[i].dead = 0;
868  }
869  if (unique->constants.dead != 0) {
870  nodelist = unique->constants.nodelist;
871  deleted = 0;
872  slots = unique->constants.slots;
873  for (j = 0; j < slots; j++) {
874  lastP = &(nodelist[j]);
875  node = *lastP;
876  while (node != NULL) {
877  next = node->next;
878  if (node->ref == 0) {
879  deleted++;
880 #ifndef DD_UNSORTED_FREE_LIST
881 #ifdef DD_RED_BLACK_FREE_LIST
882 #ifdef __osf__
883 #pragma pointer_size save
884 #pragma pointer_size short
885 #endif
886  cuddOrderedInsert(&tree,node);
887 #ifdef __osf__
888 #pragma pointer_size restore
889 #endif
890 #endif
891 #else
892  cuddDeallocNode(unique,node);
893 #endif
894  } else {
895  *lastP = node;
896  lastP = &(node->next);
897  }
898  node = next;
899  }
900  *lastP = NULL;
901  }
902  if ((unsigned) deleted != unique->constants.dead) {
903  ddReportRefMess(unique, CUDD_CONST_INDEX, "cuddGarbageCollect");
904  }
905  totalDeleted += deleted;
906  unique->constants.keys -= deleted;
907  unique->constants.dead = 0;
908  }
909  if ((unsigned) totalDeleted != unique->dead) {
910  ddReportRefMess(unique, -1, "cuddGarbageCollect");
911  }
912  unique->keys -= totalDeleted;
913  unique->dead = 0;
914 #ifdef DD_STATS
915  unique->nodesFreed += (double) totalDeleted;
916 #endif
917 
918  totalDeletedZ = 0;
919 
920  for (i = 0; i < unique->sizeZ; i++) {
921  if (unique->subtableZ[i].dead == 0) continue;
922  nodelist = unique->subtableZ[i].nodelist;
923 
924  deleted = 0;
925  slots = unique->subtableZ[i].slots;
926  for (j = 0; j < slots; j++) {
927  lastP = &(nodelist[j]);
928  node = *lastP;
929  while (node != NULL) {
930  next = node->next;
931  if (node->ref == 0) {
932  deleted++;
933 #ifndef DD_UNSORTED_FREE_LIST
934 #ifdef DD_RED_BLACK_FREE_LIST
935 #ifdef __osf__
936 #pragma pointer_size save
937 #pragma pointer_size short
938 #endif
939  cuddOrderedInsert(&tree,node);
940 #ifdef __osf__
941 #pragma pointer_size restore
942 #endif
943 #endif
944 #else
945  cuddDeallocNode(unique,node);
946 #endif
947  } else {
948  *lastP = node;
949  lastP = &(node->next);
950  }
951  node = next;
952  }
953  *lastP = NULL;
954  }
955  if ((unsigned) deleted != unique->subtableZ[i].dead) {
956  ddReportRefMess(unique, i, "cuddGarbageCollect");
957  }
958  totalDeletedZ += deleted;
959  unique->subtableZ[i].keys -= deleted;
960  unique->subtableZ[i].dead = 0;
961  }
962 
963  /* No need to examine the constant table for ZDDs.
964  ** If we did we should be careful not to count whatever dead
965  ** nodes we found there among the dead ZDD nodes. */
966  if ((unsigned) totalDeletedZ != unique->deadZ) {
967  ddReportRefMess(unique, -1, "cuddGarbageCollect");
968  }
969  unique->keysZ -= totalDeletedZ;
970  unique->deadZ = 0;
971 #ifdef DD_STATS
972  unique->nodesFreed += (double) totalDeletedZ;
973 #endif
974 
975 
976 #ifndef DD_UNSORTED_FREE_LIST
977 #ifdef DD_RED_BLACK_FREE_LIST
978  unique->nextFree = cuddOrderedThread(tree,unique->nextFree);
979 #else
980  memListTrav = unique->memoryList;
981  sentry = NULL;
982  while (memListTrav != NULL) {
983  ptruint offset;
984  nxtNode = (DdNodePtr *)memListTrav[0];
985 // offset = (ptruint) memListTrav & (sizeof(DdNode) - 1);
986 // memListTrav += (sizeof(DdNode) - offset) / sizeof(DdNodePtr);
987  offset = (ptruint) memListTrav & (32 - 1);
988  memListTrav += (32 - offset) / sizeof(DdNodePtr);
989 
990  downTrav = (DdNode *)memListTrav;
991  k = 0;
992  do {
993  if (downTrav[k].ref == 0) {
994  if (sentry == NULL) {
995  unique->nextFree = sentry = &downTrav[k];
996  } else {
997  /* First hook sentry->next to the dead node and then
998  ** reassign sentry to the dead node. */
999  sentry = (sentry->next = &downTrav[k]);
1000  }
1001  }
1002  } while (++k < DD_MEM_CHUNK);
1003  memListTrav = nxtNode;
1004  }
1005  sentry->next = NULL;
1006 #endif
1007 #endif
1008 
1009  unique->GCTime += util_cpu_time() - localTime;
1010 
1011  hook = unique->postGCHook;
1012  while (hook != NULL) {
1013  int res = (hook->f)(unique,"DD",NULL);
1014  if (res == 0) return(0);
1015  hook = hook->next;
1016  }
1017 
1018 #ifdef DD_VERBOSE
1019  (void) fprintf(unique->err," done\n");
1020 #endif
1021 
1022  return(totalDeleted+totalDeletedZ);
1023 
1024 } /* end of cuddGarbageCollect */
static void ddReportRefMess(DdManager *unique, int i, const char *caller)
Definition: cuddTable.c:3157
DdHalfWord ref
Definition: cudd.h:280
unsigned int keys
Definition: cuddInt.h:330
DdNode * f
Definition: cuddInt.h:317
Definition: cudd.h:278
unsigned int deadZ
Definition: cuddInt.h:372
DdNode * data
Definition: cuddInt.h:319
int size
Definition: cuddInt.h:361
double gcFrac
Definition: cuddInt.h:375
unsigned int slots
Definition: cuddInt.h:368
ptruint h
Definition: cuddInt.h:318
#define Cudd_Regular(node)
Definition: cudd.h:397
FILE * err
Definition: cuddInt.h:442
DdNode * g
Definition: cuddInt.h:317
int garbageCollections
Definition: cuddInt.h:452
DdSubtable * subtables
Definition: cuddInt.h:365
#define util_cpu_time
Definition: util_hack.h:36
DD_HFP f
Definition: cuddInt.h:246
ABC_PTRUINT_T ptruint
Definition: cuddInt.h:261
#define DD_GC_FRAC_HI
Definition: cuddInt.h:134
unsigned int dead
Definition: cuddInt.h:371
unsigned int cacheSlots
Definition: cuddInt.h:353
DdNode sentinel
Definition: cuddInt.h:344
char * stash
Definition: cuddInt.h:399
unsigned int keys
Definition: cuddInt.h:369
unsigned int dead
Definition: cuddInt.h:332
DdCache * cache
Definition: cuddInt.h:352
DdNode * next
Definition: cudd.h:281
#define DD_GC_FRAC_LO
Definition: cuddInt.h:133
long GCTime
Definition: cuddInt.h:453
#define CUDD_CONST_INDEX
Definition: cudd.h:117
DdNode ** nodelist
Definition: cuddInt.h:327
void cuddLocalCacheClearDead(DdManager *manager)
Definition: cuddLCache.c:352
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:547
DdNode ** memoryList
Definition: cuddInt.h:397
DdNode * nextFree
Definition: cuddInt.h:398
struct DdHook * next
Definition: cuddInt.h:247
void cuddClearDeathRow(DdManager *table)
Definition: cuddRef.c:726
int sizeZ
Definition: cuddInt.h:362
unsigned int looseUpTo
Definition: cuddInt.h:377
unsigned int slots
Definition: cuddInt.h:329
DdHook * postGCHook
Definition: cuddInt.h:438
#define cuddClean(p)
Definition: cuddInt.h:804
DdSubtable constants
Definition: cuddInt.h:367
double cachedeletions
Definition: cuddInt.h:460
#define DD_MEM_CHUNK
Definition: cuddInt.h:104
unsigned int keysZ
Definition: cuddInt.h:370
DdHook * preGCHook
Definition: cuddInt.h:437
unsigned int minDead
Definition: cuddInt.h:374
DdSubtable * subtableZ
Definition: cuddInt.h:366
#define DD_NON_CONSTANT
Definition: cuddInt.h:123
void cuddGetBranches ( DdNode g,
DdNode **  g1,
DdNode **  g0 
)

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

Synopsis [Computes the children of g.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 162 of file cuddCof.c.

166 {
167  DdNode *G = Cudd_Regular(g);
168 
169  *g1 = cuddT(G);
170  *g0 = cuddE(G);
171  if (Cudd_IsComplement(g)) {
172  *g1 = Cudd_Not(*g1);
173  *g0 = Cudd_Not(*g0);
174  }
175 
176 } /* end of cuddGetBranches */
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_Regular(node)
Definition: cudd.h:397
#define Cudd_IsComplement(node)
Definition: cudd.h:425
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddE(node)
Definition: cuddInt.h:652
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 538 of file cuddLCache.c.

542 {
543  DdHashTable *hash;
544  int logSize;
545 
546 #ifdef __osf__
547 #pragma pointer_size save
548 #pragma pointer_size short
549 #endif
550  hash = ABC_ALLOC(DdHashTable, 1);
551  if (hash == NULL) {
552  manager->errorCode = CUDD_MEMORY_OUT;
553  return(NULL);
554  }
555  hash->keysize = keySize;
556  hash->manager = manager;
557  hash->memoryList = NULL;
558  hash->nextFree = NULL;
559  hash->itemsize = (keySize + 1) * sizeof(DdNode *) +
560  sizeof(ptrint) + sizeof(DdHashItem *);
561  /* We have to guarantee that the shift be < 32. */
562  if (initSize < 2) initSize = 2;
563  logSize = cuddComputeFloorLog2(initSize);
564  hash->numBuckets = 1 << logSize;
565  hash->shift = sizeof(int) * 8 - logSize;
566  hash->bucket = ABC_ALLOC(DdHashItem *, hash->numBuckets);
567  if (hash->bucket == NULL) {
568  manager->errorCode = CUDD_MEMORY_OUT;
569  ABC_FREE(hash);
570  return(NULL);
571  }
572  memset(hash->bucket, 0, hash->numBuckets * sizeof(DdHashItem *));
573  hash->size = 0;
575 #ifdef __osf__
576 #pragma pointer_size restore
577 #endif
578  return(hash);
579 
580 } /* end of cuddHashTableInit */
char * memset()
unsigned int keysize
Definition: cuddInt.h:304
DdHashItem ** bucket
Definition: cuddInt.h:306
unsigned int size
Definition: cuddInt.h:311
Definition: cudd.h:278
DdManager * manager
Definition: cuddInt.h:313
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
ABC_PTRINT_T ptrint
Definition: cuddInt.h:260
unsigned int numBuckets
Definition: cuddInt.h:309
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1079
static uint32_t hash(uint32_t x)
Definition: Map.h:38
unsigned int maxsize
Definition: cuddInt.h:312
unsigned int itemsize
Definition: cuddInt.h:305
DdHashItem * nextFree
Definition: cuddInt.h:307
#define ABC_FREE(obj)
Definition: abc_global.h:232
int shift
Definition: cuddInt.h:310
DdHashItem ** memoryList
Definition: cuddInt.h:308
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
#define DD_MAX_HASHTABLE_DENSITY
Definition: cuddLCache.c:86
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 648 of file cuddLCache.c.

653 {
654  int result;
655  unsigned int posn;
656  DdHashItem *item;
657  unsigned int i;
658 
659 #ifdef DD_DEBUG
660  assert(hash->keysize > 3);
661 #endif
662 
663  if (hash->size > hash->maxsize) {
664  result = cuddHashTableResize(hash);
665  if (result == 0) return(0);
666  }
667  item = cuddHashTableAlloc(hash);
668  if (item == NULL) return(0);
669  hash->size++;
670  item->value = value;
671  cuddRef(value);
672  item->count = count;
673  for (i = 0; i < hash->keysize; i++) {
674  item->key[i] = key[i];
675  }
676  posn = ddLCHash(key,hash->keysize,hash->shift);
677  item->next = hash->bucket[posn];
678  hash->bucket[posn] = item;
679 
680  return(1);
681 
682 } /* end of cuddHashTableInsert */
unsigned int keysize
Definition: cuddInt.h:304
#define cuddRef(n)
Definition: cuddInt.h:584
DdHashItem ** bucket
Definition: cuddInt.h:306
DdNode * value
Definition: cuddInt.h:298
unsigned int size
Definition: cuddInt.h:311
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddLCache.c:1393
ptrint count
Definition: cuddInt.h:297
struct DdHashItem * next
Definition: cuddInt.h:296
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddLCache.c:1182
unsigned int maxsize
Definition: cuddInt.h:312
int value
DdNode * key[1]
Definition: cuddInt.h:299
#define assert(ex)
Definition: util_old.h:213
int shift
Definition: cuddInt.h:310
static int result
Definition: cuddGenetic.c:125
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddLCache.c:1277
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 767 of file cuddLCache.c.

772 {
773  int result;
774  unsigned int posn;
775  DdHashItem *item;
776 
777 #ifdef DD_DEBUG
778  assert(hash->keysize == 1);
779 #endif
780 
781  if (hash->size > hash->maxsize) {
782  result = cuddHashTableResize(hash);
783  if (result == 0) return(0);
784  }
785  item = cuddHashTableAlloc(hash);
786  if (item == NULL) return(0);
787  hash->size++;
788  item->value = value;
789  cuddRef(value);
790  item->count = count;
791  item->key[0] = f;
792  posn = ddLCHash2(cuddF2L(f),cuddF2L(f),hash->shift);
793  item->next = hash->bucket[posn];
794  hash->bucket[posn] = item;
795 
796  return(1);
797 
798 } /* end of cuddHashTableInsert1 */
unsigned int keysize
Definition: cuddInt.h:304
#define cuddRef(n)
Definition: cuddInt.h:584
DdHashItem ** bucket
Definition: cuddInt.h:306
DdNode * value
Definition: cuddInt.h:298
unsigned int size
Definition: cuddInt.h:311
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddLCache.c:1393
ptrint count
Definition: cuddInt.h:297
struct DdHashItem * next
Definition: cuddInt.h:296
#define cuddF2L(f)
Definition: cuddInt.h:718
unsigned int maxsize
Definition: cuddInt.h:312
int value
DdNode * key[1]
Definition: cuddInt.h:299
#define ddLCHash2(f, g, shift)
Definition: cuddLCache.c:126
#define assert(ex)
Definition: util_old.h:213
int shift
Definition: cuddInt.h:310
static int result
Definition: cuddGenetic.c:125
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddLCache.c:1277
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 874 of file cuddLCache.c.

880 {
881  int result;
882  unsigned int posn;
883  DdHashItem *item;
884 
885 #ifdef DD_DEBUG
886  assert(hash->keysize == 2);
887 #endif
888 
889  if (hash->size > hash->maxsize) {
890  result = cuddHashTableResize(hash);
891  if (result == 0) return(0);
892  }
893  item = cuddHashTableAlloc(hash);
894  if (item == NULL) return(0);
895  hash->size++;
896  item->value = value;
897  cuddRef(value);
898  item->count = count;
899  item->key[0] = f;
900  item->key[1] = g;
901  posn = ddLCHash2(cuddF2L(f),cuddF2L(g),hash->shift);
902  item->next = hash->bucket[posn];
903  hash->bucket[posn] = item;
904 
905  return(1);
906 
907 } /* end of cuddHashTableInsert2 */
unsigned int keysize
Definition: cuddInt.h:304
#define cuddRef(n)
Definition: cuddInt.h:584
DdHashItem ** bucket
Definition: cuddInt.h:306
DdNode * value
Definition: cuddInt.h:298
unsigned int size
Definition: cuddInt.h:311
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddLCache.c:1393
ptrint count
Definition: cuddInt.h:297
struct DdHashItem * next
Definition: cuddInt.h:296
#define cuddF2L(f)
Definition: cuddInt.h:718
unsigned int maxsize
Definition: cuddInt.h:312
int value
DdNode * key[1]
Definition: cuddInt.h:299
#define ddLCHash2(f, g, shift)
Definition: cuddLCache.c:126
#define assert(ex)
Definition: util_old.h:213
int shift
Definition: cuddInt.h:310
static int result
Definition: cuddGenetic.c:125
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddLCache.c:1277
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 984 of file cuddLCache.c.

991 {
992  int result;
993  unsigned int posn;
994  DdHashItem *item;
995 
996 #ifdef DD_DEBUG
997  assert(hash->keysize == 3);
998 #endif
999 
1000  if (hash->size > hash->maxsize) {
1001  result = cuddHashTableResize(hash);
1002  if (result == 0) return(0);
1003  }
1004  item = cuddHashTableAlloc(hash);
1005  if (item == NULL) return(0);
1006  hash->size++;
1007  item->value = value;
1008  cuddRef(value);
1009  item->count = count;
1010  item->key[0] = f;
1011  item->key[1] = g;
1012  item->key[2] = h;
1013  posn = ddLCHash3(cuddF2L(f),cuddF2L(g),cuddF2L(h),hash->shift);
1014  item->next = hash->bucket[posn];
1015  hash->bucket[posn] = item;
1016 
1017  return(1);
1018 
1019 } /* end of cuddHashTableInsert3 */
unsigned int keysize
Definition: cuddInt.h:304
#define cuddRef(n)
Definition: cuddInt.h:584
DdHashItem ** bucket
Definition: cuddInt.h:306
DdNode * value
Definition: cuddInt.h:298
unsigned int size
Definition: cuddInt.h:311
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddLCache.c:1393
ptrint count
Definition: cuddInt.h:297
struct DdHashItem * next
Definition: cuddInt.h:296
#define cuddF2L(f)
Definition: cuddInt.h:718
unsigned int maxsize
Definition: cuddInt.h:312
int value
DdNode * key[1]
Definition: cuddInt.h:299
#define assert(ex)
Definition: util_old.h:213
int shift
Definition: cuddInt.h:310
static int result
Definition: cuddGenetic.c:125
#define ddLCHash3(f, g, h, shift)
Definition: cuddLCache.c:142
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddLCache.c:1277
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 703 of file cuddLCache.c.

706 {
707  unsigned int posn;
708  DdHashItem *item, *prev;
709  unsigned int i, keysize;
710 
711 #ifdef DD_DEBUG
712  assert(hash->keysize > 3);
713 #endif
714 
715  posn = ddLCHash(key,hash->keysize,hash->shift);
716  item = hash->bucket[posn];
717  prev = NULL;
718 
719  keysize = hash->keysize;
720  while (item != NULL) {
721  DdNodePtr *key2 = item->key;
722  int equal = 1;
723  for (i = 0; i < keysize; i++) {
724  if (key[i] != key2[i]) {
725  equal = 0;
726  break;
727  }
728  }
729  if (equal) {
730  DdNode *value = item->value;
731  cuddSatDec(item->count);
732  if (item->count == 0) {
733  cuddDeref(value);
734  if (prev == NULL) {
735  hash->bucket[posn] = item->next;
736  } else {
737  prev->next = item->next;
738  }
739  item->next = hash->nextFree;
740  hash->nextFree = item;
741  hash->size--;
742  }
743  return(value);
744  }
745  prev = item;
746  item = item->next;
747  }
748  return(NULL);
749 
750 } /* end of cuddHashTableLookup */
unsigned int keysize
Definition: cuddInt.h:304
DdHashItem ** bucket
Definition: cuddInt.h:306
DdNode * value
Definition: cuddInt.h:298
unsigned int size
Definition: cuddInt.h:311
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
ptrint count
Definition: cuddInt.h:297
struct DdHashItem * next
Definition: cuddInt.h:296
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddLCache.c:1182
DdHashItem * nextFree
Definition: cuddInt.h:307
int value
#define cuddSatDec(x)
Definition: cuddInt.h:896
DdNode * key[1]
Definition: cuddInt.h:299
#define assert(ex)
Definition: util_old.h:213
int shift
Definition: cuddInt.h:310
#define equal(a, b)
Definition: espresso.h:326
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 819 of file cuddLCache.c.

822 {
823  unsigned int posn;
824  DdHashItem *item, *prev;
825 
826 #ifdef DD_DEBUG
827  assert(hash->keysize == 1);
828 #endif
829 
830  posn = ddLCHash2(cuddF2L(f),cuddF2L(f),hash->shift);
831  item = hash->bucket[posn];
832  prev = NULL;
833 
834  while (item != NULL) {
835  DdNodePtr *key = item->key;
836  if (f == key[0]) {
837  DdNode *value = item->value;
838  cuddSatDec(item->count);
839  if (item->count == 0) {
840  cuddDeref(value);
841  if (prev == NULL) {
842  hash->bucket[posn] = item->next;
843  } else {
844  prev->next = item->next;
845  }
846  item->next = hash->nextFree;
847  hash->nextFree = item;
848  hash->size--;
849  }
850  return(value);
851  }
852  prev = item;
853  item = item->next;
854  }
855  return(NULL);
856 
857 } /* end of cuddHashTableLookup1 */
unsigned int keysize
Definition: cuddInt.h:304
DdHashItem ** bucket
Definition: cuddInt.h:306
DdNode * value
Definition: cuddInt.h:298
unsigned int size
Definition: cuddInt.h:311
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
ptrint count
Definition: cuddInt.h:297
struct DdHashItem * next
Definition: cuddInt.h:296
#define cuddF2L(f)
Definition: cuddInt.h:718
DdHashItem * nextFree
Definition: cuddInt.h:307
enum keys key
int value
#define cuddSatDec(x)
Definition: cuddInt.h:896
DdNode * key[1]
Definition: cuddInt.h:299
#define ddLCHash2(f, g, shift)
Definition: cuddLCache.c:126
#define assert(ex)
Definition: util_old.h:213
int shift
Definition: cuddInt.h:310
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 928 of file cuddLCache.c.

932 {
933  unsigned int posn;
934  DdHashItem *item, *prev;
935 
936 #ifdef DD_DEBUG
937  assert(hash->keysize == 2);
938 #endif
939 
940  posn = ddLCHash2(cuddF2L(f),cuddF2L(g),hash->shift);
941  item = hash->bucket[posn];
942  prev = NULL;
943 
944  while (item != NULL) {
945  DdNodePtr *key = item->key;
946  if ((f == key[0]) && (g == key[1])) {
947  DdNode *value = item->value;
948  cuddSatDec(item->count);
949  if (item->count == 0) {
950  cuddDeref(value);
951  if (prev == NULL) {
952  hash->bucket[posn] = item->next;
953  } else {
954  prev->next = item->next;
955  }
956  item->next = hash->nextFree;
957  hash->nextFree = item;
958  hash->size--;
959  }
960  return(value);
961  }
962  prev = item;
963  item = item->next;
964  }
965  return(NULL);
966 
967 } /* end of cuddHashTableLookup2 */
unsigned int keysize
Definition: cuddInt.h:304
DdHashItem ** bucket
Definition: cuddInt.h:306
DdNode * value
Definition: cuddInt.h:298
unsigned int size
Definition: cuddInt.h:311
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
ptrint count
Definition: cuddInt.h:297
struct DdHashItem * next
Definition: cuddInt.h:296
#define cuddF2L(f)
Definition: cuddInt.h:718
DdHashItem * nextFree
Definition: cuddInt.h:307
enum keys key
int value
#define cuddSatDec(x)
Definition: cuddInt.h:896
DdNode * key[1]
Definition: cuddInt.h:299
#define ddLCHash2(f, g, shift)
Definition: cuddLCache.c:126
#define assert(ex)
Definition: util_old.h:213
int shift
Definition: cuddInt.h:310
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 1040 of file cuddLCache.c.

1045 {
1046  unsigned int posn;
1047  DdHashItem *item, *prev;
1048 
1049 #ifdef DD_DEBUG
1050  assert(hash->keysize == 3);
1051 #endif
1052 
1053  posn = ddLCHash3(cuddF2L(f),cuddF2L(g),cuddF2L(h),hash->shift);
1054  item = hash->bucket[posn];
1055  prev = NULL;
1056 
1057  while (item != NULL) {
1058  DdNodePtr *key = item->key;
1059  if ((f == key[0]) && (g == key[1]) && (h == key[2])) {
1060  DdNode *value = item->value;
1061  cuddSatDec(item->count);
1062  if (item->count == 0) {
1063  cuddDeref(value);
1064  if (prev == NULL) {
1065  hash->bucket[posn] = item->next;
1066  } else {
1067  prev->next = item->next;
1068  }
1069  item->next = hash->nextFree;
1070  hash->nextFree = item;
1071  hash->size--;
1072  }
1073  return(value);
1074  }
1075  prev = item;
1076  item = item->next;
1077  }
1078  return(NULL);
1079 
1080 } /* end of cuddHashTableLookup3 */
unsigned int keysize
Definition: cuddInt.h:304
DdHashItem ** bucket
Definition: cuddInt.h:306
DdNode * value
Definition: cuddInt.h:298
unsigned int size
Definition: cuddInt.h:311
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
ptrint count
Definition: cuddInt.h:297
struct DdHashItem * next
Definition: cuddInt.h:296
#define cuddF2L(f)
Definition: cuddInt.h:718
DdHashItem * nextFree
Definition: cuddInt.h:307
enum keys key
int value
#define cuddSatDec(x)
Definition: cuddInt.h:896
DdNode * key[1]
Definition: cuddInt.h:299
#define assert(ex)
Definition: util_old.h:213
int shift
Definition: cuddInt.h:310
#define ddLCHash3(f, g, h, shift)
Definition: cuddLCache.c:142
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 595 of file cuddLCache.c.

597 {
598 #ifdef __osf__
599 #pragma pointer_size save
600 #pragma pointer_size short
601 #endif
602  unsigned int i;
603  DdManager *dd = hash->manager;
604  DdHashItem *bucket;
605  DdHashItem **memlist, **nextmem;
606  unsigned int numBuckets = hash->numBuckets;
607 
608  for (i = 0; i < numBuckets; i++) {
609  bucket = hash->bucket[i];
610  while (bucket != NULL) {
611  Cudd_RecursiveDeref(dd, bucket->value);
612  bucket = bucket->next;
613  }
614  }
615 
616  memlist = hash->memoryList;
617  while (memlist != NULL) {
618  nextmem = (DdHashItem **) memlist[0];
619  ABC_FREE(memlist);
620  memlist = nextmem;
621  }
622 
623  ABC_FREE(hash->bucket);
624  ABC_FREE(hash);
625 #ifdef __osf__
626 #pragma pointer_size restore
627 #endif
628 
629  return;
630 
631 } /* end of cuddHashTableQuit */
DdHashItem ** bucket
Definition: cuddInt.h:306
DdNode * value
Definition: cuddInt.h:298
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
DdManager * manager
Definition: cuddInt.h:313
struct DdHashItem * next
Definition: cuddInt.h:296
unsigned int numBuckets
Definition: cuddInt.h:309
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdHashItem ** memoryList
Definition: cuddInt.h:308
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 639 of file cuddCheck.c.

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

140 {
141  int i;
142  unsigned int logSize;
143 #ifndef DD_CACHE_PROFILE
144  DdNodePtr *mem;
145  ptruint offset;
146 #endif
147 
148  /* Round cacheSize to largest power of 2 not greater than the requested
149  ** initial cache size. */
150  logSize = cuddComputeFloorLog2(ddMax(cacheSize,unique->slots/2));
151  cacheSize = 1 << logSize;
152 // unique->acache = ABC_ALLOC(DdCache,cacheSize+1);
153  unique->acache = ABC_ALLOC(DdCache,cacheSize+2);
154  if (unique->acache == NULL) {
155  unique->errorCode = CUDD_MEMORY_OUT;
156  return(0);
157  }
158  /* If the size of the cache entry is a power of 2, we want to
159  ** enforce alignment to that power of two. This happens when
160  ** DD_CACHE_PROFILE is not defined. */
161 #ifdef DD_CACHE_PROFILE
162  unique->cache = unique->acache;
163  unique->memused += (cacheSize) * sizeof(DdCache);
164 #else
165  mem = (DdNodePtr *) unique->acache;
166 // offset = (ptruint) mem & (sizeof(DdCache) - 1);
167 // mem += (sizeof(DdCache) - offset) / sizeof(DdNodePtr);
168  offset = (ptruint) mem & (32 - 1);
169  mem += (32 - offset) / sizeof(DdNodePtr);
170  unique->cache = (DdCache *) mem;
171 // assert(((ptruint) unique->cache & (sizeof(DdCache) - 1)) == 0);
172  assert(((ptruint) unique->cache & (32 - 1)) == 0);
173  unique->memused += (cacheSize+1) * sizeof(DdCache);
174 #endif
175  unique->cacheSlots = cacheSize;
176  unique->cacheShift = sizeof(int) * 8 - logSize;
177  unique->maxCacheHard = maxCacheSize;
178  /* If cacheSlack is non-negative, we can resize. */
179  unique->cacheSlack = (int) ddMin(maxCacheSize,
181  2 * (int) cacheSize;
182  Cudd_SetMinHit(unique,DD_MIN_HIT);
183  /* Initialize to avoid division by 0 and immediate resizing. */
184  unique->cacheMisses = (double) (int) (cacheSize * unique->minHit + 1);
185  unique->cacheHits = 0;
186  unique->totCachehits = 0;
187  /* The sum of cacheMisses and totCacheMisses is always correct,
188  ** even though cacheMisses is larger than it should for the reasons
189  ** explained above. */
190  unique->totCacheMisses = -unique->cacheMisses;
191  unique->cachecollisions = 0;
192  unique->cacheinserts = 0;
193  unique->cacheLastInserts = 0;
194  unique->cachedeletions = 0;
195 
196  /* Initialize the cache */
197  for (i = 0; (unsigned) i < cacheSize; i++) {
198  unique->cache[i].h = 0; /* unused slots */
199  unique->cache[i].data = NULL; /* invalid entry */
200 #ifdef DD_CACHE_PROFILE
201  unique->cache[i].count = 0;
202 #endif
203  }
204 
205  return(1);
206 
207 } /* end of cuddInitCache */
Definition: cudd.h:278
DdNode * data
Definition: cuddInt.h:319
unsigned int maxCacheHard
Definition: cuddInt.h:359
unsigned int slots
Definition: cuddInt.h:368
ptruint h
Definition: cuddInt.h:318
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
double cachecollisions
Definition: cuddInt.h:457
#define DD_MIN_HIT
Definition: cuddInt.h:136
double cacheinserts
Definition: cuddInt.h:458
ABC_PTRUINT_T ptruint
Definition: cuddInt.h:261
unsigned int cacheSlots
Definition: cuddInt.h:353
DdCache * cache
Definition: cuddInt.h:352
double totCacheMisses
Definition: cuddInt.h:456
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1079
#define ddMax(x, y)
Definition: cuddInt.h:832
double cacheLastInserts
Definition: cuddInt.h:459
double cacheHits
Definition: cuddInt.h:356
#define ddMin(x, y)
Definition: cuddInt.h:818
#define DD_MAX_CACHE_TO_SLOTS_RATIO
Definition: cuddInt.h:144
void Cudd_SetMinHit(DdManager *dd, unsigned int hr)
Definition: cuddAPI.c:1298
int cacheSlack
Definition: cuddInt.h:358
unsigned long memused
Definition: cuddInt.h:449
double cacheMisses
Definition: cuddInt.h:355
double minHit
Definition: cuddInt.h:357
int cacheShift
Definition: cuddInt.h:354
#define assert(ex)
Definition: util_old.h:213
double cachedeletions
Definition: cuddInt.h:460
DdCache * acache
Definition: cuddInt.h:351
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
double totCachehits
Definition: cuddInt.h:455
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 237 of file cuddInteract.c.

239 {
240  int i,j,k;
241  ABC_UINT64_T words;
242  long *interact;
243  int *support;
244  DdNode *f;
245  DdNode *sentinel = &(table->sentinel);
246  DdNodePtr *nodelist;
247  int slots;
248  int n = table->size;
249 
250  words = ((n * (n-1)) >> (1 + LOGBPL)) + 1;
251  table->interact = interact = ABC_ALLOC(long,(unsigned)words);
252  if (interact == NULL) {
253  table->errorCode = CUDD_MEMORY_OUT;
254  return(0);
255  }
256  for (i = 0; i < words; i++) {
257  interact[i] = 0;
258  }
259 
260  support = ABC_ALLOC(int,n);
261  if (support == NULL) {
262  table->errorCode = CUDD_MEMORY_OUT;
263  ABC_FREE(interact);
264  return(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  for (k = 0; k < n; k++) {
281  support[k] = 0;
282  }
283  ddSuppInteract(f,support);
284  ddClearLocal(f);
285  ddUpdateInteract(table,support);
286  }
287  f = Cudd_Regular(f->next);
288  }
289  }
290  }
291  ddClearGlobal(table);
292 
293  ABC_FREE(support);
294  return(1);
295 
296 } /* end of cuddInitInteract */
Definition: cudd.h:278
int size
Definition: cuddInt.h:361
#define Cudd_Regular(node)
Definition: cudd.h:397
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdSubtable * subtables
Definition: cuddInt.h:365
#define Cudd_IsComplement(node)
Definition: cudd.h:425
DdNode sentinel
Definition: cuddInt.h:344
DdNode * next
Definition: cudd.h:281
long * interact
Definition: cuddInt.h:394
static void ddClearLocal(DdNode *f)
Definition: cuddInteract.c:348
DdNode ** nodelist
Definition: cuddInt.h:327
int support
Definition: abcSaucy.c:64
static void ddSuppInteract(DdNode *f, int *support)
Definition: cuddInteract.c:317
static void ddClearGlobal(DdManager *table)
Definition: cuddInteract.c:411
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int slots
Definition: cuddInt.h:329
static void ddUpdateInteract(DdManager *table, int *support)
Definition: cuddInteract.c:377
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
#define LOGBPL
Definition: cuddInteract.c:93
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 759 of file cuddLinear.c.

761 {
762  int words;
763  int wordsPerRow;
764  int nvars;
765  int word;
766  int bit;
767  int i;
768  long *linear;
769 
770  nvars = table->size;
771  wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
772  words = wordsPerRow * nvars;
773  table->linear = linear = ABC_ALLOC(long,words);
774  if (linear == NULL) {
775  table->errorCode = CUDD_MEMORY_OUT;
776  return(0);
777  }
778  table->memused += words * sizeof(long);
779  table->linearSize = nvars;
780  for (i = 0; i < words; i++) linear[i] = 0;
781  for (i = 0; i < nvars; i++) {
782  word = wordsPerRow * i + (i >> LOGBPL);
783  bit = i & (BPL-1);
784  linear[word] = 1 << bit;
785  }
786  return(1);
787 
788 } /* end of cuddInitLinear */
#define BPL
Definition: cuddLinear.c:82
int size
Definition: cuddInt.h:361
#define LOGBPL
Definition: cuddLinear.c:83
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
long * linear
Definition: cuddInt.h:395
int linearSize
Definition: cuddInt.h:393
unsigned long memused
Definition: cuddInt.h:449
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
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 351 of file cuddTable.c.

356 {
357  DdManager *unique = ABC_ALLOC(DdManager,1);
358  int i, j;
359  DdNodePtr *nodelist;
360  DdNode *sentinel;
361  unsigned int slots;
362  int shift;
363 
364  if (unique == NULL) {
365  return(NULL);
366  }
367  sentinel = &(unique->sentinel);
368  sentinel->ref = 0;
369  sentinel->index = 0;
370  cuddT(sentinel) = NULL;
371  cuddE(sentinel) = NULL;
372  sentinel->next = NULL;
373  unique->epsilon = DD_EPSILON;
375  unique->maxGrowthAlt = 2.0 * DD_MAX_REORDER_GROWTH;
376  unique->reordCycle = 0; /* do not use alternate threshold */
377  unique->size = numVars;
378  unique->sizeZ = numVarsZ;
379  unique->maxSize = ddMax(DD_DEFAULT_RESIZE, numVars);
380  unique->maxSizeZ = ddMax(DD_DEFAULT_RESIZE, numVarsZ);
381 
382  /* Adjust the requested number of slots to a power of 2. */
383  slots = 8;
384  while (slots < numSlots) {
385  slots <<= 1;
386  }
387  unique->initSlots = slots;
388  shift = sizeof(int) * 8 - cuddComputeFloorLog2(slots);
389 
390  unique->slots = (numVars + numVarsZ + 1) * slots;
391  unique->keys = 0;
392  unique->maxLive = ~0; /* very large number */
393  unique->keysZ = 0;
394  unique->dead = 0;
395  unique->deadZ = 0;
396  unique->gcFrac = DD_GC_FRAC_HI;
397  unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots);
398  unique->looseUpTo = looseUpTo;
399  unique->gcEnabled = 1;
400  unique->allocated = 0;
401  unique->reclaimed = 0;
402  unique->subtables = ABC_ALLOC(DdSubtable,unique->maxSize);
403  if (unique->subtables == NULL) {
404  ABC_FREE(unique);
405  return(NULL);
406  }
407  unique->subtableZ = ABC_ALLOC(DdSubtable,unique->maxSizeZ);
408  if (unique->subtableZ == NULL) {
409  ABC_FREE(unique->subtables);
410  ABC_FREE(unique);
411  return(NULL);
412  }
413  unique->perm = ABC_ALLOC(int,unique->maxSize);
414  if (unique->perm == NULL) {
415  ABC_FREE(unique->subtables);
416  ABC_FREE(unique->subtableZ);
417  ABC_FREE(unique);
418  return(NULL);
419  }
420  unique->invperm = ABC_ALLOC(int,unique->maxSize);
421  if (unique->invperm == NULL) {
422  ABC_FREE(unique->subtables);
423  ABC_FREE(unique->subtableZ);
424  ABC_FREE(unique->perm);
425  ABC_FREE(unique);
426  return(NULL);
427  }
428  unique->permZ = ABC_ALLOC(int,unique->maxSizeZ);
429  if (unique->permZ == NULL) {
430  ABC_FREE(unique->subtables);
431  ABC_FREE(unique->subtableZ);
432  ABC_FREE(unique->perm);
433  ABC_FREE(unique->invperm);
434  ABC_FREE(unique);
435  return(NULL);
436  }
437  unique->invpermZ = ABC_ALLOC(int,unique->maxSizeZ);
438  if (unique->invpermZ == NULL) {
439  ABC_FREE(unique->subtables);
440  ABC_FREE(unique->subtableZ);
441  ABC_FREE(unique->perm);
442  ABC_FREE(unique->invperm);
443  ABC_FREE(unique->permZ);
444  ABC_FREE(unique);
445  return(NULL);
446  }
447  unique->map = NULL;
448  unique->stack = ABC_ALLOC(DdNodePtr,ddMax(unique->maxSize,unique->maxSizeZ)+1);
449  if (unique->stack == NULL) {
450  ABC_FREE(unique->subtables);
451  ABC_FREE(unique->subtableZ);
452  ABC_FREE(unique->perm);
453  ABC_FREE(unique->invperm);
454  ABC_FREE(unique->permZ);
455  ABC_FREE(unique->invpermZ);
456  ABC_FREE(unique);
457  return(NULL);
458  }
459  unique->stack[0] = NULL; /* to suppress harmless UMR */
460 
461 #ifndef DD_NO_DEATH_ROW
462  unique->deathRowDepth = 1 << cuddComputeFloorLog2(unique->looseUpTo >> 2);
463  unique->deathRow = ABC_ALLOC(DdNodePtr,unique->deathRowDepth);
464  if (unique->deathRow == NULL) {
465  ABC_FREE(unique->subtables);
466  ABC_FREE(unique->subtableZ);
467  ABC_FREE(unique->perm);
468  ABC_FREE(unique->invperm);
469  ABC_FREE(unique->permZ);
470  ABC_FREE(unique->invpermZ);
471  ABC_FREE(unique->stack);
472  ABC_FREE(unique);
473  return(NULL);
474  }
475  for (i = 0; i < unique->deathRowDepth; i++) {
476  unique->deathRow[i] = NULL;
477  }
478  unique->nextDead = 0;
479  unique->deadMask = unique->deathRowDepth - 1;
480 #endif
481 
482  for (i = 0; (unsigned) i < numVars; i++) {
483  unique->subtables[i].slots = slots;
484  unique->subtables[i].shift = shift;
485  unique->subtables[i].keys = 0;
486  unique->subtables[i].dead = 0;
487  unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
488  unique->subtables[i].bindVar = 0;
490  unique->subtables[i].pairIndex = 0;
491  unique->subtables[i].varHandled = 0;
493 
494  nodelist = unique->subtables[i].nodelist = ABC_ALLOC(DdNodePtr,slots);
495  if (nodelist == NULL) {
496  for (j = 0; j < i; j++) {
497  ABC_FREE(unique->subtables[j].nodelist);
498  }
499  ABC_FREE(unique->subtables);
500  ABC_FREE(unique->subtableZ);
501  ABC_FREE(unique->perm);
502  ABC_FREE(unique->invperm);
503  ABC_FREE(unique->permZ);
504  ABC_FREE(unique->invpermZ);
505  ABC_FREE(unique->stack);
506  ABC_FREE(unique);
507  return(NULL);
508  }
509  for (j = 0; (unsigned) j < slots; j++) {
510  nodelist[j] = sentinel;
511  }
512  unique->perm[i] = i;
513  unique->invperm[i] = i;
514  }
515  for (i = 0; (unsigned) i < numVarsZ; i++) {
516  unique->subtableZ[i].slots = slots;
517  unique->subtableZ[i].shift = shift;
518  unique->subtableZ[i].keys = 0;
519  unique->subtableZ[i].dead = 0;
520  unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
521  nodelist = unique->subtableZ[i].nodelist = ABC_ALLOC(DdNodePtr,slots);
522  if (nodelist == NULL) {
523  for (j = 0; (unsigned) j < numVars; j++) {
524  ABC_FREE(unique->subtables[j].nodelist);
525  }
526  ABC_FREE(unique->subtables);
527  for (j = 0; j < i; j++) {
528  ABC_FREE(unique->subtableZ[j].nodelist);
529  }
530  ABC_FREE(unique->subtableZ);
531  ABC_FREE(unique->perm);
532  ABC_FREE(unique->invperm);
533  ABC_FREE(unique->permZ);
534  ABC_FREE(unique->invpermZ);
535  ABC_FREE(unique->stack);
536  ABC_FREE(unique);
537  return(NULL);
538  }
539  for (j = 0; (unsigned) j < slots; j++) {
540  nodelist[j] = NULL;
541  }
542  unique->permZ[i] = i;
543  unique->invpermZ[i] = i;
544  }
545  unique->constants.slots = slots;
546  unique->constants.shift = shift;
547  unique->constants.keys = 0;
548  unique->constants.dead = 0;
549  unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
550  nodelist = unique->constants.nodelist = ABC_ALLOC(DdNodePtr,slots);
551  if (nodelist == NULL) {
552  for (j = 0; (unsigned) j < numVars; j++) {
553  ABC_FREE(unique->subtables[j].nodelist);
554  }
555  ABC_FREE(unique->subtables);
556  for (j = 0; (unsigned) j < numVarsZ; j++) {
557  ABC_FREE(unique->subtableZ[j].nodelist);
558  }
559  ABC_FREE(unique->subtableZ);
560  ABC_FREE(unique->perm);
561  ABC_FREE(unique->invperm);
562  ABC_FREE(unique->permZ);
563  ABC_FREE(unique->invpermZ);
564  ABC_FREE(unique->stack);
565  ABC_FREE(unique);
566  return(NULL);
567  }
568  for (j = 0; (unsigned) j < slots; j++) {
569  nodelist[j] = NULL;
570  }
571 
572  unique->memoryList = NULL;
573  unique->nextFree = NULL;
574 
575  unique->memused = sizeof(DdManager) + (unique->maxSize + unique->maxSizeZ)
576  * (sizeof(DdSubtable) + 2 * sizeof(int)) + (numVars + 1) *
577  slots * sizeof(DdNodePtr) +
578  (ddMax(unique->maxSize,unique->maxSizeZ) + 1) * sizeof(DdNodePtr);
579 #ifndef DD_NO_DEATH_ROW
580  unique->memused += unique->deathRowDepth * sizeof(DdNodePtr);
581 #endif
582 
583  /* Initialize fields concerned with automatic dynamic reordering */
584  unique->reorderings = 0;
585  unique->autoDyn = 0; /* initially disabled */
586  unique->autoDynZ = 0; /* initially disabled */
587  unique->realign = 0; /* initially disabled */
588  unique->realignZ = 0; /* initially disabled */
589  unique->reordered = 0;
590  unique->autoMethod = CUDD_REORDER_SIFT;
591  unique->autoMethodZ = CUDD_REORDER_SIFT;
592  unique->nextDyn = DD_FIRST_REORDER;
593  unique->countDead = ~0;
594  unique->siftMaxVar = DD_SIFT_MAX_VAR;
595  unique->siftMaxSwap = DD_SIFT_MAX_SWAPS;
596  unique->tree = NULL;
597  unique->treeZ = NULL;
598  unique->groupcheck = CUDD_GROUP_CHECK7;
599  unique->recomb = DD_DEFAULT_RECOMB;
600  unique->symmviolation = 0;
601  unique->arcviolation = 0;
602  unique->populationSize = 0;
603  unique->numberXovers = 0;
604  unique->linear = NULL;
605  unique->linearSize = 0;
606 
607  /* Initialize ZDD universe. */
608  unique->univ = (DdNodePtr *)NULL;
609 
610  /* Initialize auxiliary fields. */
611  unique->localCaches = NULL;
612  unique->preGCHook = NULL;
613  unique->postGCHook = NULL;
614  unique->preReorderingHook = NULL;
615  unique->postReorderingHook = NULL;
616  unique->out = stdout;
617  unique->err = stderr;
618  unique->errorCode = CUDD_NO_ERROR;
619 
620  /* Initialize statistical counters. */
621  unique->maxmemhard = ~ 0UL;
622  unique->garbageCollections = 0;
623  unique->GCTime = 0;
624  unique->reordTime = 0;
625 #ifdef DD_STATS
626  unique->nodesDropped = 0;
627  unique->nodesFreed = 0;
628 #endif
629  unique->peakLiveNodes = 0;
630 #ifdef DD_UNIQUE_PROFILE
631  unique->uniqueLookUps = 0;
632  unique->uniqueLinks = 0;
633 #endif
634 #ifdef DD_COUNT
635  unique->recursiveCalls = 0;
636  unique->swapSteps = 0;
637 #ifdef DD_STATS
638  unique->nextSample = 250000;
639 #endif
640 #endif
641 
642  return(unique);
643 
644 } /* end of cuddInitTable */
DdHalfWord ref
Definition: cudd.h:280
ABC_INT64_T allocated
Definition: cuddInt.h:382
Cudd_AggregationType groupcheck
Definition: cuddInt.h:426
unsigned int keys
Definition: cuddInt.h:330
long reordTime
Definition: cuddInt.h:454
Cudd_ReorderingType autoMethod
Definition: cuddInt.h:418
#define DD_SIFT_MAX_VAR
Definition: cuddInt.h:147
unsigned int peakLiveNodes
Definition: cuddInt.h:465
int maxSizeZ
Definition: cuddInt.h:364
int * map
Definition: cuddInt.h:391
Definition: cudd.h:278
unsigned int deadZ
Definition: cuddInt.h:372
int siftMaxSwap
Definition: cuddInt.h:412
DdHook * preReorderingHook
Definition: cuddInt.h:439
unsigned deadMask
Definition: cuddInt.h:404
int * invpermZ
Definition: cuddInt.h:389
int reordCycle
Definition: cuddInt.h:415
int size
Definition: cuddInt.h:361
double gcFrac
Definition: cuddInt.h:375
struct DdManager DdManager
Definition: cudd.h:293
unsigned int slots
Definition: cuddInt.h:368
double maxGrowthAlt
Definition: cuddInt.h:414
int realign
Definition: cuddInt.h:420
double maxGrowth
Definition: cuddInt.h:413
FILE * err
Definition: cuddInt.h:442
int garbageCollections
Definition: cuddInt.h:452
int populationSize
Definition: cuddInt.h:430
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
#define DD_FIRST_REORDER
Definition: cuddInt.h:151
Cudd_ReorderingType autoMethodZ
Definition: cuddInt.h:419
int bindVar
Definition: cuddInt.h:334
DdSubtable * subtables
Definition: cuddInt.h:365
int * permZ
Definition: cuddInt.h:387
DdNode * DdNodePtr
Definition: cuddInt.h:268
#define DD_EPSILON
Definition: cuddInt.h:109
MtrNode * tree
Definition: cuddInt.h:424
struct DdSubtable DdSubtable
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:126
#define DD_DEFAULT_RECOMB
Definition: cuddInt.h:149
DdNode ** deathRow
Definition: cuddInt.h:401
DdNode ** stack
Definition: cuddInt.h:380
unsigned int countDead
Definition: cuddInt.h:423
unsigned int initSlots
Definition: cuddInt.h:379
Cudd_VariableType varType
Definition: cuddInt.h:336
int reordered
Definition: cuddInt.h:409
unsigned int nextDyn
Definition: cuddInt.h:422
#define DD_GC_FRAC_HI
Definition: cuddInt.h:134
unsigned int dead
Definition: cuddInt.h:371
unsigned int maxLive
Definition: cuddInt.h:373
int recomb
Definition: cuddInt.h:427
DdNode sentinel
Definition: cuddInt.h:344
DdHook * postReorderingHook
Definition: cuddInt.h:440
unsigned int keys
Definition: cuddInt.h:369
unsigned int dead
Definition: cuddInt.h:332
FILE * out
Definition: cuddInt.h:441
#define DD_SIFT_MAX_SWAPS
Definition: cuddInt.h:148
int realignZ
Definition: cuddInt.h:421
DdNode * next
Definition: cudd.h:281
Cudd_LazyGroupType varToBeGrouped
Definition: cuddInt.h:339
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1079
int maxSize
Definition: cuddInt.h:363
unsigned int maxKeys
Definition: cuddInt.h:331
long * linear
Definition: cuddInt.h:395
long GCTime
Definition: cuddInt.h:453
int gcEnabled
Definition: cuddInt.h:376
#define ddMax(x, y)
Definition: cuddInt.h:832
int symmviolation
Definition: cuddInt.h:428
int numberXovers
Definition: cuddInt.h:431
DdNode ** nodelist
Definition: cuddInt.h:327
int linearSize
Definition: cuddInt.h:393
DdLocalCache * localCaches
Definition: cuddInt.h:432
int reorderings
Definition: cuddInt.h:410
#define cuddT(node)
Definition: cuddInt.h:636
int nextDead
Definition: cuddInt.h:403
int varHandled
Definition: cuddInt.h:338
DdNode ** memoryList
Definition: cuddInt.h:397
unsigned long memused
Definition: cuddInt.h:449
int siftMaxVar
Definition: cuddInt.h:411
int deathRowDepth
Definition: cuddInt.h:402
DdNode * nextFree
Definition: cuddInt.h:398
#define DD_DEFAULT_RESIZE
Definition: cuddInt.h:102
int sizeZ
Definition: cuddInt.h:362
DdHalfWord index
Definition: cudd.h:279
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int looseUpTo
Definition: cuddInt.h:377
unsigned int slots
Definition: cuddInt.h:329
unsigned long maxmemhard
Definition: cuddInt.h:451
DdHook * postGCHook
Definition: cuddInt.h:438
int pairIndex
Definition: cuddInt.h:337
#define DD_MAX_REORDER_GROWTH
Definition: cuddInt.h:150
CUDD_VALUE_TYPE epsilon
Definition: cuddInt.h:407
MtrNode * treeZ
Definition: cuddInt.h:425
int autoDynZ
Definition: cuddInt.h:417
#define cuddE(node)
Definition: cuddInt.h:652
int arcviolation
Definition: cuddInt.h:429
int * invperm
Definition: cuddInt.h:388
DdSubtable constants
Definition: cuddInt.h:367
int autoDyn
Definition: cuddInt.h:416
int shift
Definition: cuddInt.h:328
unsigned int keysZ
Definition: cuddInt.h:370
DdHook * preGCHook
Definition: cuddInt.h:437
int * perm
Definition: cuddInt.h:386
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
unsigned int minDead
Definition: cuddInt.h:374
double reclaimed
Definition: cuddInt.h:384
DdSubtable * subtableZ
Definition: cuddInt.h:366
DdNode ** univ
Definition: cuddInt.h:392
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 1795 of file cuddTable.c.

1799 {
1800  DdSubtable *newsubtables;
1801  DdNodePtr *newnodelist;
1802  DdNodePtr *newvars;
1803  DdNode *sentinel = &(unique->sentinel);
1804  int oldsize,newsize;
1805  int i,j,index,reorderSave;
1806  unsigned int numSlots = unique->initSlots;
1807  int *newperm, *newinvperm, *newmap=NULL;
1808  DdNode *one, *zero;
1809 
1810 #ifdef DD_DEBUG
1811  assert(n > 0 && level < unique->size);
1812 #endif
1813 
1814  oldsize = unique->size;
1815  /* Easy case: there is still room in the current table. */
1816  if (oldsize + n <= unique->maxSize) {
1817  /* Shift the tables at and below level. */
1818  for (i = oldsize - 1; i >= level; i--) {
1819  unique->subtables[i+n].slots = unique->subtables[i].slots;
1820  unique->subtables[i+n].shift = unique->subtables[i].shift;
1821  unique->subtables[i+n].keys = unique->subtables[i].keys;
1822  unique->subtables[i+n].maxKeys = unique->subtables[i].maxKeys;
1823  unique->subtables[i+n].dead = unique->subtables[i].dead;
1824  unique->subtables[i+n].nodelist = unique->subtables[i].nodelist;
1825  unique->subtables[i+n].bindVar = unique->subtables[i].bindVar;
1826  unique->subtables[i+n].varType = unique->subtables[i].varType;
1827  unique->subtables[i+n].pairIndex = unique->subtables[i].pairIndex;
1828  unique->subtables[i+n].varHandled = unique->subtables[i].varHandled;
1829  unique->subtables[i+n].varToBeGrouped =
1830  unique->subtables[i].varToBeGrouped;
1831 
1832  index = unique->invperm[i];
1833  unique->invperm[i+n] = index;
1834  unique->perm[index] += n;
1835  }
1836  /* Create new subtables. */
1837  for (i = 0; i < n; i++) {
1838  unique->subtables[level+i].slots = numSlots;
1839  unique->subtables[level+i].shift = sizeof(int) * 8 -
1840  cuddComputeFloorLog2(numSlots);
1841  unique->subtables[level+i].keys = 0;
1842  unique->subtables[level+i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY;
1843  unique->subtables[level+i].dead = 0;
1844  unique->subtables[level+i].bindVar = 0;
1845  unique->subtables[level+i].varType = CUDD_VAR_PRIMARY_INPUT;
1846  unique->subtables[level+i].pairIndex = 0;
1847  unique->subtables[level+i].varHandled = 0;
1848  unique->subtables[level+i].varToBeGrouped = CUDD_LAZY_NONE;
1849 
1850  unique->perm[oldsize+i] = level + i;
1851  unique->invperm[level+i] = oldsize + i;
1852  newnodelist = unique->subtables[level+i].nodelist =
1853  ABC_ALLOC(DdNodePtr, numSlots);
1854  if (newnodelist == NULL) {
1855  unique->errorCode = CUDD_MEMORY_OUT;
1856  return(0);
1857  }
1858  for (j = 0; (unsigned) j < numSlots; j++) {
1859  newnodelist[j] = sentinel;
1860  }
1861  }
1862  if (unique->map != NULL) {
1863  for (i = 0; i < n; i++) {
1864  unique->map[oldsize+i] = oldsize + i;
1865  }
1866  }
1867  } else {
1868  /* The current table is too small: we need to allocate a new,
1869  ** larger one; move all old subtables, and initialize the new
1870  ** subtables.
1871  */
1872  newsize = oldsize + n + DD_DEFAULT_RESIZE;
1873 #ifdef DD_VERBOSE
1874  (void) fprintf(unique->err,
1875  "Increasing the table size from %d to %d\n",
1876  unique->maxSize, newsize);
1877 #endif
1878  /* Allocate memory for new arrays (except nodelists). */
1879  newsubtables = ABC_ALLOC(DdSubtable,newsize);
1880  if (newsubtables == NULL) {
1881  unique->errorCode = CUDD_MEMORY_OUT;
1882  return(0);
1883  }
1884  newvars = ABC_ALLOC(DdNodePtr,newsize);
1885  if (newvars == NULL) {
1886  unique->errorCode = CUDD_MEMORY_OUT;
1887  ABC_FREE(newsubtables);
1888  return(0);
1889  }
1890  newperm = ABC_ALLOC(int,newsize);
1891  if (newperm == NULL) {
1892  unique->errorCode = CUDD_MEMORY_OUT;
1893  ABC_FREE(newsubtables);
1894  ABC_FREE(newvars);
1895  return(0);
1896  }
1897  newinvperm = ABC_ALLOC(int,newsize);
1898  if (newinvperm == NULL) {
1899  unique->errorCode = CUDD_MEMORY_OUT;
1900  ABC_FREE(newsubtables);
1901  ABC_FREE(newvars);
1902  ABC_FREE(newperm);
1903  return(0);
1904  }
1905  if (unique->map != NULL) {
1906  newmap = ABC_ALLOC(int,newsize);
1907  if (newmap == NULL) {
1908  unique->errorCode = CUDD_MEMORY_OUT;
1909  ABC_FREE(newsubtables);
1910  ABC_FREE(newvars);
1911  ABC_FREE(newperm);
1912  ABC_FREE(newinvperm);
1913  return(0);
1914  }
1915  unique->memused += (newsize - unique->maxSize) * sizeof(int);
1916  }
1917  unique->memused += (newsize - unique->maxSize) * ((numSlots+1) *
1918  sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable));
1919  /* Copy levels before insertion points from old tables. */
1920  for (i = 0; i < level; i++) {
1921  newsubtables[i].slots = unique->subtables[i].slots;
1922  newsubtables[i].shift = unique->subtables[i].shift;
1923  newsubtables[i].keys = unique->subtables[i].keys;
1924  newsubtables[i].maxKeys = unique->subtables[i].maxKeys;
1925  newsubtables[i].dead = unique->subtables[i].dead;
1926  newsubtables[i].nodelist = unique->subtables[i].nodelist;
1927  newsubtables[i].bindVar = unique->subtables[i].bindVar;
1928  newsubtables[i].varType = unique->subtables[i].varType;
1929  newsubtables[i].pairIndex = unique->subtables[i].pairIndex;
1930  newsubtables[i].varHandled = unique->subtables[i].varHandled;
1931  newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped;
1932 
1933  newvars[i] = unique->vars[i];
1934  newperm[i] = unique->perm[i];
1935  newinvperm[i] = unique->invperm[i];
1936  }
1937  /* Finish initializing permutation for new table to old one. */
1938  for (i = level; i < oldsize; i++) {
1939  newperm[i] = unique->perm[i];
1940  }
1941  /* Initialize new levels. */
1942  for (i = level; i < level + n; i++) {
1943  newsubtables[i].slots = numSlots;
1944  newsubtables[i].shift = sizeof(int) * 8 -
1945  cuddComputeFloorLog2(numSlots);
1946  newsubtables[i].keys = 0;
1947  newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY;
1948  newsubtables[i].dead = 0;
1949  newsubtables[i].bindVar = 0;
1950  newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT;
1951  newsubtables[i].pairIndex = 0;
1952  newsubtables[i].varHandled = 0;
1953  newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE;
1954 
1955  newperm[oldsize + i - level] = i;
1956  newinvperm[i] = oldsize + i - level;
1957  newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots);
1958  if (newnodelist == NULL) {
1959  /* We are going to leak some memory. We should clean up. */
1960  unique->errorCode = CUDD_MEMORY_OUT;
1961  return(0);
1962  }
1963  for (j = 0; (unsigned) j < numSlots; j++) {
1964  newnodelist[j] = sentinel;
1965  }
1966  }
1967  /* Copy the old tables for levels past the insertion point. */
1968  for (i = level; i < oldsize; i++) {
1969  newsubtables[i+n].slots = unique->subtables[i].slots;
1970  newsubtables[i+n].shift = unique->subtables[i].shift;
1971  newsubtables[i+n].keys = unique->subtables[i].keys;
1972  newsubtables[i+n].maxKeys = unique->subtables[i].maxKeys;
1973  newsubtables[i+n].dead = unique->subtables[i].dead;
1974  newsubtables[i+n].nodelist = unique->subtables[i].nodelist;
1975  newsubtables[i+n].bindVar = unique->subtables[i].bindVar;
1976  newsubtables[i+n].varType = unique->subtables[i].varType;
1977  newsubtables[i+n].pairIndex = unique->subtables[i].pairIndex;
1978  newsubtables[i+n].varHandled = unique->subtables[i].varHandled;
1979  newsubtables[i+n].varToBeGrouped =
1980  unique->subtables[i].varToBeGrouped;
1981 
1982  newvars[i] = unique->vars[i];
1983  index = unique->invperm[i];
1984  newinvperm[i+n] = index;
1985  newperm[index] += n;
1986  }
1987  /* Update the map. */
1988  if (unique->map != NULL) {
1989  for (i = 0; i < oldsize; i++) {
1990  newmap[i] = unique->map[i];
1991  }
1992  for (i = oldsize; i < oldsize + n; i++) {
1993  newmap[i] = i;
1994  }
1995  ABC_FREE(unique->map);
1996  unique->map = newmap;
1997  }
1998  /* Install the new tables and free the old ones. */
1999  ABC_FREE(unique->subtables);
2000  unique->subtables = newsubtables;
2001  unique->maxSize = newsize;
2002  ABC_FREE(unique->vars);
2003  unique->vars = newvars;
2004  ABC_FREE(unique->perm);
2005  unique->perm = newperm;
2006  ABC_FREE(unique->invperm);
2007  unique->invperm = newinvperm;
2008  /* Update the stack for iterative procedures. */
2009  if (newsize > unique->maxSizeZ) {
2010  ABC_FREE(unique->stack);
2011  unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1);
2012  if (unique->stack == NULL) {
2013  unique->errorCode = CUDD_MEMORY_OUT;
2014  return(0);
2015  }
2016  unique->stack[0] = NULL; /* to suppress harmless UMR */
2017  unique->memused +=
2018  (newsize - ddMax(unique->maxSize,unique->maxSizeZ))
2019  * sizeof(DdNode *);
2020  }
2021  }
2022  /* Update manager parameters to account for the new subtables. */
2023  unique->slots += n * numSlots;
2024  ddFixLimits(unique);
2025  unique->size += n;
2026 
2027  /* Now that the table is in a coherent state, create the new
2028  ** projection functions. We need to temporarily disable reordering,
2029  ** because we cannot reorder without projection functions in place.
2030  **/
2031  one = unique->one;
2032  zero = Cudd_Not(one);
2033 
2034  reorderSave = unique->autoDyn;
2035  unique->autoDyn = 0;
2036  for (i = oldsize; i < oldsize + n; i++) {
2037  unique->vars[i] = cuddUniqueInter(unique,i,one,zero);
2038  if (unique->vars[i] == NULL) {
2039  unique->autoDyn = reorderSave;
2040  /* Shift everything back so table remains coherent. */
2041  for (j = oldsize; j < i; j++) {
2042  Cudd_IterDerefBdd(unique,unique->vars[j]);
2043  cuddDeallocNode(unique,unique->vars[j]);
2044  unique->vars[j] = NULL;
2045  }
2046  for (j = level; j < oldsize; j++) {
2047  unique->subtables[j].slots = unique->subtables[j+n].slots;
2048  unique->subtables[j].slots = unique->subtables[j+n].slots;
2049  unique->subtables[j].shift = unique->subtables[j+n].shift;
2050  unique->subtables[j].keys = unique->subtables[j+n].keys;
2051  unique->subtables[j].maxKeys =
2052  unique->subtables[j+n].maxKeys;
2053  unique->subtables[j].dead = unique->subtables[j+n].dead;
2054  ABC_FREE(unique->subtables[j].nodelist);
2055  unique->subtables[j].nodelist =
2056  unique->subtables[j+n].nodelist;
2057  unique->subtables[j+n].nodelist = NULL;
2058  unique->subtables[j].bindVar =
2059  unique->subtables[j+n].bindVar;
2060  unique->subtables[j].varType =
2061  unique->subtables[j+n].varType;
2062  unique->subtables[j].pairIndex =
2063  unique->subtables[j+n].pairIndex;
2064  unique->subtables[j].varHandled =
2065  unique->subtables[j+n].varHandled;
2066  unique->subtables[j].varToBeGrouped =
2067  unique->subtables[j+n].varToBeGrouped;
2068  index = unique->invperm[j+n];
2069  unique->invperm[j] = index;
2070  unique->perm[index] -= n;
2071  }
2072  unique->size = oldsize;
2073  unique->slots -= n * numSlots;
2074  ddFixLimits(unique);
2075  (void) Cudd_DebugCheck(unique);
2076  return(0);
2077  }
2078  cuddRef(unique->vars[i]);
2079  }
2080  if (unique->tree != NULL) {
2081  unique->tree->size += n;
2082  unique->tree->index = unique->invperm[0];
2083  ddPatchTree(unique,unique->tree);
2084  }
2085  unique->autoDyn = reorderSave;
2086 
2087  return(1);
2088 
2089 } /* end of cuddInsertSubtables */
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
#define cuddRef(n)
Definition: cuddInt.h:584
unsigned int keys
Definition: cuddInt.h:330
int maxSizeZ
Definition: cuddInt.h:364
int * map
Definition: cuddInt.h:391
Definition: cudd.h:278
static void ddPatchTree(DdManager *dd, MtrNode *treenode)
Definition: cuddTable.c:3080
#define Cudd_Not(node)
Definition: cudd.h:367
MtrHalfWord size
Definition: mtr.h:134
int size
Definition: cuddInt.h:361
unsigned int slots
Definition: cuddInt.h:368
FILE * err
Definition: cuddInt.h:442
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int bindVar
Definition: cuddInt.h:334
DdSubtable * subtables
Definition: cuddInt.h:365
MtrNode * tree
Definition: cuddInt.h:424
struct DdSubtable DdSubtable
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:126
DdNode ** stack
Definition: cuddInt.h:380
unsigned int initSlots
Definition: cuddInt.h:379
Cudd_VariableType varType
Definition: cuddInt.h:336
DdNode sentinel
Definition: cuddInt.h:344
MtrHalfWord index
Definition: mtr.h:135
unsigned int dead
Definition: cuddInt.h:332
static DdNode * one
Definition: cuddDecomp.c:112
Cudd_LazyGroupType varToBeGrouped
Definition: cuddInt.h:339
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1079
int maxSize
Definition: cuddInt.h:363
unsigned int maxKeys
Definition: cuddInt.h:331
#define ddMax(x, y)
Definition: cuddInt.h:832
DdNode ** nodelist
Definition: cuddInt.h:327
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:142
static int size
Definition: cuddSign.c:86
int varHandled
Definition: cuddInt.h:338
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:547
unsigned long memused
Definition: cuddInt.h:449
#define DD_DEFAULT_RESIZE
Definition: cuddInt.h:102
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int slots
Definition: cuddInt.h:329
DdNode ** vars
Definition: cuddInt.h:390
int pairIndex
Definition: cuddInt.h:337
DdNode * one
Definition: cuddInt.h:345
static DD_INLINE void ddFixLimits(DdManager *unique)
Definition: cuddTable.c:2805
#define assert(ex)
Definition: util_old.h:213
int * invperm
Definition: cuddInt.h:388
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
int autoDyn
Definition: cuddInt.h:416
int shift
Definition: cuddInt.h:328
int * perm
Definition: cuddInt.h:386
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
static DdNode * zero
Definition: cuddApa.c:100
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 762 of file cuddRef.c.

765 {
766 #ifndef DD_NO_DEATH_ROW
767  int i;
768 
769  for (i = 0; i < dd->deathRowDepth; i++) {
770  if (f == dd->deathRow[i]) {
771  return(i);
772  }
773  }
774 #endif
775 
776  return(-1);
777 
778 } /* end of cuddIsInDeathRow */
DdNode ** deathRow
Definition: cuddInt.h:401
int deathRowDepth
Definition: cuddInt.h:402
void cuddLevelQueueDequeue ( DdLevelQueue queue,
int  level 
)

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

Synopsis [Remove an item from the front of a level queue.]

Description [Remove an item from the front of a level queue.]

SideEffects [None]

SeeAlso [cuddLevelQueueEnqueue]

Definition at line 354 of file cuddLevelQ.c.

357 {
358  DdQueueItem *item = (DdQueueItem *) queue->first;
359 
360  /* Delete from the hash table. */
361  hashDelete(queue,item);
362 
363  /* Since we delete from the front, if this is the last item for
364  ** its level, there are no other items for the same level. */
365  if (queue->last[level] == item)
366  queue->last[level] = NULL;
367 
368  queue->first = item->next;
369  /* Put item on the free list. */
370  item->next = queue->freelist;
371  queue->freelist = item;
372  /* Update stats. */
373  queue->size--;
374  return;
375 
376 } /* end of cuddLevelQueueDequeue */
static void hashDelete(DdLevelQueue *queue, DdQueueItem *item)
Definition: cuddLevelQ.c:467
struct DdQueueItem * next
Definition: cuddInt.h:502
void * first
Definition: cuddInt.h:509
DdQueueItem * freelist
Definition: cuddInt.h:511
DdQueueItem ** last
Definition: cuddInt.h:510
void* cuddLevelQueueEnqueue ( DdLevelQueue queue,
void *  key,
int  level 
)

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

Synopsis [Inserts a new key in a level queue.]

Description [Inserts a new key in a level queue. A new entry is created in the queue only if the node is not already enqueued. Returns a pointer to the queue item if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddLevelQueueInit cuddLevelQueueDequeue]

Definition at line 282 of file cuddLevelQ.c.

286 {
287  int plevel;
288  DdQueueItem *item;
289 
290 #ifdef DD_DEBUG
291  assert(level < queue->levels);
292 #endif
293  /* Check whether entry for this node exists. */
294  item = hashLookup(queue,key);
295  if (item != NULL) return(item);
296 
297  /* Get a free item from either the free list or the memory manager. */
298  if (queue->freelist == NULL) {
299  item = (DdQueueItem *) ABC_ALLOC(char, queue->itemsize);
300  if (item == NULL)
301  return(NULL);
302  } else {
303  item = queue->freelist;
304  queue->freelist = item->next;
305  }
306  /* Initialize. */
307  memset(item, 0, queue->itemsize);
308  item->key = key;
309  /* Update stats. */
310  queue->size++;
311 
312  if (queue->last[level]) {
313  /* There are already items for this level in the queue. */
314  item->next = queue->last[level]->next;
315  queue->last[level]->next = item;
316  } else {
317  /* There are no items at the current level. Look for the first
318  ** non-empty level preceeding this one. */
319  plevel = level;
320  while (plevel != 0 && queue->last[plevel] == NULL)
321  plevel--;
322  if (queue->last[plevel] == NULL) {
323  /* No element precedes this one in the queue. */
324  item->next = (DdQueueItem *) queue->first;
325  queue->first = item;
326  } else {
327  item->next = queue->last[plevel]->next;
328  queue->last[plevel]->next = item;
329  }
330  }
331  queue->last[level] = item;
332 
333  /* Insert entry for the key in the hash table. */
334  if (hashInsert(queue,item) == 0) {
335  return(NULL);
336  }
337  return(item);
338 
339 } /* end of cuddLevelQueueEnqueue */
char * memset()
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
struct DdQueueItem * next
Definition: cuddInt.h:502
static int hashInsert(DdLevelQueue *queue, DdQueueItem *item)
Definition: cuddLevelQ.c:433
void * first
Definition: cuddInt.h:509
static DdQueueItem * hashLookup(DdLevelQueue *queue, void *key)
Definition: cuddLevelQ.c:398
int levels
Definition: abcSaucy.c:60
enum keys key
DdQueueItem * freelist
Definition: cuddInt.h:511
#define assert(ex)
Definition: util_old.h:213
DdQueueItem ** last
Definition: cuddInt.h:510
void * key
Definition: cuddInt.h:504
int itemsize
Definition: cuddInt.h:514
DdLevelQueue* cuddLevelQueueInit ( int  levels,
int  itemSize,
int  numBuckets 
)

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

Synopsis [Initializes a level queue.]

Description [Initializes a level queue. A level queue is a queue where inserts are based on the levels of the nodes. Within each level the policy is FIFO. Level queues are useful in traversing a BDD top-down. Queue items are kept in a free list when dequeued for efficiency. Returns a pointer to the new queue if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddLevelQueueQuit cuddLevelQueueEnqueue cuddLevelQueueDequeue]

Definition at line 169 of file cuddLevelQ.c.

173 {
174  DdLevelQueue *queue;
175  int logSize;
176 
177  queue = ABC_ALLOC(DdLevelQueue,1);
178  if (queue == NULL)
179  return(NULL);
180 #ifdef __osf__
181 #pragma pointer_size save
182 #pragma pointer_size short
183 #endif
184  /* Keep pointers to the insertion points for all levels. */
185  queue->last = ABC_ALLOC(DdQueueItem *, levels);
186 #ifdef __osf__
187 #pragma pointer_size restore
188 #endif
189  if (queue->last == NULL) {
190  ABC_FREE(queue);
191  return(NULL);
192  }
193  /* Use a hash table to test for uniqueness. */
194  if (numBuckets < 2) numBuckets = 2;
195  logSize = cuddComputeFloorLog2(numBuckets);
196  queue->numBuckets = 1 << logSize;
197  queue->shift = sizeof(int) * 8 - logSize;
198 #ifdef __osf__
199 #pragma pointer_size save
200 #pragma pointer_size short
201 #endif
202  queue->buckets = ABC_ALLOC(DdQueueItem *, queue->numBuckets);
203 #ifdef __osf__
204 #pragma pointer_size restore
205 #endif
206  if (queue->buckets == NULL) {
207  ABC_FREE(queue->last);
208  ABC_FREE(queue);
209  return(NULL);
210  }
211 #ifdef __osf__
212 #pragma pointer_size save
213 #pragma pointer_size short
214 #endif
215  memset(queue->last, 0, levels * sizeof(DdQueueItem *));
216  memset(queue->buckets, 0, queue->numBuckets * sizeof(DdQueueItem *));
217 #ifdef __osf__
218 #pragma pointer_size restore
219 #endif
220  queue->first = NULL;
221  queue->freelist = NULL;
222  queue->levels = levels;
223  queue->itemsize = itemSize;
224  queue->size = 0;
225  queue->maxsize = queue->numBuckets * DD_MAX_SUBTABLE_DENSITY;
226  return(queue);
227 
228 } /* end of cuddLevelQueueInit */
char * memset()
int maxsize
Definition: cuddInt.h:516
int levels
Definition: cuddInt.h:513
int numBuckets
Definition: cuddInt.h:517
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:126
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1079
void * first
Definition: cuddInt.h:509
int levels
Definition: abcSaucy.c:60
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdQueueItem * freelist
Definition: cuddInt.h:511
DdQueueItem ** buckets
Definition: cuddInt.h:512
DdQueueItem ** last
Definition: cuddInt.h:510
int itemsize
Definition: cuddInt.h:514
void cuddLevelQueueQuit ( DdLevelQueue queue)

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

Synopsis [Shuts down a level queue.]

Description [Shuts down a level queue and releases all the associated memory.]

SideEffects [None]

SeeAlso [cuddLevelQueueInit]

Definition at line 244 of file cuddLevelQ.c.

246 {
247  DdQueueItem *item;
248 
249  while (queue->freelist != NULL) {
250  item = queue->freelist;
251  queue->freelist = item->next;
252  ABC_FREE(item);
253  }
254  while (queue->first != NULL) {
255  item = (DdQueueItem *) queue->first;
256  queue->first = item->next;
257  ABC_FREE(item);
258  }
259  ABC_FREE(queue->buckets);
260  ABC_FREE(queue->last);
261  ABC_FREE(queue);
262  return;
263 
264 } /* end of cuddLevelQueueQuit */
struct DdQueueItem * next
Definition: cuddInt.h:502
void * first
Definition: cuddInt.h:509
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdQueueItem * freelist
Definition: cuddInt.h:511
DdQueueItem ** buckets
Definition: cuddInt.h:512
DdQueueItem ** last
Definition: cuddInt.h:510
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 240 of file cuddLinear.c.

244 {
245  int i;
246  int *var;
247  int size;
248  int x;
249  int result;
250 #ifdef DD_STATS
251  int previousSize;
252 #endif
253 
254 #ifdef DD_STATS
255  ddTotalNumberLinearTr = 0;
256 #endif
257 
258  size = table->size;
259 
260  var = NULL;
261  entry = NULL;
262  if (table->linear == NULL) {
263  result = cuddInitLinear(table);
264  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
265 #if 0
266  (void) fprintf(table->out,"\n");
267  result = Cudd_PrintLinear(table);
268  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
269 #endif
270  } else if (table->size != table->linearSize) {
271  result = cuddResizeLinear(table);
272  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
273 #if 0
274  (void) fprintf(table->out,"\n");
275  result = Cudd_PrintLinear(table);
276  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
277 #endif
278  }
279 
280  /* Find order in which to sift variables. */
281  entry = ABC_ALLOC(int,size);
282  if (entry == NULL) {
283  table->errorCode = CUDD_MEMORY_OUT;
284  goto cuddLinearAndSiftingOutOfMem;
285  }
286  var = ABC_ALLOC(int,size);
287  if (var == NULL) {
288  table->errorCode = CUDD_MEMORY_OUT;
289  goto cuddLinearAndSiftingOutOfMem;
290  }
291 
292  for (i = 0; i < size; i++) {
293  x = table->perm[i];
294  entry[i] = table->subtables[x].keys;
295  var[i] = i;
296  }
297 
298  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddLinearUniqueCompare);
299 
300  /* Now sift. */
301  for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
302  x = table->perm[var[i]];
303  if (x < lower || x > upper) continue;
304 #ifdef DD_STATS
305  previousSize = table->keys - table->isolated;
306 #endif
307  result = ddLinearAndSiftingAux(table,x,lower,upper);
308  if (!result) goto cuddLinearAndSiftingOutOfMem;
309 #ifdef DD_STATS
310  if (table->keys < (unsigned) previousSize + table->isolated) {
311  (void) fprintf(table->out,"-");
312  } else if (table->keys > (unsigned) previousSize + table->isolated) {
313  (void) fprintf(table->out,"+"); /* should never happen */
314  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]);
315  } else {
316  (void) fprintf(table->out,"=");
317  }
318  fflush(table->out);
319 #endif
320 #ifdef DD_DEBUG
321  (void) Cudd_DebugCheck(table);
322 #endif
323  }
324 
325  ABC_FREE(var);
326  ABC_FREE(entry);
327 
328 #ifdef DD_STATS
329  (void) fprintf(table->out,"\n#:L_LINSIFT %8d: linear trans.",
330  ddTotalNumberLinearTr);
331 #endif
332 
333  return(1);
334 
335 cuddLinearAndSiftingOutOfMem:
336 
337  if (entry != NULL) ABC_FREE(entry);
338  if (var != NULL) ABC_FREE(var);
339 
340  return(0);
341 
342 } /* end of cuddLinearAndSifting */
unsigned int keys
Definition: cuddInt.h:330
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:326
int size
Definition: cuddInt.h:361
int var(Lit p)
Definition: SolverTypes.h:62
int cuddInitLinear(DdManager *table)
Definition: cuddLinear.c:759
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdSubtable * subtables
Definition: cuddInt.h:365
int cuddResizeLinear(DdManager *table)
Definition: cuddLinear.c:804
int Cudd_PrintLinear(DdManager *table)
Definition: cuddLinear.c:153
unsigned int keys
Definition: cuddInt.h:369
FILE * out
Definition: cuddInt.h:441
long * linear
Definition: cuddInt.h:395
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:142
int linearSize
Definition: cuddInt.h:393
static int size
Definition: cuddSign.c:86
#define ddMin(x, y)
Definition: cuddInt.h:818
int siftMaxVar
Definition: cuddInt.h:411
static int * entry
Definition: cuddLinear.c:102
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int ddLinearUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddLinear.c:872
static int result
Definition: cuddGenetic.c:125
int isolated
Definition: cuddInt.h:385
int * perm
Definition: cuddInt.h:386
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
static int ddLinearAndSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddLinear.c:900
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 364 of file cuddLinear.c.

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

406 {
407  DdLocalCache *cache = manager->localCaches;
408 
409  while (cache != NULL) {
410  memset(cache->item, 0, cache->slots * cache->itemsize);
411  cache = cache->next;
412  }
413  return;
414 
415 } /* end of cuddLocalCacheClearAll */
char * memset()
DdLocalCacheItem * item
Definition: cuddInt.h:281
struct DdLocalCache * next
Definition: cuddInt.h:291
unsigned int itemsize
Definition: cuddInt.h:282
unsigned int slots
Definition: cuddInt.h:284
DdLocalCache * localCaches
Definition: cuddInt.h:432
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 352 of file cuddLCache.c.

354 {
355  DdLocalCache *cache = manager->localCaches;
356  unsigned int keysize;
357  unsigned int itemsize;
358  unsigned int slots;
359  DdLocalCacheItem *item;
360  DdNodePtr *key;
361  unsigned int i, j;
362 
363  while (cache != NULL) {
364  keysize = cache->keysize;
365  itemsize = cache->itemsize;
366  slots = cache->slots;
367  item = cache->item;
368  for (i = 0; i < slots; i++) {
369  if (item->value != NULL) {
370  if (Cudd_Regular(item->value)->ref == 0) {
371  item->value = NULL;
372  } else {
373  key = item->key;
374  for (j = 0; j < keysize; j++) {
375  if (Cudd_Regular(key[j])->ref == 0) {
376  item->value = NULL;
377  break;
378  }
379  }
380  }
381  }
382  item = (DdLocalCacheItem *) ((char *) item + itemsize);
383  }
384  cache = cache->next;
385  }
386  return;
387 
388 } /* end of cuddLocalCacheClearDead */
Definition: cudd.h:278
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * value
Definition: cuddInt.h:272
unsigned int keysize
Definition: cuddInt.h:283
DdLocalCacheItem * item
Definition: cuddInt.h:281
struct DdLocalCache * next
Definition: cuddInt.h:291
unsigned int itemsize
Definition: cuddInt.h:282
unsigned int slots
Definition: cuddInt.h:284
DdLocalCache * localCaches
Definition: cuddInt.h:432
DdNode * key[1]
Definition: cuddInt.h:276
enum keys key
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 183 of file cuddLCache.c.

188 {
189  DdLocalCache *cache;
190  int logSize;
191 
192  cache = ABC_ALLOC(DdLocalCache,1);
193  if (cache == NULL) {
194  manager->errorCode = CUDD_MEMORY_OUT;
195  return(NULL);
196  }
197  cache->manager = manager;
198  cache->keysize = keySize;
199  cache->itemsize = (keySize + 1) * sizeof(DdNode *);
200 #ifdef DD_CACHE_PROFILE
201  cache->itemsize += sizeof(ptrint);
202 #endif
203  logSize = cuddComputeFloorLog2(ddMax(cacheSize,manager->slots/2));
204  cacheSize = 1 << logSize;
205  cache->item = (DdLocalCacheItem *)
206  ABC_ALLOC(char, cacheSize * cache->itemsize);
207  if (cache->item == NULL) {
208  manager->errorCode = CUDD_MEMORY_OUT;
209  ABC_FREE(cache);
210  return(NULL);
211  }
212  cache->slots = cacheSize;
213  cache->shift = sizeof(int) * 8 - logSize;
214  cache->maxslots = ddMin(maxCacheSize,manager->slots);
215  cache->minHit = manager->minHit;
216  /* Initialize to avoid division by 0 and immediate resizing. */
217  cache->lookUps = (double) (int) (cacheSize * cache->minHit + 1);
218  cache->hits = 0;
219  manager->memused += cacheSize * cache->itemsize + sizeof(DdLocalCache);
220 
221  /* Initialize the cache. */
222  memset(cache->item, 0, cacheSize * cache->itemsize);
223 
224  /* Add to manager's list of local caches for GC. */
226 
227  return(cache);
228 
229 } /* end of cuddLocalCacheInit */
char * memset()
Definition: cudd.h:278
unsigned int slots
Definition: cuddInt.h:368
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
double minHit
Definition: cuddInt.h:287
unsigned int keysize
Definition: cuddInt.h:283
DdLocalCacheItem * item
Definition: cuddInt.h:281
unsigned int maxslots
Definition: cuddInt.h:289
unsigned int itemsize
Definition: cuddInt.h:282
ABC_PTRINT_T ptrint
Definition: cuddInt.h:260
double hits
Definition: cuddInt.h:288
double lookUps
Definition: cuddInt.h:286
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1079
unsigned int slots
Definition: cuddInt.h:284
#define ddMax(x, y)
Definition: cuddInt.h:832
#define ddMin(x, y)
Definition: cuddInt.h:818
unsigned long memused
Definition: cuddInt.h:449
#define ABC_FREE(obj)
Definition: abc_global.h:232
double minHit
Definition: cuddInt.h:357
struct DdLocalCache DdLocalCache
DdManager * manager
Definition: cuddInt.h:290
static void cuddLocalCacheAddToList(DdLocalCache *cache)
Definition: cuddLCache.c:1211
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
void cuddLocalCacheInsert ( DdLocalCache cache,
DdNodePtr key,
DdNode value 
)

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

Synopsis [Inserts a result in a local cache.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 272 of file cuddLCache.c.

276 {
277  unsigned int posn;
279 
280  posn = ddLCHash(key,cache->keysize,cache->shift);
281  entry = (DdLocalCacheItem *) ((char *) cache->item +
282  posn * cache->itemsize);
283  memcpy(entry->key,key,cache->keysize * sizeof(DdNode *));
284  entry->value = value;
285 #ifdef DD_CACHE_PROFILE
286  entry->count++;
287 #endif
288 
289 } /* end of cuddLocalCacheInsert */
Definition: cudd.h:278
char * memcpy()
DdNode * value
Definition: cuddInt.h:272
unsigned int keysize
Definition: cuddInt.h:283
DdLocalCacheItem * item
Definition: cuddInt.h:281
static int * entry
Definition: cuddGroup.c:122
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddLCache.c:1182
unsigned int itemsize
Definition: cuddInt.h:282
DdNode * key[1]
Definition: cuddInt.h:276
int value
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 305 of file cuddLCache.c.

308 {
309  unsigned int posn;
311  DdNode *value;
312 
313  cache->lookUps++;
314  posn = ddLCHash(key,cache->keysize,cache->shift);
315  entry = (DdLocalCacheItem *) ((char *) cache->item +
316  posn * cache->itemsize);
317  if (entry->value != NULL &&
318  memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) {
319  cache->hits++;
320  value = Cudd_Regular(entry->value);
321  if (value->ref == 0) {
322  cuddReclaim(cache->manager,value);
323  }
324  return(entry->value);
325  }
326 
327  /* Cache miss: decide whether to resize */
328 
329  if (cache->slots < cache->maxslots &&
330  cache->hits > cache->lookUps * cache->minHit) {
331  cuddLocalCacheResize(cache);
332  }
333 
334  return(NULL);
335 
336 } /* end of cuddLocalCacheLookup */
DdHalfWord ref
Definition: cudd.h:280
Definition: cudd.h:278
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddRef.c:584
DdNode * value
Definition: cuddInt.h:272
double minHit
Definition: cuddInt.h:287
unsigned int keysize
Definition: cuddInt.h:283
DdLocalCacheItem * item
Definition: cuddInt.h:281
static int * entry
Definition: cuddGroup.c:122
unsigned int maxslots
Definition: cuddInt.h:289
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddLCache.c:1182
unsigned int itemsize
Definition: cuddInt.h:282
double hits
Definition: cuddInt.h:288
double lookUps
Definition: cuddInt.h:286
unsigned int slots
Definition: cuddInt.h:284
int memcmp()
static void cuddLocalCacheResize(DdLocalCache *cache)
Definition: cuddLCache.c:1100
DdNode * key[1]
Definition: cuddInt.h:276
int value
DdManager * manager
Definition: cuddInt.h:290
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 246 of file cuddLCache.c.

248 {
249  cache->manager->memused -=
250  cache->slots * cache->itemsize + sizeof(DdLocalCache);
252  ABC_FREE(cache->item);
253  ABC_FREE(cache);
254 
255  return;
256 
257 } /* end of cuddLocalCacheQuit */
static void cuddLocalCacheRemoveFromList(DdLocalCache *cache)
Definition: cuddLCache.c:1235
DdLocalCacheItem * item
Definition: cuddInt.h:281
unsigned int itemsize
Definition: cuddInt.h:282
unsigned int slots
Definition: cuddInt.h:284
unsigned long memused
Definition: cuddInt.h:449
#define ABC_FREE(obj)
Definition: abc_global.h:232
struct DdLocalCache DdLocalCache
DdManager * manager
Definition: cuddInt.h:290
DdNode* cuddMakeBddFromZddCover ( DdManager dd,
DdNode node 
)

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

Synopsis [Converts a ZDD cover to a BDD graph.]

Description [Converts a ZDD cover to a BDD graph. If successful, it returns a BDD node, otherwise it returns NULL. It is a recursive algorithm as the following. First computes 3 cofactors of a ZDD cover; f1, f0 and fd. Second, compute BDDs(b1, b0 and bd) of f1, f0 and fd. Third, compute T=b1+bd and E=b0+bd. Fourth, compute 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 one of T or one of E, cuddUniqueInterIVO is called, here IVO stands for independent variable ordering.]

SideEffects []

SeeAlso [Cudd_MakeBddFromZddCover]

Definition at line 800 of file cuddZddIsop.c.

803 {
804  DdNode *neW;
805  int v;
806  DdNode *f1, *f0, *fd;
807  DdNode *b1, *b0, *bd;
808  DdNode *T, *E;
809 
810  statLine(dd);
811  if (node == dd->one)
812  return(dd->one);
813  if (node == dd->zero)
814  return(Cudd_Not(dd->one));
815 
816  /* Check cache */
817  neW = cuddCacheLookup1(dd, cuddMakeBddFromZddCover, node);
818  if (neW)
819  return(neW);
820 
821  v = Cudd_Regular(node)->index; /* either yi or zi */
822  if (cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd)) return(NULL);
823  Cudd_Ref(f1);
824  Cudd_Ref(f0);
825  Cudd_Ref(fd);
826 
827  b1 = cuddMakeBddFromZddCover(dd, f1);
828  if (!b1) {
829  Cudd_RecursiveDerefZdd(dd, f1);
830  Cudd_RecursiveDerefZdd(dd, f0);
831  Cudd_RecursiveDerefZdd(dd, fd);
832  return(NULL);
833  }
834  Cudd_Ref(b1);
835  b0 = cuddMakeBddFromZddCover(dd, f0);
836  if (!b0) {
837  Cudd_RecursiveDerefZdd(dd, f1);
838  Cudd_RecursiveDerefZdd(dd, f0);
839  Cudd_RecursiveDerefZdd(dd, fd);
840  Cudd_RecursiveDeref(dd, b1);
841  return(NULL);
842  }
843  Cudd_Ref(b0);
844  Cudd_RecursiveDerefZdd(dd, f1);
845  Cudd_RecursiveDerefZdd(dd, f0);
846  if (fd != dd->zero) {
847  bd = cuddMakeBddFromZddCover(dd, fd);
848  if (!bd) {
849  Cudd_RecursiveDerefZdd(dd, fd);
850  Cudd_RecursiveDeref(dd, b1);
851  Cudd_RecursiveDeref(dd, b0);
852  return(NULL);
853  }
854  Cudd_Ref(bd);
855  Cudd_RecursiveDerefZdd(dd, fd);
856 
857  T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd));
858  if (!T) {
859  Cudd_RecursiveDeref(dd, b1);
860  Cudd_RecursiveDeref(dd, b0);
861  Cudd_RecursiveDeref(dd, bd);
862  return(NULL);
863  }
864  T = Cudd_NotCond(T, T != NULL);
865  Cudd_Ref(T);
866  Cudd_RecursiveDeref(dd, b1);
867  E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd));
868  if (!E) {
869  Cudd_RecursiveDeref(dd, b0);
870  Cudd_RecursiveDeref(dd, bd);
871  Cudd_RecursiveDeref(dd, T);
872  return(NULL);
873  }
874  E = Cudd_NotCond(E, E != NULL);
875  Cudd_Ref(E);
876  Cudd_RecursiveDeref(dd, b0);
877  Cudd_RecursiveDeref(dd, bd);
878  }
879  else {
880  Cudd_RecursiveDerefZdd(dd, fd);
881  T = b1;
882  E = b0;
883  }
884 
885  if (Cudd_IsComplement(T)) {
886  neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E));
887  if (!neW) {
888  Cudd_RecursiveDeref(dd, T);
889  Cudd_RecursiveDeref(dd, E);
890  return(NULL);
891  }
892  neW = Cudd_Not(neW);
893  }
894  else {
895  neW = cuddUniqueInterIVO(dd, v / 2, T, E);
896  if (!neW) {
897  Cudd_RecursiveDeref(dd, T);
898  Cudd_RecursiveDeref(dd, E);
899  return(NULL);
900  }
901  }
902  Cudd_Ref(neW);
903  Cudd_RecursiveDeref(dd, T);
904  Cudd_RecursiveDeref(dd, E);
905 
907  Cudd_Deref(neW);
908  return(neW);
909 
910 } /* end of cuddMakeBddFromZddCover */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
#define b1
Definition: extraBdd.h:76
DdNode * zero
Definition: cuddInt.h:346
#define Cudd_Regular(node)
Definition: cudd.h:397
DdNode * cuddMakeBddFromZddCover(DdManager *dd, DdNode *node)
Definition: cuddZddIsop.c:800
#define statLine(dd)
Definition: cuddInt.h:1037
#define Cudd_IsComplement(node)
Definition: cudd.h:425
DdNode * cuddCacheLookup1(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddCache.c:556
DdNode * cuddUniqueInterIVO(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1304
int cuddZddGetCofactors3(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)
#define b0
Definition: extraBdd.h:75
DdNode * one
Definition: cuddInt.h:345
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:886
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddCache.c:323
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 716 of file cuddReorder.c.

719 {
720  return(x+1);
721 
722 } /* end of cuddNextHigh */
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 738 of file cuddReorder.c.

741 {
742  return(x-1);
743 
744 } /* end of cuddNextLow */
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 2979 of file cuddUtil.c.

2982 {
2983  DdNodePtr *table;
2984  int size, retval;
2985 
2986  size = ddDagInt(Cudd_Regular(f));
2987  table = ABC_ALLOC(DdNodePtr, size);
2988  if (table == NULL) {
2990  return(NULL);
2991  }
2992 
2993  retval = cuddNodeArrayRecur(f, table, 0);
2994  assert(retval == size);
2995 
2996  *n = size;
2997  return(table);
2998 
2999 } /* cuddNodeArray */
Definition: cudd.h:278
#define Cudd_Regular(node)
Definition: cudd.h:397
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static int size
Definition: cuddSign.c:86
static int ddDagInt(DdNode *n)
Definition: cuddUtil.c:3165
static void ddClearFlag(DdNode *f)
Definition: cuddUtil.c:3735
#define assert(ex)
Definition: util_old.h:213
static int cuddNodeArrayRecur(DdNode *f, DdNodePtr *table, int index)
Definition: cuddUtil.c:3200
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 2866 of file cuddUtil.c.

2869 {
2870  int retval;
2872 
2873  if (table == NULL) return(0);
2874 
2875  retval = dp2(dd,f,table);
2876  st__free_table(table);
2877  (void) fputc('\n',dd->out);
2878  return(retval);
2879 
2880 } /* end of cuddP */
void st__free_table(st__table *table)
Definition: st.c:81
static int dp2(DdManager *dd, DdNode *f, st__table *t)
Definition: cuddUtil.c:3018
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
FILE * out
Definition: cuddInt.h:441
Definition: st.h:52
int st__ptrhash(const char *, int)
Definition: st.c:468
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 710 of file cuddCheck.c.

713 {
714  f = Cudd_Regular(f);
715 #if SIZEOF_VOID_P == 8
716  (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));
717 #else
718  (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));
719 #endif
720 
721 } /* end of cuddPrintNode */
DdHalfWord ref
Definition: cudd.h:280
#define Cudd_Regular(node)
Definition: cudd.h:397
ABC_PTRUINT_T ptruint
Definition: cuddInt.h:261
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
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 747 of file cuddCheck.c.

752 {
753  MtrNode *node;
754  int level;
755 
756  assert(root != NULL);
757  assert(root->younger == NULL || root->younger->elder == root);
758  assert(root->elder == NULL || root->elder->younger == root);
759  if (zdd) {
760  level = dd->permZ[root->index];
761  } else {
762  level = dd->perm[root->index];
763  }
764  if (!silent) (void) printf("(%d",level);
765  if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) {
766  if (!silent) (void) printf(",");
767  } else {
768  node = root->child;
769  while (node != NULL) {
770  assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size));
771  assert(node->parent == root);
772  cuddPrintVarGroups(dd,node,zdd,silent);
773  node = node->younger;
774  }
775  }
776  if (!silent) {
777  (void) printf("%d", (int) (level + root->size - 1));
778  if (root->flags != MTR_DEFAULT) {
779  (void) printf("|");
780  if (MTR_TEST(root,MTR_FIXED)) (void) printf("F");
781  if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N");
782  if (MTR_TEST(root,MTR_SOFT)) (void) printf("S");
783  }
784  (void) printf(")");
785  if (root->parent == NULL) (void) printf("\n");
786  }
787  assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0);
788  return;
789 
790 } /* end of cuddPrintVarGroups */
#define MTR_TERMINAL
Definition: mtr.h:100
MtrHalfWord flags
Definition: mtr.h:132
void cuddPrintVarGroups(DdManager *dd, MtrNode *root, int zdd, int silent)
Definition: cuddCheck.c:747
MtrHalfWord size
Definition: mtr.h:134
#define MTR_FIXED
Definition: mtr.h:102
int * permZ
Definition: cuddInt.h:387
struct MtrNode * parent
Definition: mtr.h:136
#define MTR_DEFAULT
Definition: mtr.h:99
struct MtrNode * elder
Definition: mtr.h:138
#define MTR_TEST(node, flag)
Definition: mtr.h:155
struct MtrNode * younger
Definition: mtr.h:139
MtrHalfWord index
Definition: mtr.h:135
#define MTR_NEWNODE
Definition: mtr.h:103
MtrHalfWord low
Definition: mtr.h:133
Definition: mtr.h:131
#define assert(ex)
Definition: util_old.h:213
struct MtrNode * child
Definition: mtr.h:137
int * perm
Definition: cuddInt.h:386
#define MTR_SOFT
Definition: mtr.h:101
void cuddReclaim ( DdManager table,
DdNode n 
)

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

Synopsis [Brings children of a dead node back.]

Description []

SideEffects [None]

SeeAlso [cuddReclaimZdd]

Definition at line 584 of file cuddRef.c.

587 {
588  DdNode *N;
589  int ord;
590  DdNodePtr *stack = table->stack;
591  int SP = 1;
592  double initialDead = table->dead;
593 
594  N = Cudd_Regular(n);
595 
596 #ifdef DD_DEBUG
597  assert(N->ref == 0);
598 #endif
599 
600  do {
601  if (N->ref == 0) {
602  N->ref = 1;
603  table->dead--;
604  if (cuddIsConstant(N)) {
605  table->constants.dead--;
606  N = stack[--SP];
607  } else {
608  ord = table->perm[N->index];
609  stack[SP++] = Cudd_Regular(cuddE(N));
610  table->subtables[ord].dead--;
611  N = cuddT(N);
612  }
613  } else {
614  cuddSatInc(N->ref);
615  N = stack[--SP];
616  }
617  } while (SP != 0);
618 
619  N = Cudd_Regular(n);
620  cuddSatDec(N->ref);
621  table->reclaimed += initialDead - table->dead;
622 
623 } /* end of cuddReclaim */
DdHalfWord ref
Definition: cudd.h:280
Definition: cudd.h:278
#define Cudd_Regular(node)
Definition: cudd.h:397
DdSubtable * subtables
Definition: cuddInt.h:365
DdNode ** stack
Definition: cuddInt.h:380
unsigned int dead
Definition: cuddInt.h:371
unsigned int dead
Definition: cuddInt.h:332
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define cuddSatDec(x)
Definition: cuddInt.h:896
#define assert(ex)
Definition: util_old.h:213
DdSubtable constants
Definition: cuddInt.h:367
int * perm
Definition: cuddInt.h:386
#define cuddSatInc(x)
Definition: cuddInt.h:878
double reclaimed
Definition: cuddInt.h:384
void cuddReclaimZdd ( DdManager table,
DdNode n 
)

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

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

Description []

SideEffects [None]

SeeAlso [cuddReclaim]

Definition at line 638 of file cuddRef.c.

641 {
642  DdNode *N;
643  int ord;
644  DdNodePtr *stack = table->stack;
645  int SP = 1;
646 
647  N = n;
648 
649 #ifdef DD_DEBUG
650  assert(N->ref == 0);
651 #endif
652 
653  do {
654  cuddSatInc(N->ref);
655 
656  if (N->ref == 1) {
657  table->deadZ--;
658  table->reclaimed++;
659 #ifdef DD_DEBUG
660  assert(!cuddIsConstant(N));
661 #endif
662  ord = table->permZ[N->index];
663  stack[SP++] = cuddE(N);
664  table->subtableZ[ord].dead--;
665  N = cuddT(N);
666  } else {
667  N = stack[--SP];
668  }
669  } while (SP != 0);
670 
671  cuddSatDec(n->ref);
672 
673 } /* end of cuddReclaimZdd */
DdHalfWord ref
Definition: cudd.h:280
Definition: cudd.h:278
unsigned int deadZ
Definition: cuddInt.h:372
int * permZ
Definition: cuddInt.h:387
DdNode ** stack
Definition: cuddInt.h:380
unsigned int dead
Definition: cuddInt.h:332
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
#define cuddSatDec(x)
Definition: cuddInt.h:896
#define assert(ex)
Definition: util_old.h:213
#define cuddSatInc(x)
Definition: cuddInt.h:878
double reclaimed
Definition: cuddInt.h:384
DdSubtable * subtableZ
Definition: cuddInt.h:366
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 1530 of file cuddTable.c.

1533 {
1534  unsigned int slots, oldslots;
1535  int shift, oldshift;
1536  int j, pos;
1537  DdNodePtr *nodelist, *oldnodelist;
1538  DdNode *node, *next;
1539  DdNode *sentinel = &(unique->sentinel);
1540  hack split;
1541  extern DD_OOMFP MMoutOfMemory;
1542  DD_OOMFP saveHandler;
1543 
1544  if (unique->gcFrac == DD_GC_FRAC_HI && unique->slots > unique->looseUpTo) {
1545  unique->gcFrac = DD_GC_FRAC_LO;
1546  unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots);
1547 #ifdef DD_VERBOSE
1548  (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_LO);
1549  (void) fprintf(unique->err,"minDead = %d\n", unique->minDead);
1550 #endif
1551  }
1552 
1553  if (unique->gcFrac != DD_GC_FRAC_MIN && unique->memused > unique->maxmem) {
1554  unique->gcFrac = DD_GC_FRAC_MIN;
1555  unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots);
1556 #ifdef DD_VERBOSE
1557  (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_MIN);
1558  (void) fprintf(unique->err,"minDead = %d\n", unique->minDead);
1559 #endif
1560  cuddShrinkDeathRow(unique);
1561  if (cuddGarbageCollect(unique,1) > 0) return;
1562  }
1563 
1564  if (i != CUDD_CONST_INDEX) {
1565  oldslots = unique->subtables[i].slots;
1566  oldshift = unique->subtables[i].shift;
1567  oldnodelist = unique->subtables[i].nodelist;
1568 
1569  /* Compute the new size of the subtable. */
1570  slots = oldslots << 1;
1571  shift = oldshift - 1;
1572 
1573  saveHandler = MMoutOfMemory;
1574  MMoutOfMemory = Cudd_OutOfMem;
1575  nodelist = ABC_ALLOC(DdNodePtr, slots);
1576  MMoutOfMemory = saveHandler;
1577  if (nodelist == NULL) {
1578  (void) fprintf(unique->err,
1579  "Unable to resize subtable %d for lack of memory\n",
1580  i);
1581  /* Prevent frequent resizing attempts. */
1582  (void) cuddGarbageCollect(unique,1);
1583  if (unique->stash != NULL) {
1584  ABC_FREE(unique->stash);
1585  unique->stash = NULL;
1586  /* Inhibit resizing of tables. */
1587  cuddSlowTableGrowth(unique);
1588  }
1589  return;
1590  }
1591  unique->subtables[i].nodelist = nodelist;
1592  unique->subtables[i].slots = slots;
1593  unique->subtables[i].shift = shift;
1594  unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
1595 
1596  /* Move the nodes from the old table to the new table.
1597  ** This code depends on the type of hash function.
1598  ** It assumes that the effect of doubling the size of the table
1599  ** is to retain one more bit of the 32-bit hash value.
1600  ** The additional bit is the LSB. */
1601  for (j = 0; (unsigned) j < oldslots; j++) {
1602  DdNodePtr *evenP, *oddP;
1603  node = oldnodelist[j];
1604  evenP = &(nodelist[j<<1]);
1605  oddP = &(nodelist[(j<<1)+1]);
1606  while (node != sentinel) {
1607  next = node->next;
1608  pos = ddHash(cuddF2L(cuddT(node)), cuddF2L(cuddE(node)), shift);
1609  if (pos & 1) {
1610  *oddP = node;
1611  oddP = &(node->next);
1612  } else {
1613  *evenP = node;
1614  evenP = &(node->next);
1615  }
1616  node = next;
1617  }
1618  *evenP = *oddP = sentinel;
1619  }
1620  ABC_FREE(oldnodelist);
1621 
1622 #ifdef DD_VERBOSE
1623  (void) fprintf(unique->err,
1624  "rehashing layer %d: keys %d dead %d new size %d\n",
1625  i, unique->subtables[i].keys,
1626  unique->subtables[i].dead, slots);
1627 #endif
1628  } else {
1629  oldslots = unique->constants.slots;
1630  oldshift = unique->constants.shift;
1631  oldnodelist = unique->constants.nodelist;
1632 
1633  /* The constant subtable is never subjected to reordering.
1634  ** Therefore, when it is resized, it is because it has just
1635  ** reached the maximum load. We can safely just double the size,
1636  ** with no need for the loop we use for the other tables.
1637  */
1638  slots = oldslots << 1;
1639  shift = oldshift - 1;
1640  saveHandler = MMoutOfMemory;
1641  MMoutOfMemory = Cudd_OutOfMem;
1642  nodelist = ABC_ALLOC(DdNodePtr, slots);
1643  MMoutOfMemory = saveHandler;
1644  if (nodelist == NULL) {
1645  (void) fprintf(unique->err,
1646  "Unable to resize constant subtable for lack of memory\n");
1647  (void) cuddGarbageCollect(unique,1);
1648  for (j = 0; j < unique->size; j++) {
1649  unique->subtables[j].maxKeys <<= 1;
1650  }
1651  unique->constants.maxKeys <<= 1;
1652  return;
1653  }
1654  unique->constants.slots = slots;
1655  unique->constants.shift = shift;
1656  unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
1657  unique->constants.nodelist = nodelist;
1658  for (j = 0; (unsigned) j < slots; j++) {
1659  nodelist[j] = NULL;
1660  }
1661  for (j = 0; (unsigned) j < oldslots; j++) {
1662  node = oldnodelist[j];
1663  while (node != NULL) {
1664  next = node->next;
1665  split.value = cuddV(node);
1666  pos = ddHash(split.bits[0], split.bits[1], shift);
1667  node->next = nodelist[pos];
1668  nodelist[pos] = node;
1669  node = next;
1670  }
1671  }
1672  ABC_FREE(oldnodelist);
1673 
1674 #ifdef DD_VERBOSE
1675  (void) fprintf(unique->err,
1676  "rehashing constants: keys %d dead %d new size %d\n",
1677  unique->constants.keys,unique->constants.dead,slots);
1678 #endif
1679  }
1680 
1681  /* Update global data */
1682 
1683  unique->memused += (slots - oldslots) * sizeof(DdNodePtr);
1684  unique->slots += (slots - oldslots);
1685  ddFixLimits(unique);
1686 
1687 } /* end of cuddRehash */
unsigned int keys
Definition: cuddInt.h:330
void(* DD_OOMFP)(long)
Definition: cudd.h:324
#define ddHash(f, g, s)
Definition: cuddInt.h:737
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2837
Definition: cudd.h:278
unsigned int bits[2]
Definition: cuddTable.c:112
int size
Definition: cuddInt.h:361
double gcFrac
Definition: cuddInt.h:375
unsigned int slots
Definition: cuddInt.h:368
bool pos
Definition: globals.c:30
FILE * err
Definition: cuddInt.h:442
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdSubtable * subtables
Definition: cuddInt.h:365
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:126
#define cuddV(node)
Definition: cuddInt.h:668
#define DD_GC_FRAC_HI
Definition: cuddInt.h:134
DdNode sentinel
Definition: cuddInt.h:344
char * stash
Definition: cuddInt.h:399
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:729
unsigned int dead
Definition: cuddInt.h:332
DdNode * next
Definition: cudd.h:281
#define DD_GC_FRAC_LO
Definition: cuddInt.h:133
unsigned int maxKeys
Definition: cuddInt.h:331
#define CUDD_CONST_INDEX
Definition: cudd.h:117
DdNode ** nodelist
Definition: cuddInt.h:327
#define cuddF2L(f)
Definition: cuddInt.h:718
#define cuddT(node)
Definition: cuddInt.h:636
CUDD_VALUE_TYPE value
Definition: cuddTable.c:111
#define DD_GC_FRAC_MIN
Definition: cuddInt.h:135
void cuddSlowTableGrowth(DdManager *unique)
Definition: cuddTable.c:2385
unsigned long memused
Definition: cuddInt.h:449
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int looseUpTo
Definition: cuddInt.h:377
unsigned int slots
Definition: cuddInt.h:329
#define cuddE(node)
Definition: cuddInt.h:652
static DD_INLINE void ddFixLimits(DdManager *unique)
Definition: cuddTable.c:2805
DdSubtable constants
Definition: cuddInt.h:367
unsigned long maxmem
Definition: cuddInt.h:450
int shift
Definition: cuddInt.h:328
void cuddShrinkDeathRow(DdManager *table)
Definition: cuddRef.c:688
unsigned int minDead
Definition: cuddInt.h:374
#define MMoutOfMemory
Definition: util_hack.h:38
DdNode* cuddRemapUnderApprox ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
double  quality 
)

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

Synopsis [Applies the remapping underappoximation algorithm.]

Description [Applies the remapping underappoximation algorithm. Proceeds in three phases:

  • collect information on each node in the BDD; this is done via DFS.
  • traverse the BDD in top-down fashion and compute for each node whether remapping increases density.
  • traverse the BDD via DFS and actually perform the elimination.

Returns the approximated BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_RemapUnderApprox]

Definition at line 601 of file cuddApprox.c.

607 {
608  ApproxInfo *info;
609  DdNode *subset;
610  int result;
611 
612  if (f == NULL) {
613  fprintf(dd->err, "Cannot subset, nil object\n");
615  return(NULL);
616  }
617 
618  if (Cudd_IsConstant(f)) {
619  return(f);
620  }
621 
622  /* Create table where node data are accessible via a hash table. */
623  info = gatherInfo(dd, f, numVars, TRUE);
624  if (info == NULL) {
625  (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
627  return(NULL);
628  }
629 
630  /* Mark nodes that should be replaced by zero. */
631  result = RAmarkNodes(dd, f, info, threshold, quality);
632  if (result == 0) {
633  (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
634  ABC_FREE(info->page);
635  st__free_table(info->table);
636  ABC_FREE(info);
638  return(NULL);
639  }
640 
641  /* Build the result. */
642  subset = RAbuildSubset(dd, f, info);
643 #if 1
644  if (subset && info->size < Cudd_DagSize(subset))
645  (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n",
646  info->size, Cudd_DagSize(subset));
647 #endif
648  ABC_FREE(info->page);
649  st__free_table(info->table);
650  ABC_FREE(info);
651 
652 #ifdef DD_DEBUG
653  if (subset != NULL) {
654  cuddRef(subset);
655 #if 0
656  (void) Cudd_DebugCheck(dd);
657  (void) Cudd_CheckKeys(dd);
658 #endif
659  if (!Cudd_bddLeq(dd, subset, f)) {
660  (void) fprintf(dd->err, "Wrong subset\n");
661  }
662  cuddDeref(subset);
664  }
665 #endif
666  return(subset);
667 
668 } /* end of cuddRemapUnderApprox */
void st__free_table(st__table *table)
Definition: st.c:81
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_IsConstant(node)
Definition: cudd.h:352
FILE * err
Definition: cuddInt.h:442
static ApproxInfo * gatherInfo(DdManager *dd, DdNode *node, int numVars, int parity)
Definition: cuddApprox.c:907
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:142
st__table * table
Definition: cuddApprox.c:135
#define TRUE
Definition: cudd.h:88
static int RAmarkNodes(DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality)
Definition: cuddApprox.c:1371
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
#define ABC_FREE(obj)
Definition: abc_global.h:232
int Cudd_CheckKeys(DdManager *table)
Definition: cuddCheck.c:458
static DdNode * RAbuildSubset(DdManager *dd, DdNode *node, ApproxInfo *info)
Definition: cuddApprox.c:1990
NodeData * page
Definition: cuddApprox.c:134
static int result
Definition: cuddGenetic.c:125
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
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 804 of file cuddLinear.c.

806 {
807  int words,oldWords;
808  int wordsPerRow,oldWordsPerRow;
809  int nvars,oldNvars;
810  int word,oldWord;
811  int bit;
812  int i,j;
813  long *linear,*oldLinear;
814 
815  oldNvars = table->linearSize;
816  oldWordsPerRow = ((oldNvars - 1) >> LOGBPL) + 1;
817  oldWords = oldWordsPerRow * oldNvars;
818  oldLinear = table->linear;
819 
820  nvars = table->size;
821  wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
822  words = wordsPerRow * nvars;
823  table->linear = linear = ABC_ALLOC(long,words);
824  if (linear == NULL) {
825  table->errorCode = CUDD_MEMORY_OUT;
826  return(0);
827  }
828  table->memused += (words - oldWords) * sizeof(long);
829  for (i = 0; i < words; i++) linear[i] = 0;
830 
831  /* Copy old matrix. */
832  for (i = 0; i < oldNvars; i++) {
833  for (j = 0; j < oldWordsPerRow; j++) {
834  oldWord = oldWordsPerRow * i + j;
835  word = wordsPerRow * i + j;
836  linear[word] = oldLinear[oldWord];
837  }
838  }
839  ABC_FREE(oldLinear);
840 
841  /* Add elements to the diagonal. */
842  for (i = oldNvars; i < nvars; i++) {
843  word = wordsPerRow * i + (i >> LOGBPL);
844  bit = i & (BPL-1);
845  linear[word] = 1 << bit;
846  }
847  table->linearSize = nvars;
848 
849  return(1);
850 
851 } /* end of cuddResizeLinear */
#define BPL
Definition: cuddLinear.c:82
int size
Definition: cuddInt.h:361
#define LOGBPL
Definition: cuddLinear.c:83
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
long * linear
Definition: cuddInt.h:395
int linearSize
Definition: cuddInt.h:393
unsigned long memused
Definition: cuddInt.h:449
#define ABC_FREE(obj)
Definition: abc_global.h:232
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
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 2241 of file cuddTable.c.

2244 {
2245  DdSubtable *newsubtables;
2246  DdNodePtr *newnodelist;
2247  int oldsize,newsize;
2248  int i,j,reorderSave;
2249  unsigned int numSlots = unique->initSlots;
2250  int *newperm, *newinvperm;
2251 
2252  oldsize = unique->sizeZ;
2253  /* Easy case: there is still room in the current table. */
2254  if (index < unique->maxSizeZ) {
2255  for (i = oldsize; i <= index; i++) {
2256  unique->subtableZ[i].slots = numSlots;
2257  unique->subtableZ[i].shift = sizeof(int) * 8 -
2258  cuddComputeFloorLog2(numSlots);
2259  unique->subtableZ[i].keys = 0;
2260  unique->subtableZ[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY;
2261  unique->subtableZ[i].dead = 0;
2262  unique->permZ[i] = i;
2263  unique->invpermZ[i] = i;
2264  newnodelist = unique->subtableZ[i].nodelist =
2265  ABC_ALLOC(DdNodePtr, numSlots);
2266  if (newnodelist == NULL) {
2267  unique->errorCode = CUDD_MEMORY_OUT;
2268  return(0);
2269  }
2270  for (j = 0; (unsigned) j < numSlots; j++) {
2271  newnodelist[j] = NULL;
2272  }
2273  }
2274  } else {
2275  /* The current table is too small: we need to allocate a new,
2276  ** larger one; move all old subtables, and initialize the new
2277  ** subtables up to index included.
2278  */
2279  newsize = index + DD_DEFAULT_RESIZE;
2280 #ifdef DD_VERBOSE
2281  (void) fprintf(unique->err,
2282  "Increasing the ZDD table size from %d to %d\n",
2283  unique->maxSizeZ, newsize);
2284 #endif
2285  newsubtables = ABC_ALLOC(DdSubtable,newsize);
2286  if (newsubtables == NULL) {
2287  unique->errorCode = CUDD_MEMORY_OUT;
2288  return(0);
2289  }
2290  newperm = ABC_ALLOC(int,newsize);
2291  if (newperm == NULL) {
2292  unique->errorCode = CUDD_MEMORY_OUT;
2293  return(0);
2294  }
2295  newinvperm = ABC_ALLOC(int,newsize);
2296  if (newinvperm == NULL) {
2297  unique->errorCode = CUDD_MEMORY_OUT;
2298  return(0);
2299  }
2300  unique->memused += (newsize - unique->maxSizeZ) * ((numSlots+1) *
2301  sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable));
2302  if (newsize > unique->maxSize) {
2303  ABC_FREE(unique->stack);
2304  unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1);
2305  if (unique->stack == NULL) {
2306  unique->errorCode = CUDD_MEMORY_OUT;
2307  return(0);
2308  }
2309  unique->stack[0] = NULL; /* to suppress harmless UMR */
2310  unique->memused +=
2311  (newsize - ddMax(unique->maxSize,unique->maxSizeZ))
2312  * sizeof(DdNode *);
2313  }
2314  for (i = 0; i < oldsize; i++) {
2315  newsubtables[i].slots = unique->subtableZ[i].slots;
2316  newsubtables[i].shift = unique->subtableZ[i].shift;
2317  newsubtables[i].keys = unique->subtableZ[i].keys;
2318  newsubtables[i].maxKeys = unique->subtableZ[i].maxKeys;
2319  newsubtables[i].dead = unique->subtableZ[i].dead;
2320  newsubtables[i].nodelist = unique->subtableZ[i].nodelist;
2321  newperm[i] = unique->permZ[i];
2322  newinvperm[i] = unique->invpermZ[i];
2323  }
2324  for (i = oldsize; i <= index; i++) {
2325  newsubtables[i].slots = numSlots;
2326  newsubtables[i].shift = sizeof(int) * 8 -
2327  cuddComputeFloorLog2(numSlots);
2328  newsubtables[i].keys = 0;
2329  newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY;
2330  newsubtables[i].dead = 0;
2331  newperm[i] = i;
2332  newinvperm[i] = i;
2333  newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots);
2334  if (newnodelist == NULL) {
2335  unique->errorCode = CUDD_MEMORY_OUT;
2336  return(0);
2337  }
2338  for (j = 0; (unsigned) j < numSlots; j++) {
2339  newnodelist[j] = NULL;
2340  }
2341  }
2342  ABC_FREE(unique->subtableZ);
2343  unique->subtableZ = newsubtables;
2344  unique->maxSizeZ = newsize;
2345  ABC_FREE(unique->permZ);
2346  unique->permZ = newperm;
2347  ABC_FREE(unique->invpermZ);
2348  unique->invpermZ = newinvperm;
2349  }
2350  unique->slots += (index + 1 - unique->sizeZ) * numSlots;
2351  ddFixLimits(unique);
2352  unique->sizeZ = index + 1;
2353 
2354  /* Now that the table is in a coherent state, update the ZDD
2355  ** universe. We need to temporarily disable reordering,
2356  ** because we cannot reorder without universe in place.
2357  */
2358 
2359  reorderSave = unique->autoDynZ;
2360  unique->autoDynZ = 0;
2361  cuddZddFreeUniv(unique);
2362  if (!cuddZddInitUniv(unique)) {
2363  unique->autoDynZ = reorderSave;
2364  return(0);
2365  }
2366  unique->autoDynZ = reorderSave;
2367 
2368  return(1);
2369 
2370 } /* end of cuddResizeTableZdd */
unsigned int keys
Definition: cuddInt.h:330
int cuddZddInitUniv(DdManager *zdd)
Definition: cuddInit.c:252
int maxSizeZ
Definition: cuddInt.h:364
Definition: cudd.h:278
int * invpermZ
Definition: cuddInt.h:389
unsigned int slots
Definition: cuddInt.h:368
FILE * err
Definition: cuddInt.h:442
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int * permZ
Definition: cuddInt.h:387
struct DdSubtable DdSubtable
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:126
DdNode ** stack
Definition: cuddInt.h:380
unsigned int initSlots
Definition: cuddInt.h:379
unsigned int dead
Definition: cuddInt.h:332
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1079
int maxSize
Definition: cuddInt.h:363
void cuddZddFreeUniv(DdManager *zdd)
Definition: cuddInit.c:301
unsigned int maxKeys
Definition: cuddInt.h:331
#define ddMax(x, y)
Definition: cuddInt.h:832
DdNode ** nodelist
Definition: cuddInt.h:327
unsigned long memused
Definition: cuddInt.h:449
#define DD_DEFAULT_RESIZE
Definition: cuddInt.h:102
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int slots
Definition: cuddInt.h:329
int autoDynZ
Definition: cuddInt.h:417
static DD_INLINE void ddFixLimits(DdManager *unique)
Definition: cuddTable.c:2805
int shift
Definition: cuddInt.h:328
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdSubtable * subtableZ
Definition: cuddInt.h:366
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 156 of file cuddInteract.c.

160 {
161  int posn, word, bit;
162 
163 #ifdef DD_DEBUG
164  assert(x < y);
165  assert(y < table->size);
166  assert(x >= 0);
167 #endif
168 
169  posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1;
170  word = posn >> LOGBPL;
171  bit = posn & (BPL-1);
172  table->interact[word] |= 1L << bit;
173 
174 } /* end of cuddSetInteract */
int size
Definition: cuddInt.h:361
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
long * interact
Definition: cuddInt.h:394
static int size
Definition: cuddSign.c:86
#define BPL
Definition: cuddInteract.c:92
#define assert(ex)
Definition: util_old.h:213
#define LOGBPL
Definition: cuddInteract.c:93
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 688 of file cuddRef.c.

690 {
691 #ifndef DD_NO_DEATH_ROW
692  int i;
693 
694  if (table->deathRowDepth > 3) {
695  for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) {
696  if (table->deathRow[i] == NULL) break;
697  Cudd_IterDerefBdd(table,table->deathRow[i]);
698  table->deathRow[i] = NULL;
699  }
700  table->deathRowDepth /= 4;
701  table->deadMask = table->deathRowDepth - 1;
702  if ((unsigned) table->nextDead > table->deadMask) {
703  table->nextDead = 0;
704  }
705  table->deathRow = ABC_REALLOC(DdNodePtr, table->deathRow,
706  table->deathRowDepth);
707  }
708 #endif
709 
710 } /* end of cuddShrinkDeathRow */
Definition: cudd.h:278
unsigned deadMask
Definition: cuddInt.h:404
#define ABC_REALLOC(type, obj, num)
Definition: abc_global.h:233
DdNode ** deathRow
Definition: cuddInt.h:401
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:217
int nextDead
Definition: cuddInt.h:403
int deathRowDepth
Definition: cuddInt.h:402
void cuddShrinkSubtable ( DdManager unique,
int  i 
)

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

Synopsis [Shrinks a subtable.]

Description [Shrinks a subtable.]

SideEffects [None]

SeeAlso [cuddRehash]

Definition at line 1702 of file cuddTable.c.

1705 {
1706  int j;
1707  int shift, posn;
1708  DdNodePtr *nodelist, *oldnodelist;
1709  DdNode *node, *next;
1710  DdNode *sentinel = &(unique->sentinel);
1711  unsigned int slots, oldslots;
1712  extern DD_OOMFP MMoutOfMemory;
1713  DD_OOMFP saveHandler;
1714 
1715  oldnodelist = unique->subtables[i].nodelist;
1716  oldslots = unique->subtables[i].slots;
1717  slots = oldslots >> 1;
1718  saveHandler = MMoutOfMemory;
1719  MMoutOfMemory = Cudd_OutOfMem;
1720  nodelist = ABC_ALLOC(DdNodePtr, slots);
1721  MMoutOfMemory = saveHandler;
1722  if (nodelist == NULL) {
1723  return;
1724  }
1725  unique->subtables[i].nodelist = nodelist;
1726  unique->subtables[i].slots = slots;
1727  unique->subtables[i].shift++;
1728  unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
1729 #ifdef DD_VERBOSE
1730  (void) fprintf(unique->err,
1731  "shrunk layer %d (%d keys) from %d to %d slots\n",
1732  i, unique->subtables[i].keys, oldslots, slots);
1733 #endif
1734 
1735  for (j = 0; (unsigned) j < slots; j++) {
1736  nodelist[j] = sentinel;
1737  }
1738  shift = unique->subtables[i].shift;
1739  for (j = 0; (unsigned) j < oldslots; j++) {
1740  node = oldnodelist[j];
1741  while (node != sentinel) {
1742  DdNode *looking, *T, *E;
1743  DdNodePtr *previousP;
1744  next = node->next;
1745  posn = ddHash(cuddF2L(cuddT(node)), cuddF2L(cuddE(node)), shift);
1746  previousP = &(nodelist[posn]);
1747  looking = *previousP;
1748  T = cuddT(node);
1749  E = cuddE(node);
1750  while (T < cuddT(looking)) {
1751  previousP = &(looking->next);
1752  looking = *previousP;
1753 #ifdef DD_UNIQUE_PROFILE
1754  unique->uniqueLinks++;
1755 #endif
1756  }
1757  while (T == cuddT(looking) && E < cuddE(looking)) {
1758  previousP = &(looking->next);
1759  looking = *previousP;
1760 #ifdef DD_UNIQUE_PROFILE
1761  unique->uniqueLinks++;
1762 #endif
1763  }
1764  node->next = *previousP;
1765  *previousP = node;
1766  node = next;
1767  }
1768  }
1769  ABC_FREE(oldnodelist);
1770 
1771  unique->memused += ((long) slots - (long) oldslots) * sizeof(DdNode *);
1772  unique->slots += slots - oldslots;
1773  unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots);
1774  unique->cacheSlack = (int)
1776  - 2 * (int) unique->cacheSlots;
1777 
1778 } /* end of cuddShrinkSubtable */
unsigned int keys
Definition: cuddInt.h:330
void(* DD_OOMFP)(long)
Definition: cudd.h:324
#define ddHash(f, g, s)
Definition: cuddInt.h:737
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2837
Definition: cudd.h:278
double gcFrac
Definition: cuddInt.h:375
unsigned int maxCacheHard
Definition: cuddInt.h:359
unsigned int slots
Definition: cuddInt.h:368
FILE * err
Definition: cuddInt.h:442
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdSubtable * subtables
Definition: cuddInt.h:365
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:126
unsigned int cacheSlots
Definition: cuddInt.h:353
DdNode sentinel
Definition: cuddInt.h:344
DdNode * next
Definition: cudd.h:281
unsigned int maxKeys
Definition: cuddInt.h:331
DdNode ** nodelist
Definition: cuddInt.h:327
#define cuddF2L(f)
Definition: cuddInt.h:718
#define ddMin(x, y)
Definition: cuddInt.h:818
#define DD_MAX_CACHE_TO_SLOTS_RATIO
Definition: cuddInt.h:144
int cacheSlack
Definition: cuddInt.h:358
#define cuddT(node)
Definition: cuddInt.h:636
unsigned long memused
Definition: cuddInt.h:449
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int slots
Definition: cuddInt.h:329
#define cuddE(node)
Definition: cuddInt.h:652
int shift
Definition: cuddInt.h:328
unsigned int minDead
Definition: cuddInt.h:374
#define MMoutOfMemory
Definition: util_hack.h:38
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 508 of file cuddReorder.c.

512 {
513  int i;
514  int *var;
515  int size;
516  int x;
517  int result;
518 #ifdef DD_STATS
519  int previousSize;
520 #endif
521 
522  size = table->size;
523 
524  /* Find order in which to sift variables. */
525  var = NULL;
526  entry = ABC_ALLOC(int,size);
527  if (entry == NULL) {
528  table->errorCode = CUDD_MEMORY_OUT;
529  goto cuddSiftingOutOfMem;
530  }
531  var = ABC_ALLOC(int,size);
532  if (var == NULL) {
533  table->errorCode = CUDD_MEMORY_OUT;
534  goto cuddSiftingOutOfMem;
535  }
536 
537  for (i = 0; i < size; i++) {
538  x = table->perm[i];
539  entry[i] = table->subtables[x].keys;
540  var[i] = i;
541  }
542 
543  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddUniqueCompare);
544 
545  /* Now sift. */
546  for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
547  if (ddTotalNumberSwapping >= table->siftMaxSwap)
548  break;
549  x = table->perm[var[i]];
550 
551  if (x < lower || x > upper || table->subtables[x].bindVar == 1)
552  continue;
553 #ifdef DD_STATS
554  previousSize = table->keys - table->isolated;
555 #endif
556  result = ddSiftingAux(table, x, lower, upper);
557  if (!result) goto cuddSiftingOutOfMem;
558 #ifdef DD_STATS
559  if (table->keys < (unsigned) previousSize + table->isolated) {
560  (void) fprintf(table->out,"-");
561  } else if (table->keys > (unsigned) previousSize + table->isolated) {
562  (void) fprintf(table->out,"+"); /* should never happen */
563  (void) fprintf(table->err,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]);
564  } else {
565  (void) fprintf(table->out,"=");
566  }
567  fflush(table->out);
568 #endif
569  }
570 
571  ABC_FREE(var);
572  ABC_FREE(entry);
573 
574  return(1);
575 
576 cuddSiftingOutOfMem:
577 
578  if (entry != NULL) ABC_FREE(entry);
579  if (var != NULL) ABC_FREE(var);
580 
581  return(0);
582 
583 } /* end of cuddSifting */
static int * entry
Definition: cuddReorder.c:105
unsigned int keys
Definition: cuddInt.h:330
int siftMaxSwap
Definition: cuddInt.h:412
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:326
int size
Definition: cuddInt.h:361
int var(Lit p)
Definition: SolverTypes.h:62
FILE * err
Definition: cuddInt.h:442
static int ddSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddReorder.c:1488
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int bindVar
Definition: cuddInt.h:334
DdSubtable * subtables
Definition: cuddInt.h:365
int ddTotalNumberSwapping
Definition: cuddReorder.c:107
unsigned int keys
Definition: cuddInt.h:369
FILE * out
Definition: cuddInt.h:441
static int ddUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddReorder.c:1323
static int size
Definition: cuddSign.c:86
#define ddMin(x, y)
Definition: cuddInt.h:818
int siftMaxVar
Definition: cuddInt.h:411
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int result
Definition: cuddGenetic.c:125
int isolated
Definition: cuddInt.h:385
int * perm
Definition: cuddInt.h:386
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
void cuddSlowTableGrowth ( DdManager unique)

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

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

Description []

SideEffects [None]

SeeAlso []

Definition at line 2385 of file cuddTable.c.

2387 {
2388  int i;
2389 
2390  unique->maxCacheHard = unique->cacheSlots - 1;
2391  unique->cacheSlack = - (int) (unique->cacheSlots + 1);
2392  for (i = 0; i < unique->size; i++) {
2393  unique->subtables[i].maxKeys <<= 2;
2394  }
2395  unique->gcFrac = DD_GC_FRAC_MIN;
2396  unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots);
2397  cuddShrinkDeathRow(unique);
2398  (void) fprintf(unique->err,"Slowing down table growth: ");
2399  (void) fprintf(unique->err,"GC fraction = %.2f\t", unique->gcFrac);
2400  (void) fprintf(unique->err,"minDead = %u\n", unique->minDead);
2401 
2402 } /* end of cuddSlowTableGrowth */
int size
Definition: cuddInt.h:361
double gcFrac
Definition: cuddInt.h:375
unsigned int maxCacheHard
Definition: cuddInt.h:359
unsigned int slots
Definition: cuddInt.h:368
FILE * err
Definition: cuddInt.h:442
DdSubtable * subtables
Definition: cuddInt.h:365
unsigned int cacheSlots
Definition: cuddInt.h:353
unsigned int maxKeys
Definition: cuddInt.h:331
int cacheSlack
Definition: cuddInt.h:358
#define DD_GC_FRAC_MIN
Definition: cuddInt.h:135
void cuddShrinkDeathRow(DdManager *table)
Definition: cuddRef.c:688
unsigned int minDead
Definition: cuddInt.h:374
DdNode* cuddSolveEqnRecur ( DdManager bdd,
DdNode F,
DdNode Y,
DdNode **  G,
int  n,
int *  yIndex,
int  i 
)

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

Synopsis [Implements the recursive step of Cudd_SolveEqn.]

Description [Implements the recursive step of Cudd_SolveEqn. Returns NULL if the intermediate solution blows up or reordering occurs. The parametric solutions are stored in the array G.]

SideEffects [none]

SeeAlso [Cudd_SolveEqn, Cudd_VerifySol]

Definition at line 210 of file cuddSolve.c.

218 {
219  DdNode *Fn, *Fm1, *Fv, *Fvbar, *T, *w, *nextY, *one;
220  DdNodePtr *variables;
221 
222  int j;
223 
224  statLine(bdd);
225  variables = bdd->vars;
226  one = DD_ONE(bdd);
227 
228  /* Base condition. */
229  if (Y == one) {
230  return F;
231  }
232 
233  /* Cofactor of Y. */
234  yIndex[i] = Y->index;
235  nextY = Cudd_T(Y);
236 
237  /* Universal abstraction of F with respect to the top variable index. */
238  Fm1 = cuddBddExistAbstractRecur(bdd, Cudd_Not(F), variables[yIndex[i]]);
239  if (Fm1) {
240  Fm1 = Cudd_Not(Fm1);
241  cuddRef(Fm1);
242  } else {
243  return(NULL);
244  }
245 
246  Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1);
247  if (Fn) {
248  cuddRef(Fn);
249  } else {
250  Cudd_RecursiveDeref(bdd, Fm1);
251  return(NULL);
252  }
253 
254  Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]);
255  if (Fv) {
256  cuddRef(Fv);
257  } else {
258  Cudd_RecursiveDeref(bdd, Fm1);
259  Cudd_RecursiveDeref(bdd, Fn);
260  return(NULL);
261  }
262 
263  Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]]));
264  if (Fvbar) {
265  cuddRef(Fvbar);
266  } else {
267  Cudd_RecursiveDeref(bdd, Fm1);
268  Cudd_RecursiveDeref(bdd, Fn);
269  Cudd_RecursiveDeref(bdd, Fv);
270  return(NULL);
271  }
272 
273  /* Build i-th component of the solution. */
274  w = cuddBddIteRecur(bdd, variables[yIndex[i]], Cudd_Not(Fv), Fvbar);
275  if (w) {
276  cuddRef(w);
277  } else {
278  Cudd_RecursiveDeref(bdd, Fm1);
279  Cudd_RecursiveDeref(bdd, Fn);
280  Cudd_RecursiveDeref(bdd, Fv);
281  Cudd_RecursiveDeref(bdd, Fvbar);
282  return(NULL);
283  }
284 
285  T = cuddBddRestrictRecur(bdd, w, Cudd_Not(Fm1));
286  if(T) {
287  cuddRef(T);
288  } else {
289  Cudd_RecursiveDeref(bdd, Fm1);
290  Cudd_RecursiveDeref(bdd, Fn);
291  Cudd_RecursiveDeref(bdd, Fv);
292  Cudd_RecursiveDeref(bdd, Fvbar);
293  Cudd_RecursiveDeref(bdd, w);
294  return(NULL);
295  }
296 
297  Cudd_RecursiveDeref(bdd,Fm1);
298  Cudd_RecursiveDeref(bdd,w);
299  Cudd_RecursiveDeref(bdd,Fv);
300  Cudd_RecursiveDeref(bdd,Fvbar);
301 
302  /* Substitute components of solution already found into solution. */
303  for (j = n-1; j > i; j--) {
304  w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]);
305  if(w) {
306  cuddRef(w);
307  } else {
308  Cudd_RecursiveDeref(bdd, Fn);
309  Cudd_RecursiveDeref(bdd, T);
310  return(NULL);
311  }
312  Cudd_RecursiveDeref(bdd,T);
313  T = w;
314  }
315  G[i] = T;
316 
317  Cudd_Deref(Fn);
318 
319  return(Fn);
320 
321 } /* end of cuddSolveEqnRecur */
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddBddAbs.c:352
#define cuddRef(n)
Definition: cuddInt.h:584
#define Cudd_T(node)
Definition: cudd.h:440
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
DdNode * cuddBddComposeRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *proj)
Definition: cuddCompose.c:850
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
#define statLine(dd)
Definition: cuddInt.h:1037
static DdNode * one
Definition: cuddDecomp.c:112
DdNode * cuddCofactorRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddCof.c:230
DdNode * cuddSolveEqnRecur(DdManager *bdd, DdNode *F, DdNode *Y, DdNode **G, int n, int *yIndex, int i)
Definition: cuddSolve.c:210
DdHalfWord index
Definition: cudd.h:279
DdNode ** vars
Definition: cuddInt.h:390
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddRestrictRecur(DdManager *dd, DdNode *f, DdNode *c)
Definition: cuddGenCof.c:912
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633
DdNode* cuddSubsetHeavyBranch ( DdManager dd,
DdNode f,
int  numVars,
int  threshold 
)

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

Synopsis [The main procedure that returns a subset by choosing the heavier branch in the BDD.]

Description [Here a subset BDD is built by throwing away one of the children. Starting at root, annotate each node with the number of minterms (in terms of the total number of variables specified - numVars), number of nodes taken by the DAG rooted at this node and number of additional nodes taken by the child that has the lesser minterms. The child with the lower number of minterms is thrown away and a dyanmic count of the nodes of the subset is kept. Once the threshold is reached the subset is returned to the calling procedure.]

SideEffects [None]

SeeAlso [Cudd_SubsetHeavyBranch]

Definition at line 305 of file cuddSubsetHB.c.

310 {
311 
312  int i, *size;
313  st__table *visitedTable;
314  int numNodes;
315  NodeData_t *currNodeQual;
316  DdNode *subset;
317  st__table *storeTable, *approxTable;
318  char *key, *value;
319  st__generator *stGen;
320 
321  if (f == NULL) {
322  fprintf(dd->err, "Cannot subset, nil object\n");
324  return(NULL);
325  }
326 
327  one = Cudd_ReadOne(dd);
328  zero = Cudd_Not(one);
329 
330  /* If user does not know numVars value, set it to the maximum
331  * exponent that the pow function can take. The -1 is due to the
332  * discrepancy in the value that pow takes and the value that
333  * log gives.
334  */
335  if (numVars == 0) {
336  /* set default value */
337  numVars = DBL_MAX_EXP - 1;
338  }
339 
340  if (Cudd_IsConstant(f)) {
341  return(f);
342  }
343 
344  max = pow(2.0, (double)numVars);
345 
346  /* Create visited table where structures for node data are allocated and
347  stored in a st__table */
348  visitedTable = SubsetCountMinterm(f, numVars);
349  if ((visitedTable == NULL) || memOut) {
350  (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
352  return(0);
353  }
354  numNodes = SubsetCountNodes(f, visitedTable, numVars);
355  if (memOut) {
356  (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
358  return(0);
359  }
360 
361  if ( st__lookup(visitedTable, (const char *)f, (char **)&currNodeQual) == 0) {
362  fprintf(dd->err,
363  "Something is wrong, ought to be node quality table\n");
365  }
366 
367  size = ABC_ALLOC(int, 1);
368  if (size == NULL) {
370  return(NULL);
371  }
372  *size = numNodes;
373 
374 #ifdef DEBUG
375  num_calls = 0;
376 #endif
377  /* table to store nodes being created. */
378  storeTable = st__init_table( st__ptrcmp, st__ptrhash);
379  /* insert the constant */
380  cuddRef(one);
381  if ( st__insert(storeTable, (char *)Cudd_ReadOne(dd), NIL(char)) ==
382  st__OUT_OF_MEM) {
383  fprintf(dd->out, "Something wrong, st__table insert failed\n");
384  }
385  /* table to store approximations of nodes */
386  approxTable = st__init_table( st__ptrcmp, st__ptrhash);
387  subset = (DdNode *)BuildSubsetBdd(dd, f, size, visitedTable, threshold,
388  storeTable, approxTable);
389  if (subset != NULL) {
390  cuddRef(subset);
391  }
392 
393  stGen = st__init_gen(approxTable);
394  if (stGen == NULL) {
395  st__free_table(approxTable);
396  return(NULL);
397  }
398  while( st__gen(stGen, (const char **)&key, (char **)&value)) {
399  Cudd_RecursiveDeref(dd, (DdNode *)value);
400  }
401  st__free_gen(stGen); stGen = NULL;
402  st__free_table(approxTable);
403 
404  stGen = st__init_gen(storeTable);
405  if (stGen == NULL) {
406  st__free_table(storeTable);
407  return(NULL);
408  }
409  while( st__gen(stGen, (const char **)&key, (char **)&value)) {
410  Cudd_RecursiveDeref(dd, (DdNode *)key);
411  }
412  st__free_gen(stGen); stGen = NULL;
413  st__free_table(storeTable);
414 
415  for (i = 0; i <= page; i++) {
417  }
419  for (i = 0; i <= page; i++) {
420  ABC_FREE(nodePages[i]);
421  }
423  for (i = 0; i <= page; i++) {
425  }
427  for (i = 0; i <= nodeDataPage; i++) {
429  }
431  st__free_table(visitedTable);
432  ABC_FREE(size);
433 #if 0
434  (void) Cudd_DebugCheck(dd);
435  (void) Cudd_CheckKeys(dd);
436 #endif
437 
438  if (subset != NULL) {
439 #ifdef DD_DEBUG
440  if (!Cudd_bddLeq(dd, subset, f)) {
441  fprintf(dd->err, "Wrong subset\n");
443  return(NULL);
444  }
445 #endif
446  cuddDeref(subset);
447  return(subset);
448  } else {
449  return(NULL);
450  }
451 } /* end of cuddSubsetHeavyBranch */
void st__free_table(st__table *table)
Definition: st.c:81
#define cuddRef(n)
Definition: cuddInt.h:584
static int SubsetCountNodes(DdNode *node, st__table *table, int nvars)
#define cuddDeref(n)
Definition: cuddInt.h:604
static int ** nodePages
Definition: cuddSubsetHB.c:130
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
static int page
Definition: cuddSubsetHB.c:142
static DdNode * zero
Definition: cuddSubsetHB.c:128
void st__free_gen(st__generator *gen)
Definition: st.c:556
int st__insert(st__table *table, const char *key, char *value)
Definition: st.c:171
#define Cudd_IsConstant(node)
Definition: cudd.h:352
static int ** lightNodePages
Definition: cuddSubsetHB.c:131
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
FILE * err
Definition: cuddInt.h:442
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static DdNode * one
Definition: cuddSubsetHB.c:128
static DdNode * BuildSubsetBdd(DdManager *dd, DdNode *node, int *size, st__table *visitedTable, int threshold, st__table *storeTable, st__table *approxTable)
static st__table * SubsetCountMinterm(DdNode *node, int nvars)
Definition: cuddSubsetHB.c:791
#define NIL(type)
Definition: avl.h:25
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
FILE * out
Definition: cuddInt.h:441
Definition: st.h:52
static double max
Definition: cuddSubsetHB.c:134
static double ** mintermPages
Definition: cuddSubsetHB.c:129
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:142
static int size
Definition: cuddSign.c:86
st__generator * st__init_gen(st__table *table)
Definition: st.c:486
#define st__OUT_OF_MEM
Definition: st.h:113
static int nodeDataPage
Definition: cuddSubsetHB.c:148
DdNode * Cudd_ReadOne(DdManager *dd)
Definition: cuddAPI.c:987
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
static NodeData_t ** nodeDataPages
Definition: cuddSubsetHB.c:150
#define ABC_FREE(obj)
Definition: abc_global.h:232
enum keys key
int Cudd_CheckKeys(DdManager *table)
Definition: cuddCheck.c:458
#define DBL_MAX_EXP
Definition: cuddSubsetHB.c:74
int value
static int memOut
Definition: cuddSubsetHB.c:123
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
int st__ptrhash(const char *, int)
Definition: st.c:468
int st__gen(st__generator *gen, const char **key_p, char **value_p)
Definition: st.c:502
DdNode* cuddSubsetShortPaths ( DdManager dd,
DdNode f,
int  numVars,
int  threshold,
int  hardlimit 
)

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

Synopsis [The outermost procedure to return a subset of the given BDD with the shortest path lengths.]

Description [The outermost procedure to return a subset of the given BDD with the largest cubes. The path lengths are calculated, the maximum allowable path length is determined and the number of nodes of this path length that can be used to build a subset. If the threshold is larger than the size of the original BDD, the original BDD is returned. ]

SideEffects [None]

SeeAlso [Cudd_SubsetShortPaths]

Definition at line 316 of file cuddSubsetSP.c.

322 {
323  st__table *pathTable;
324  DdNode *N, *subset;
325 
326  unsigned int *pathLengthArray;
327  unsigned int maxpath, oddLen, evenLen, pathLength, *excess;
328  int i;
329  NodeDist_t *nodeStat;
330  struct AssortedInfo *info;
331  st__table *subsetNodeTable;
332 
333  one = DD_ONE(dd);
334  zero = Cudd_Not(one);
335 
336  if (numVars == 0) {
337  /* set default value */
338  numVars = Cudd_ReadSize(dd);
339  }
340 
341  if (threshold > numVars) {
342  threshold = threshold - numVars;
343  }
344  if (f == NULL) {
345  fprintf(dd->err, "Cannot partition, nil object\n");
347  return(NULL);
348  }
349  if (Cudd_IsConstant(f))
350  return (f);
351 
352  pathLengthArray = ABC_ALLOC(unsigned int, numVars+1);
353  for (i = 0; i < numVars+1; i++) pathLengthArray[i] = 0;
354 
355 
356 #ifdef DD_DEBUG
357  numCalls = 0;
358 #endif
359 
360  pathTable = CreatePathTable(f, pathLengthArray, dd->err);
361 
362  if ((pathTable == NULL) || (memOut)) {
363  if (pathTable != NULL)
364  st__free_table(pathTable);
365  ABC_FREE(pathLengthArray);
366  return (NIL(DdNode));
367  }
368 
369  excess = ABC_ALLOC(unsigned int, 1);
370  *excess = 0;
371  maxpath = AssessPathLength(pathLengthArray, threshold, numVars, excess,
372  dd->err);
373 
374  if (maxpath != (unsigned) (numVars + 1)) {
375 
376  info = ABC_ALLOC(struct AssortedInfo, 1);
377  info->maxpath = maxpath;
378  info->findShortestPath = 0;
379  info->thresholdReached = *excess;
381  info->threshold = threshold;
382 
383 #ifdef DD_DEBUG
384  (void) fprintf(dd->out, "Path length array\n");
385  for (i = 0; i < (numVars+1); i++) {
386  if (pathLengthArray[i])
387  (void) fprintf(dd->out, "%d ",i);
388  }
389  (void) fprintf(dd->out, "\n");
390  for (i = 0; i < (numVars+1); i++) {
391  if (pathLengthArray[i])
392  (void) fprintf(dd->out, "%d ",pathLengthArray[i]);
393  }
394  (void) fprintf(dd->out, "\n");
395  (void) fprintf(dd->out, "Maxpath = %d, Thresholdreached = %d\n",
396  maxpath, info->thresholdReached);
397 #endif
398 
399  N = Cudd_Regular(f);
400  if (! st__lookup(pathTable, (const char *)N, (char **)&nodeStat)) {
401  fprintf(dd->err, "Something wrong, root node must be in table\n");
403  ABC_FREE(excess);
404  ABC_FREE(info);
405  return(NULL);
406  } else {
407  if ((nodeStat->oddTopDist != MAXSHORTINT) &&
408  (nodeStat->oddBotDist != MAXSHORTINT))
409  oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist);
410  else
411  oddLen = MAXSHORTINT;
412 
413  if ((nodeStat->evenTopDist != MAXSHORTINT) &&
414  (nodeStat->evenBotDist != MAXSHORTINT))
415  evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist);
416  else
417  evenLen = MAXSHORTINT;
418 
419  pathLength = (oddLen <= evenLen) ? oddLen : evenLen;
420  if (pathLength > maxpath) {
421  (void) fprintf(dd->err, "All computations are bogus, since root has path length greater than max path length within threshold %u, %u\n", maxpath, pathLength);
423  return(NULL);
424  }
425  }
426 
427 #ifdef DD_DEBUG
428  numCalls = 0;
429  hits = 0;
430  thishit = 0;
431 #endif
432  /* initialize a table to store computed nodes */
433  if (hardlimit) {
434  subsetNodeTable = st__init_table( st__ptrcmp, st__ptrhash);
435  } else {
436  subsetNodeTable = NIL( st__table);
437  }
438  subset = BuildSubsetBdd(dd, pathTable, f, info, subsetNodeTable);
439  if (subset != NULL) {
440  cuddRef(subset);
441  }
442  /* record the number of times a computed result for a node is hit */
443 
444 #ifdef DD_DEBUG
445  (void) fprintf(dd->out, "Hits = %d, New==Node = %d, NumCalls = %d\n",
446  hits, thishit, numCalls);
447 #endif
448 
449  if (subsetNodeTable != NIL( st__table)) {
450  st__free_table(subsetNodeTable);
451  }
453  st__foreach(pathTable, stPathTableDdFree, (char *)dd);
454 
455  ABC_FREE(info);
456 
457  } else {/* if threshold larger than size of dd */
458  subset = f;
459  cuddRef(subset);
460  }
461  ABC_FREE(excess);
462  st__free_table(pathTable);
463  ABC_FREE(pathLengthArray);
464  for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]);
466 
467 #ifdef DD_DEBUG
468  /* check containment of subset in f */
469  if (subset != NULL) {
470  DdNode *check;
471  check = Cudd_bddIteConstant(dd, subset, f, one);
472  if (check != one) {
473  (void) fprintf(dd->err, "Wrong partition\n");
475  return(NULL);
476  }
477  }
478 #endif
479 
480  if (subset != NULL) {
481  cuddDeref(subset);
482  return(subset);
483  } else {
484  return(NULL);
485  }
486 
487 } /* end of cuddSubsetShortPaths */
DdHalfWord oddBotDist
Definition: cuddSubsetSP.c:103
void st__free_table(st__table *table)
Definition: st.c:81
#define cuddRef(n)
Definition: cuddInt.h:584
static DdNode * zero
Definition: cuddSubsetSP.c:140
#define cuddDeref(n)
Definition: cuddInt.h:604
st__table * maxpathTable
Definition: cuddSubsetSP.c:114
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
#define Cudd_IsConstant(node)
Definition: cudd.h:352
#define Cudd_Regular(node)
Definition: cudd.h:397
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
FILE * err
Definition: cuddInt.h:442
static int memOut
Definition: cuddSubsetSP.c:139
DdHalfWord oddTopDist
Definition: cuddSubsetSP.c:101
#define MAXSHORTINT
Definition: cuddSubsetSP.c:84
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int Cudd_ReadSize(DdManager *dd)
Definition: cuddAPI.c:1441
#define NIL(type)
Definition: avl.h:25
static void check(int expr)
Definition: satSolver.c:46
DdNode * Cudd_bddIteConstant(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:174
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
unsigned int maxpath
Definition: cuddSubsetSP.c:111
FILE * out
Definition: cuddInt.h:441
Definition: st.h:52
int thresholdReached
Definition: cuddSubsetSP.c:113
int st__foreach(st__table *table, enum st__retval(*func)(char *, char *, char *), char *arg)
Definition: st.c:421
static int nodeDistPage
Definition: cuddSubsetSP.c:144
int findShortestPath
Definition: cuddSubsetSP.c:112
static enum st__retval stPathTableDdFree(char *key, char *value, char *arg)
DdHalfWord evenBotDist
Definition: cuddSubsetSP.c:104
int st__lookup(st__table *table, const char *key, char **value)
Definition: st.c:114
static unsigned int AssessPathLength(unsigned int *pathLengthArray, int threshold, int numVars, unsigned int *excess, FILE *fp)
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdHalfWord evenTopDist
Definition: cuddSubsetSP.c:102
#define DD_ONE(dd)
Definition: cuddInt.h:911
static st__table * CreatePathTable(DdNode *node, unsigned int *pathLengthArray, FILE *fp)
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
int st__ptrhash(const char *, int)
Definition: st.c:468
static DdNode * one
Definition: cuddSubsetSP.c:140
static NodeDist_t ** nodeDistPages
Definition: cuddSubsetSP.c:142
static DdNode * BuildSubsetBdd(DdManager *dd, st__table *pathTable, DdNode *node, struct AssortedInfo *info, st__table *subsetNodeTable)
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 761 of file cuddReorder.c.

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

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

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

326 {
327  int i;
328  int *var;
329  int size;
330  int x;
331  int result;
332  int symvars;
333  int symgroups;
334 #ifdef DD_STATS
335  int previousSize;
336 #endif
337 
338  size = table->size;
339 
340  /* Find order in which to sift variables. */
341  var = NULL;
342  entry = ABC_ALLOC(int,size);
343  if (entry == NULL) {
344  table->errorCode = CUDD_MEMORY_OUT;
345  goto ddSymmSiftingOutOfMem;
346  }
347  var = ABC_ALLOC(int,size);
348  if (var == NULL) {
349  table->errorCode = CUDD_MEMORY_OUT;
350  goto ddSymmSiftingOutOfMem;
351  }
352 
353  for (i = 0; i < size; i++) {
354  x = table->perm[i];
355  entry[i] = table->subtables[x].keys;
356  var[i] = i;
357  }
358 
359  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare);
360 
361  /* Initialize the symmetry of each subtable to itself. */
362  for (i = lower; i <= upper; i++) {
363  table->subtables[i].next = i;
364  }
365 
366  for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
367  if (ddTotalNumberSwapping >= table->siftMaxSwap)
368  break;
369  // enable timeout during variable reodering - alanmi 2/13/11
370  if ( table->TimeStop && Abc_Clock() > table->TimeStop )
371  break;
372  x = table->perm[var[i]];
373 #ifdef DD_STATS
374  previousSize = table->keys - table->isolated;
375 #endif
376  if (x < lower || x > upper) continue;
377  if (table->subtables[x].next == (unsigned) x) {
378  result = ddSymmSiftingAux(table,x,lower,upper);
379  if (!result) goto ddSymmSiftingOutOfMem;
380 #ifdef DD_STATS
381  if (table->keys < (unsigned) previousSize + table->isolated) {
382  (void) fprintf(table->out,"-");
383  } else if (table->keys > (unsigned) previousSize +
384  table->isolated) {
385  (void) fprintf(table->out,"+"); /* should never happen */
386  } else {
387  (void) fprintf(table->out,"=");
388  }
389  fflush(table->out);
390 #endif
391  }
392  }
393 
394  ABC_FREE(var);
395  ABC_FREE(entry);
396 
397  ddSymmSummary(table, lower, upper, &symvars, &symgroups);
398 
399 #ifdef DD_STATS
400  (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n",
401  symvars);
402  (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups",
403  symgroups);
404 #endif
405 
406  return(1+symvars);
407 
408 ddSymmSiftingOutOfMem:
409 
410  if (entry != NULL) ABC_FREE(entry);
411  if (var != NULL) ABC_FREE(var);
412 
413  return(0);
414 
415 } /* end of cuddSymmSifting */
unsigned int keys
Definition: cuddInt.h:330
abctime TimeStop
Definition: cuddInt.h:489
static int * entry
Definition: cuddSymmetry.c:97
int siftMaxSwap
Definition: cuddInt.h:412
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:326
int size
Definition: cuddInt.h:361
int var(Lit p)
Definition: SolverTypes.h:62
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdSubtable * subtables
Definition: cuddInt.h:365
static abctime Abc_Clock()
Definition: abc_global.h:279
unsigned int keys
Definition: cuddInt.h:369
FILE * out
Definition: cuddInt.h:441
static void ddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
static int size
Definition: cuddSign.c:86
#define ddMin(x, y)
Definition: cuddInt.h:818
int siftMaxVar
Definition: cuddInt.h:411
#define ABC_FREE(obj)
Definition: abc_global.h:232
int ddTotalNumberSwapping
Definition: cuddReorder.c:107
unsigned int next
Definition: cuddInt.h:333
static int result
Definition: cuddGenetic.c:125
int isolated
Definition: cuddInt.h:385
static int ddSymmUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddSymmetry.c:608
int * perm
Definition: cuddInt.h:386
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
static int ddSymmSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddSymmetry.c:636
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 442 of file cuddSymmetry.c.

446 {
447  int i;
448  int *var;
449  int size;
450  int x;
451  int result;
452  int symvars;
453  int symgroups;
454  int classes;
455  int initialSize;
456 #ifdef DD_STATS
457  int previousSize;
458 #endif
459 
460  initialSize = table->keys - table->isolated;
461 
462  size = table->size;
463 
464  /* Find order in which to sift variables. */
465  var = NULL;
466  entry = ABC_ALLOC(int,size);
467  if (entry == NULL) {
468  table->errorCode = CUDD_MEMORY_OUT;
469  goto ddSymmSiftingConvOutOfMem;
470  }
471  var = ABC_ALLOC(int,size);
472  if (var == NULL) {
473  table->errorCode = CUDD_MEMORY_OUT;
474  goto ddSymmSiftingConvOutOfMem;
475  }
476 
477  for (i = 0; i < size; i++) {
478  x = table->perm[i];
479  entry[i] = table->subtables[x].keys;
480  var[i] = i;
481  }
482 
483  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare);
484 
485  /* Initialize the symmetry of each subtable to itself
486  ** for first pass of converging symmetric sifting.
487  */
488  for (i = lower; i <= upper; i++) {
489  table->subtables[i].next = i;
490  }
491 
492  for (i = 0; i < ddMin(table->siftMaxVar, table->size); i++) {
493  if (ddTotalNumberSwapping >= table->siftMaxSwap)
494  break;
495  x = table->perm[var[i]];
496  if (x < lower || x > upper) continue;
497  /* Only sift if not in symmetry group already. */
498  if (table->subtables[x].next == (unsigned) x) {
499 #ifdef DD_STATS
500  previousSize = table->keys - table->isolated;
501 #endif
502  result = ddSymmSiftingAux(table,x,lower,upper);
503  if (!result) goto ddSymmSiftingConvOutOfMem;
504 #ifdef DD_STATS
505  if (table->keys < (unsigned) previousSize + table->isolated) {
506  (void) fprintf(table->out,"-");
507  } else if (table->keys > (unsigned) previousSize +
508  table->isolated) {
509  (void) fprintf(table->out,"+");
510  } else {
511  (void) fprintf(table->out,"=");
512  }
513  fflush(table->out);
514 #endif
515  }
516  }
517 
518  /* Sifting now until convergence. */
519  while ((unsigned) initialSize > table->keys - table->isolated) {
520  initialSize = table->keys - table->isolated;
521 #ifdef DD_STATS
522  (void) fprintf(table->out,"\n");
523 #endif
524  /* Here we consider only one representative for each symmetry class. */
525  for (x = lower, classes = 0; x <= upper; x++, classes++) {
526  while ((unsigned) x < table->subtables[x].next) {
527  x = table->subtables[x].next;
528  }
529  /* Here x is the largest index in a group.
530  ** Groups consist of adjacent variables.
531  ** Hence, the next increment of x will move it to a new group.
532  */
533  i = table->invperm[x];
534  entry[i] = table->subtables[x].keys;
535  var[classes] = i;
536  }
537 
538  qsort((void *)var,classes,sizeof(int),(DD_QSFP)ddSymmUniqueCompare);
539 
540  /* Now sift. */
541  for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) {
542  if (ddTotalNumberSwapping >= table->siftMaxSwap)
543  break;
544  x = table->perm[var[i]];
545  if ((unsigned) x >= table->subtables[x].next) {
546 #ifdef DD_STATS
547  previousSize = table->keys - table->isolated;
548 #endif
549  result = ddSymmSiftingConvAux(table,x,lower,upper);
550  if (!result ) goto ddSymmSiftingConvOutOfMem;
551 #ifdef DD_STATS
552  if (table->keys < (unsigned) previousSize + table->isolated) {
553  (void) fprintf(table->out,"-");
554  } else if (table->keys > (unsigned) previousSize +
555  table->isolated) {
556  (void) fprintf(table->out,"+");
557  } else {
558  (void) fprintf(table->out,"=");
559  }
560  fflush(table->out);
561 #endif
562  }
563  } /* for */
564  }
565 
566  ddSymmSummary(table, lower, upper, &symvars, &symgroups);
567 
568 #ifdef DD_STATS
569  (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n",
570  symvars);
571  (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups",
572  symgroups);
573 #endif
574 
575  ABC_FREE(var);
576  ABC_FREE(entry);
577 
578  return(1+symvars);
579 
580 ddSymmSiftingConvOutOfMem:
581 
582  if (entry != NULL) ABC_FREE(entry);
583  if (var != NULL) ABC_FREE(var);
584 
585  return(0);
586 
587 } /* end of cuddSymmSiftingConv */
unsigned int keys
Definition: cuddInt.h:330
static int * entry
Definition: cuddSymmetry.c:97
int siftMaxSwap
Definition: cuddInt.h:412
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:326
int size
Definition: cuddInt.h:361
int var(Lit p)
Definition: SolverTypes.h:62
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdSubtable * subtables
Definition: cuddInt.h:365
unsigned int keys
Definition: cuddInt.h:369
FILE * out
Definition: cuddInt.h:441
static void ddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
static int size
Definition: cuddSign.c:86
#define ddMin(x, y)
Definition: cuddInt.h:818
static int ddSymmSiftingConvAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddSymmetry.c:938
int siftMaxVar
Definition: cuddInt.h:411
#define ABC_FREE(obj)
Definition: abc_global.h:232
int ddTotalNumberSwapping
Definition: cuddReorder.c:107
unsigned int next
Definition: cuddInt.h:333
int * invperm
Definition: cuddInt.h:388
static int result
Definition: cuddGenetic.c:125
int isolated
Definition: cuddInt.h:385
static int ddSymmUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddSymmetry.c:608
int * perm
Definition: cuddInt.h:386
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
static int ddSymmSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddSymmetry.c:636
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 191 of file cuddInteract.c.

195 {
196  int posn, word, bit, result;
197 
198  if (x > y) {
199  int tmp = x;
200  x = y;
201  y = tmp;
202  }
203 #ifdef DD_DEBUG
204  assert(x < y);
205  assert(y < table->size);
206  assert(x >= 0);
207 #endif
208 
209  posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1;
210  word = posn >> LOGBPL;
211  bit = posn & (BPL-1);
212  result = (table->interact[word] >> bit) & 1L;
213  return(result);
214 
215 } /* end of cuddTestInteract */
int size
Definition: cuddInt.h:361
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
long * interact
Definition: cuddInt.h:394
static int size
Definition: cuddSign.c:86
#define BPL
Definition: cuddInteract.c:92
#define assert(ex)
Definition: util_old.h:213
static int result
Definition: cuddGenetic.c:125
#define LOGBPL
Definition: cuddInteract.c:93
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 793 of file cuddRef.c.

796 {
797  int count = 0;
798 #ifndef DD_NO_DEATH_ROW
799  int i;
800 
801  for (i = 0; i < dd->deathRowDepth; i++) {
802  count += f == dd->deathRow[i];
803  }
804 #endif
805 
806  return(count);
807 
808 } /* end of cuddTimesInDeathRow */
DdNode ** deathRow
Definition: cuddInt.h:401
int deathRowDepth
Definition: cuddInt.h:402
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 274 of file cuddGroup.c.

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

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

Synopsis [Applies Tom Shiple's underappoximation algorithm.]

Description [Applies Tom Shiple's underappoximation algorithm. Proceeds in three phases:

  • collect information on each node in the BDD; this is done via DFS.
  • traverse the BDD in top-down fashion and compute for each node whether its elimination increases density.
  • traverse the BDD via DFS and actually perform the elimination.

Returns the approximated BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_UnderApprox]

Definition at line 511 of file cuddApprox.c.

518 {
519  ApproxInfo *info;
520  DdNode *subset;
521  int result;
522 
523  if (f == NULL) {
524  fprintf(dd->err, "Cannot subset, nil object\n");
525  return(NULL);
526  }
527 
528  if (Cudd_IsConstant(f)) {
529  return(f);
530  }
531 
532  /* Create table where node data are accessible via a hash table. */
533  info = gatherInfo(dd, f, numVars, safe);
534  if (info == NULL) {
535  (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
537  return(NULL);
538  }
539 
540  /* Mark nodes that should be replaced by zero. */
541  result = UAmarkNodes(dd, f, info, threshold, safe, quality);
542  if (result == 0) {
543  (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n");
544  ABC_FREE(info->page);
545  st__free_table(info->table);
546  ABC_FREE(info);
548  return(NULL);
549  }
550 
551  /* Build the result. */
552  subset = UAbuildSubset(dd, f, info);
553 #if 1
554  if (subset && info->size < Cudd_DagSize(subset))
555  (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n",
556  info->size, Cudd_DagSize(subset));
557 #endif
558  ABC_FREE(info->page);
559  st__free_table(info->table);
560  ABC_FREE(info);
561 
562 #ifdef DD_DEBUG
563  if (subset != NULL) {
564  cuddRef(subset);
565 #if 0
566  (void) Cudd_DebugCheck(dd);
567  (void) Cudd_CheckKeys(dd);
568 #endif
569  if (!Cudd_bddLeq(dd, subset, f)) {
570  (void) fprintf(dd->err, "Wrong subset\n");
572  }
573  cuddDeref(subset);
574  }
575 #endif
576  return(subset);
577 
578 } /* end of cuddUnderApprox */
void st__free_table(st__table *table)
Definition: st.c:81
#define cuddRef(n)
Definition: cuddInt.h:584
static int UAmarkNodes(DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, int safe, double quality)
Definition: cuddApprox.c:1152
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
#define Cudd_IsConstant(node)
Definition: cudd.h:352
FILE * err
Definition: cuddInt.h:442
static DdNode * UAbuildSubset(DdManager *dd, DdNode *node, ApproxInfo *info)
Definition: cuddApprox.c:1276
static ApproxInfo * gatherInfo(DdManager *dd, DdNode *node, int numVars, int parity)
Definition: cuddApprox.c:907
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:142
st__table * table
Definition: cuddApprox.c:135
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
#define ABC_FREE(obj)
Definition: abc_global.h:232
int Cudd_CheckKeys(DdManager *table)
Definition: cuddCheck.c:458
NodeData * page
Definition: cuddApprox.c:134
static int result
Definition: cuddGenetic.c:125
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
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 1450 of file cuddTable.c.

1453 {
1454  int pos;
1455  DdNodePtr *nodelist;
1456  DdNode *looking;
1457  hack split;
1458 
1459 #ifdef DD_UNIQUE_PROFILE
1460  unique->uniqueLookUps++;
1461 #endif
1462 
1463  if (unique->constants.keys > unique->constants.maxKeys) {
1464  if (unique->gcEnabled && ((unique->dead > unique->minDead) ||
1465  (10 * unique->constants.dead > 9 * unique->constants.keys))) { /* too many dead */
1466  (void) cuddGarbageCollect(unique,1);
1467  } else {
1468  cuddRehash(unique,CUDD_CONST_INDEX);
1469  }
1470  }
1471 
1472  cuddAdjust(value); /* for the case of crippled infinities */
1473 
1474  if (ddAbs(value) < unique->epsilon) {
1475  value = 0.0;
1476  }
1477  split.value = value;
1478 
1479  pos = ddHash(split.bits[0], split.bits[1], unique->constants.shift);
1480  nodelist = unique->constants.nodelist;
1481  looking = nodelist[pos];
1482 
1483  /* Here we compare values both for equality and for difference less
1484  * than epsilon. The first comparison is required when values are
1485  * infinite, since Infinity - Infinity is NaN and NaN < X is 0 for
1486  * every X.
1487  */
1488  while (looking != NULL) {
1489  if (looking->type.value == value ||
1490  ddEqualVal(looking->type.value,value,unique->epsilon)) {
1491  if (looking->ref == 0) {
1492  cuddReclaim(unique,looking);
1493  }
1494  return(looking);
1495  }
1496  looking = looking->next;
1497 #ifdef DD_UNIQUE_PROFILE
1498  unique->uniqueLinks++;
1499 #endif
1500  }
1501 
1502  unique->keys++;
1503  unique->constants.keys++;
1504 
1505  looking = cuddAllocNode(unique);
1506  if (looking == NULL) return(NULL);
1507  looking->index = CUDD_CONST_INDEX;
1508  looking->type.value = value;
1509  looking->next = nodelist[pos];
1510  nodelist[pos] = looking;
1511 
1512  return(looking);
1513 
1514 } /* end of cuddUniqueConst */
DdHalfWord ref
Definition: cudd.h:280
unsigned int keys
Definition: cuddInt.h:330
#define ddHash(f, g, s)
Definition: cuddInt.h:737
Definition: cudd.h:278
unsigned int bits[2]
Definition: cuddTable.c:112
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddRef.c:584
bool pos
Definition: globals.c:30
unsigned int dead
Definition: cuddInt.h:371
CUDD_VALUE_TYPE value
Definition: cudd.h:283
unsigned int keys
Definition: cuddInt.h:369
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:729
unsigned int dead
Definition: cuddInt.h:332
DdNode * next
Definition: cudd.h:281
#define ddAbs(x)
Definition: cuddInt.h:846
void cuddRehash(DdManager *unique, int i)
Definition: cuddTable.c:1530
unsigned int maxKeys
Definition: cuddInt.h:331
int gcEnabled
Definition: cuddInt.h:376
#define CUDD_CONST_INDEX
Definition: cudd.h:117
DdNode ** nodelist
Definition: cuddInt.h:327
CUDD_VALUE_TYPE value
Definition: cuddTable.c:111
#define ddEqualVal(x, y, e)
Definition: cuddInt.h:861
union DdNode::@29 type
DdHalfWord index
Definition: cudd.h:279
CUDD_VALUE_TYPE epsilon
Definition: cuddInt.h:407
int value
DdSubtable constants
Definition: cuddInt.h:367
#define cuddAdjust(x)
Definition: cuddInt.h:979
int shift
Definition: cuddInt.h:328
DdNode * cuddAllocNode(DdManager *unique)
Definition: cuddTable.c:235
unsigned int minDead
Definition: cuddInt.h:374
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 1128 of file cuddTable.c.

1133 {
1134  int pos;
1135  unsigned int level;
1136  int retval;
1137  DdNodePtr *nodelist;
1138  DdNode *looking;
1139  DdNodePtr *previousP;
1140  DdSubtable *subtable;
1141  int gcNumber;
1142 
1143 #ifdef DD_UNIQUE_PROFILE
1144  unique->uniqueLookUps++;
1145 #endif
1146 
1147  if (index >= unique->size) {
1148  if (!ddResizeTable(unique,index)) return(NULL);
1149  }
1150 
1151  level = unique->perm[index];
1152  subtable = &(unique->subtables[level]);
1153 
1154 #ifdef DD_DEBUG
1155  assert(level < (unsigned) cuddI(unique,T->index));
1156  assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index));
1157 #endif
1158 
1159  pos = ddHash(cuddF2L(T), cuddF2L(E), subtable->shift);
1160  nodelist = subtable->nodelist;
1161  previousP = &(nodelist[pos]);
1162  looking = *previousP;
1163 
1164  while (T < cuddT(looking)) {
1165  previousP = &(looking->next);
1166  looking = *previousP;
1167 #ifdef DD_UNIQUE_PROFILE
1168  unique->uniqueLinks++;
1169 #endif
1170  }
1171  while (T == cuddT(looking) && E < cuddE(looking)) {
1172  previousP = &(looking->next);
1173  looking = *previousP;
1174 #ifdef DD_UNIQUE_PROFILE
1175  unique->uniqueLinks++;
1176 #endif
1177  }
1178  if (T == cuddT(looking) && E == cuddE(looking)) {
1179  if (looking->ref == 0) {
1180  cuddReclaim(unique,looking);
1181  }
1182  return(looking);
1183  }
1184 
1185  /* countDead is 0 if deads should be counted and ~0 if they should not. */
1186  if (unique->autoDyn &&
1187  unique->keys - (unique->dead & unique->countDead) >= unique->nextDyn) {
1188 #ifdef DD_DEBUG
1189  retval = Cudd_DebugCheck(unique);
1190  if (retval != 0) return(NULL);
1191  retval = Cudd_CheckKeys(unique);
1192  if (retval != 0) return(NULL);
1193 #endif
1194  retval = Cudd_ReduceHeap(unique,unique->autoMethod,10); /* 10 = whatever */
1195  if (retval == 0) unique->reordered = 2;
1196 #ifdef DD_DEBUG
1197  retval = Cudd_DebugCheck(unique);
1198  if (retval != 0) unique->reordered = 2;
1199  retval = Cudd_CheckKeys(unique);
1200  if (retval != 0) unique->reordered = 2;
1201 #endif
1202  return(NULL);
1203  }
1204 
1205  if (subtable->keys > subtable->maxKeys) {
1206  if (unique->gcEnabled &&
1207  ((unique->dead > unique->minDead) ||
1208  ((unique->dead > unique->minDead / 2) &&
1209  (subtable->dead > subtable->keys * 0.95)))) { /* too many dead */
1210  (void) cuddGarbageCollect(unique,1);
1211  } else {
1212  cuddRehash(unique,(int)level);
1213  }
1214  /* Update pointer to insertion point. In the case of rehashing,
1215  ** the slot may have changed. In the case of garbage collection,
1216  ** the predecessor may have been dead. */
1217  pos = ddHash(cuddF2L(T), cuddF2L(E), subtable->shift);
1218  nodelist = subtable->nodelist;
1219  previousP = &(nodelist[pos]);
1220  looking = *previousP;
1221 
1222  while (T < cuddT(looking)) {
1223  previousP = &(looking->next);
1224  looking = *previousP;
1225 #ifdef DD_UNIQUE_PROFILE
1226  unique->uniqueLinks++;
1227 #endif
1228  }
1229  while (T == cuddT(looking) && E < cuddE(looking)) {
1230  previousP = &(looking->next);
1231  looking = *previousP;
1232 #ifdef DD_UNIQUE_PROFILE
1233  unique->uniqueLinks++;
1234 #endif
1235  }
1236  }
1237 
1238  gcNumber = unique->garbageCollections;
1239  looking = cuddAllocNode(unique);
1240  if (looking == NULL) {
1241  return(NULL);
1242  }
1243  unique->keys++;
1244  subtable->keys++;
1245 
1246  if (gcNumber != unique->garbageCollections) {
1247  DdNode *looking2;
1248  pos = ddHash(cuddF2L(T), cuddF2L(E), subtable->shift);
1249  nodelist = subtable->nodelist;
1250  previousP = &(nodelist[pos]);
1251  looking2 = *previousP;
1252 
1253  while (T < cuddT(looking2)) {
1254  previousP = &(looking2->next);
1255  looking2 = *previousP;
1256 #ifdef DD_UNIQUE_PROFILE
1257  unique->uniqueLinks++;
1258 #endif
1259  }
1260  while (T == cuddT(looking2) && E < cuddE(looking2)) {
1261  previousP = &(looking2->next);
1262  looking2 = *previousP;
1263 #ifdef DD_UNIQUE_PROFILE
1264  unique->uniqueLinks++;
1265 #endif
1266  }
1267  }
1268  looking->index = index;
1269  cuddT(looking) = T;
1270  cuddE(looking) = E;
1271  looking->next = *previousP;
1272  *previousP = looking;
1273  cuddSatInc(T->ref); /* we know T is a regular pointer */
1274  cuddRef(E);
1275 
1276 #ifdef DD_DEBUG
1277  cuddCheckCollisionOrdering(unique,level,pos);
1278 #endif
1279 
1280 // assert( Cudd_Regular(T)->Id < 100000000 );
1281 // assert( Cudd_Regular(E)->Id < 100000000 );
1282  return(looking);
1283 
1284 } /* end of cuddUniqueInter */
DdHalfWord ref
Definition: cudd.h:280
#define cuddRef(n)
Definition: cuddInt.h:584
unsigned int keys
Definition: cuddInt.h:330
#define ddHash(f, g, s)
Definition: cuddInt.h:737
Cudd_ReorderingType autoMethod
Definition: cuddInt.h:418
Definition: cudd.h:278
int size
Definition: cuddInt.h:361
#define Cudd_Regular(node)
Definition: cudd.h:397
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddRef.c:584
bool pos
Definition: globals.c:30
int garbageCollections
Definition: cuddInt.h:452
DdSubtable * subtables
Definition: cuddInt.h:365
unsigned int countDead
Definition: cuddInt.h:423
int reordered
Definition: cuddInt.h:409
unsigned int nextDyn
Definition: cuddInt.h:422
unsigned int dead
Definition: cuddInt.h:371
unsigned int keys
Definition: cuddInt.h:369
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:729
unsigned int dead
Definition: cuddInt.h:332
DdNode * next
Definition: cudd.h:281
void cuddRehash(DdManager *unique, int i)
Definition: cuddTable.c:1530
unsigned int maxKeys
Definition: cuddInt.h:331
int gcEnabled
Definition: cuddInt.h:376
DdNode ** nodelist
Definition: cuddInt.h:327
static int ddResizeTable(DdManager *unique, int index)
Definition: cuddTable.c:2523
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:142
#define cuddF2L(f)
Definition: cuddInt.h:718
#define cuddT(node)
Definition: cuddInt.h:636
#define cuddI(dd, index)
Definition: cuddInt.h:686
DdHalfWord index
Definition: cudd.h:279
int Cudd_CheckKeys(DdManager *table)
Definition: cuddCheck.c:458
#define cuddE(node)
Definition: cuddInt.h:652
#define assert(ex)
Definition: util_old.h:213
int Cudd_ReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
Definition: cuddReorder.c:176
int autoDyn
Definition: cuddInt.h:416
int shift
Definition: cuddInt.h:328
int * perm
Definition: cuddInt.h:386
DdNode * cuddAllocNode(DdManager *unique)
Definition: cuddTable.c:235
unsigned int minDead
Definition: cuddInt.h:374
#define cuddSatInc(x)
Definition: cuddInt.h:878
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 1304 of file cuddTable.c.

1309 {
1310  DdNode *result;
1311  DdNode *v;
1312 
1313  v = cuddUniqueInter(unique, index, DD_ONE(unique),
1314  Cudd_Not(DD_ONE(unique)));
1315  if (v == NULL)
1316  return(NULL);
1317  cuddRef(v);
1318  result = cuddBddIteRecur(unique, v, T, E);
1319  Cudd_RecursiveDeref(unique, v);
1320  return(result);
1321 }
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
static int result
Definition: cuddGenetic.c:125
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1128
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddBddIte.c:633
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 1343 of file cuddTable.c.

1348 {
1349  int pos;
1350  unsigned int level;
1351  int retval;
1352  DdNodePtr *nodelist;
1353  DdNode *looking;
1354  DdSubtable *subtable;
1355 
1356 #ifdef DD_UNIQUE_PROFILE
1357  unique->uniqueLookUps++;
1358 #endif
1359 
1360  if (index >= unique->sizeZ) {
1361  if (!cuddResizeTableZdd(unique,index)) return(NULL);
1362  }
1363 
1364  level = unique->permZ[index];
1365  subtable = &(unique->subtableZ[level]);
1366 
1367 #ifdef DD_DEBUG
1368  assert(level < (unsigned) cuddIZ(unique,T->index));
1369  assert(level < (unsigned) cuddIZ(unique,Cudd_Regular(E)->index));
1370 #endif
1371 
1372  if (subtable->keys > subtable->maxKeys) {
1373  if (unique->gcEnabled && ((unique->deadZ > unique->minDead) ||
1374  (10 * subtable->dead > 9 * subtable->keys))) { /* too many dead */
1375  (void) cuddGarbageCollect(unique,1);
1376  } else {
1377  ddRehashZdd(unique,(int)level);
1378  }
1379  }
1380 
1381  pos = ddHash(cuddF2L(T), cuddF2L(E), subtable->shift);
1382  nodelist = subtable->nodelist;
1383  looking = nodelist[pos];
1384 
1385  while (looking != NULL) {
1386  if (cuddT(looking) == T && cuddE(looking) == E) {
1387  if (looking->ref == 0) {
1388  cuddReclaimZdd(unique,looking);
1389  }
1390  return(looking);
1391  }
1392  looking = looking->next;
1393 #ifdef DD_UNIQUE_PROFILE
1394  unique->uniqueLinks++;
1395 #endif
1396  }
1397 
1398  /* countDead is 0 if deads should be counted and ~0 if they should not. */
1399  if (unique->autoDynZ &&
1400  unique->keysZ - (unique->deadZ & unique->countDead) >= unique->nextDyn) {
1401 #ifdef DD_DEBUG
1402  retval = Cudd_DebugCheck(unique);
1403  if (retval != 0) return(NULL);
1404  retval = Cudd_CheckKeys(unique);
1405  if (retval != 0) return(NULL);
1406 #endif
1407  retval = Cudd_zddReduceHeap(unique,unique->autoMethodZ,10); /* 10 = whatever */
1408  if (retval == 0) unique->reordered = 2;
1409 #ifdef DD_DEBUG
1410  retval = Cudd_DebugCheck(unique);
1411  if (retval != 0) unique->reordered = 2;
1412  retval = Cudd_CheckKeys(unique);
1413  if (retval != 0) unique->reordered = 2;
1414 #endif
1415  return(NULL);
1416  }
1417 
1418  unique->keysZ++;
1419  subtable->keys++;
1420 
1421  looking = cuddAllocNode(unique);
1422  if (looking == NULL) return(NULL);
1423  looking->index = index;
1424  cuddT(looking) = T;
1425  cuddE(looking) = E;
1426  looking->next = nodelist[pos];
1427  nodelist[pos] = looking;
1428  cuddRef(T);
1429  cuddRef(E);
1430 
1431  return(looking);
1432 
1433 } /* end of cuddUniqueInterZdd */
DdHalfWord ref
Definition: cudd.h:280
#define cuddRef(n)
Definition: cuddInt.h:584
unsigned int keys
Definition: cuddInt.h:330
#define ddHash(f, g, s)
Definition: cuddInt.h:737
#define cuddIZ(dd, index)
Definition: cuddInt.h:704
Definition: cudd.h:278
unsigned int deadZ
Definition: cuddInt.h:372
#define Cudd_Regular(node)
Definition: cudd.h:397
bool pos
Definition: globals.c:30
Cudd_ReorderingType autoMethodZ
Definition: cuddInt.h:419
int * permZ
Definition: cuddInt.h:387
unsigned int countDead
Definition: cuddInt.h:423
int reordered
Definition: cuddInt.h:409
unsigned int nextDyn
Definition: cuddInt.h:422
int cuddResizeTableZdd(DdManager *unique, int index)
Definition: cuddTable.c:2241
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:729
unsigned int dead
Definition: cuddInt.h:332
DdNode * next
Definition: cudd.h:281
unsigned int maxKeys
Definition: cuddInt.h:331
int gcEnabled
Definition: cuddInt.h:376
DdNode ** nodelist
Definition: cuddInt.h:327
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:142
#define cuddF2L(f)
Definition: cuddInt.h:718
#define cuddT(node)
Definition: cuddInt.h:636
static void ddRehashZdd(DdManager *unique, int i)
Definition: cuddTable.c:2422
void cuddReclaimZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:638
int Cudd_zddReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
Definition: cuddZddReord.c:171
int sizeZ
Definition: cuddInt.h:362
DdHalfWord index
Definition: cudd.h:279
int Cudd_CheckKeys(DdManager *table)
Definition: cuddCheck.c:458
int autoDynZ
Definition: cuddInt.h:417
#define cuddE(node)
Definition: cuddInt.h:652
#define assert(ex)
Definition: util_old.h:213
int shift
Definition: cuddInt.h:328
unsigned int keysZ
Definition: cuddInt.h:370
DdNode * cuddAllocNode(DdManager *unique)
Definition: cuddTable.c:235
unsigned int minDead
Definition: cuddInt.h:374
DdSubtable * subtableZ
Definition: cuddInt.h:366
void cuddUpdateInteractionMatrix ( DdManager table,
int  xindex,
int  yindex 
)

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

Synopsis [Updates the interaction matrix.]

Description []

SideEffects [none]

SeeAlso []

Definition at line 718 of file cuddLinear.c.

722 {
723  int i;
724  for (i = 0; i < yindex; i++) {
725  if (i != xindex && cuddTestInteract(table,i,yindex)) {
726  if (i < xindex) {
727  cuddSetInteract(table,i,xindex);
728  } else {
729  cuddSetInteract(table,xindex,i);
730  }
731  }
732  }
733  for (i = yindex+1; i < table->size; i++) {
734  if (i != xindex && cuddTestInteract(table,yindex,i)) {
735  if (i < xindex) {
736  cuddSetInteract(table,i,xindex);
737  } else {
738  cuddSetInteract(table,xindex,i);
739  }
740  }
741  }
742 
743 } /* end of cuddUpdateInteractionMatrix */
int size
Definition: cuddInt.h:361
void cuddSetInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:156
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:191
DdNode* cuddVerifySol ( DdManager bdd,
DdNode F,
DdNode **  G,
int *  yIndex,
int  n 
)

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

Synopsis [Implements the recursive step of Cudd_VerifySol. ]

Description []

SideEffects [none]

SeeAlso [Cudd_VerifySol]

Definition at line 336 of file cuddSolve.c.

342 {
343  DdNode *w, *R;
344 
345  int j;
346 
347  R = F;
348  cuddRef(R);
349  for(j = n - 1; j >= 0; j--) {
350  w = Cudd_bddCompose(bdd, R, G[j], yIndex[j]);
351  if (w) {
352  cuddRef(w);
353  } else {
354  return(NULL);
355  }
356  Cudd_RecursiveDeref(bdd,R);
357  R = w;
358  }
359 
360  cuddDeref(R);
361 
362  return(R);
363 
364 } /* end of cuddVerifySol */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
DdNode * Cudd_bddCompose(DdManager *dd, DdNode *f, DdNode *g, int v)
Definition: cuddCompose.c:167
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 142 of file cuddWindow.c.

147 {
148 
149  int res;
150 #ifdef DD_DEBUG
151  int supposedOpt;
152 #endif
153 
154  switch (submethod) {
156  res = ddWindow2(table,low,high);
157  break;
159  res = ddWindow3(table,low,high);
160  break;
162  res = ddWindow4(table,low,high);
163  break;
165  res = ddWindowConv2(table,low,high);
166  break;
168  res = ddWindowConv3(table,low,high);
169 #ifdef DD_DEBUG
170  supposedOpt = table->keys - table->isolated;
171  res = ddWindow3(table,low,high);
172  if (table->keys - table->isolated != (unsigned) supposedOpt) {
173  (void) fprintf(table->err, "Convergence failed! (%d != %d)\n",
174  table->keys - table->isolated, supposedOpt);
175  }
176 #endif
177  break;
179  res = ddWindowConv4(table,low,high);
180 #ifdef DD_DEBUG
181  supposedOpt = table->keys - table->isolated;
182  res = ddWindow4(table,low,high);
183  if (table->keys - table->isolated != (unsigned) supposedOpt) {
184  (void) fprintf(table->err,"Convergence failed! (%d != %d)\n",
185  table->keys - table->isolated, supposedOpt);
186  }
187 #endif
188  break;
189  default: return(0);
190  }
191 
192  return(res);
193 
194 } /* end of cuddWindowReorder */
static int ddWindow2(DdManager *table, int low, int high)
Definition: cuddWindow.c:214
static int ddWindow4(DdManager *table, int low, int high)
Definition: cuddWindow.c:857
static int ddWindow3(DdManager *table, int low, int high)
Definition: cuddWindow.c:456
static int ddWindowConv2(DdManager *table, int low, int high)
Definition: cuddWindow.c:268
FILE * err
Definition: cuddInt.h:442
static int ddWindowConv4(DdManager *table, int low, int high)
Definition: cuddWindow.c:904
unsigned int keys
Definition: cuddInt.h:369
int isolated
Definition: cuddInt.h:385
static int ddWindowConv3(DdManager *table, int low, int high)
Definition: cuddWindow.c:503
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 352 of file cuddZddReord.c.

354 {
355  int *invpermZ; /* permutation array */
356  int M; /* ratio of ZDD variables to BDD variables */
357  int i,j; /* loop indices */
358  int result; /* return value */
359 
360  /* We assume that a ratio of 0 is OK. */
361  if (table->sizeZ == 0)
362  return(1);
363 
364  empty = table->zero;
365  M = table->sizeZ / table->size;
366  /* Check whether the number of ZDD variables is a multiple of the
367  ** number of BDD variables.
368  */
369  if (M * table->size != table->sizeZ)
370  return(0);
371  /* Create and initialize the inverse permutation array. */
372  invpermZ = ABC_ALLOC(int,table->sizeZ);
373  if (invpermZ == NULL) {
374  table->errorCode = CUDD_MEMORY_OUT;
375  return(0);
376  }
377  for (i = 0; i < table->size; i++) {
378  int index = table->invperm[i];
379  int indexZ = index * M;
380  int levelZ = table->permZ[indexZ];
381  levelZ = (levelZ / M) * M;
382  for (j = 0; j < M; j++) {
383  invpermZ[M * i + j] = table->invpermZ[levelZ + j];
384  }
385  }
386  /* Eliminate dead nodes. Do not scan the cache again, because we
387  ** assume that Cudd_ReduceHeap has already cleared it.
388  */
389  cuddGarbageCollect(table,0);
390 
391  result = zddShuffle(table, invpermZ);
392  ABC_FREE(invpermZ);
393  /* Fix the ZDD variable group tree. */
394  zddFixTree(table,table->treeZ);
395  return(result);
396 
397 } /* end of cuddZddAlignToBdd */
int * invpermZ
Definition: cuddInt.h:389
int size
Definition: cuddInt.h:361
DdNode * zero
Definition: cuddInt.h:346
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int * permZ
Definition: cuddInt.h:387
word M(word f1, word f2, int n)
Definition: kitPerm.c:240
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddTable.c:729
static DdNode * empty
Definition: cuddZddReord.c:112
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
MtrNode * treeZ
Definition: cuddInt.h:425
int * invperm
Definition: cuddInt.h:388
static int result
Definition: cuddGenetic.c:125
static void zddFixTree(DdManager *table, MtrNode *treenode)
static int zddShuffle(DdManager *table, int *permutation)
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
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 971 of file cuddZddSetop.c.

975 {
976  DdNode *zvar, *res;
977 
978  zvar = cuddUniqueInterZdd(dd, var, DD_ONE(dd), DD_ZERO(dd));
979  if (zvar == NULL) return(NULL);
980  cuddRef(zvar);
981 
982  res = cuddZddChangeAux(dd, P, zvar);
983  if (res == NULL) {
984  Cudd_RecursiveDerefZdd(dd,zvar);
985  return(NULL);
986  }
987  cuddRef(res);
988  Cudd_RecursiveDerefZdd(dd,zvar);
989  cuddDeref(res);
990  return(res);
991 
992 } /* end of cuddZddChange */
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
int var(Lit p)
Definition: SolverTypes.h:62
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1343
DdNode * cuddZddChangeAux(DdManager *zdd, DdNode *P, DdNode *zvar)
Definition: cuddZddSetop.c:799
#define DD_ONE(dd)
Definition: cuddInt.h:911
#define DD_ZERO(dd)
Definition: cuddInt.h:927
DdNode* cuddZddChangeAux ( DdManager zdd,
DdNode P,
DdNode zvar 
)

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

Synopsis [Performs the recursive step of Cudd_zddChange.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 799 of file cuddZddSetop.c.

803 {
804  int top_var, level;
805  DdNode *res, *t, *e;
806  DdNode *base = DD_ONE(zdd);
807  DdNode *empty = DD_ZERO(zdd);
808 
809  statLine(zdd);
810  if (P == empty)
811  return(empty);
812  if (P == base)
813  return(zvar);
814 
815  /* Check cache. */
816  res = cuddCacheLookup2Zdd(zdd, cuddZddChangeAux, P, zvar);
817  if (res != NULL)
818  return(res);
819 
820  top_var = zdd->permZ[P->index];
821  level = zdd->permZ[zvar->index];
822 
823  if (top_var > level) {
824  res = cuddZddGetNode(zdd, zvar->index, P, DD_ZERO(zdd));
825  if (res == NULL) return(NULL);
826  } else if (top_var == level) {
827  res = cuddZddGetNode(zdd, zvar->index, cuddE(P), cuddT(P));
828  if (res == NULL) return(NULL);
829  } else {
830  t = cuddZddChangeAux(zdd, cuddT(P), zvar);
831  if (t == NULL) return(NULL);
832  cuddRef(t);
833  e = cuddZddChangeAux(zdd, cuddE(P), zvar);
834  if (e == NULL) {
835  Cudd_RecursiveDerefZdd(zdd, t);
836  return(NULL);
837  }
838  cuddRef(e);
839  res = cuddZddGetNode(zdd, P->index, t, e);
840  if (res == NULL) {
841  Cudd_RecursiveDerefZdd(zdd, t);
842  Cudd_RecursiveDerefZdd(zdd, e);
843  return(NULL);
844  }
845  cuddDeref(t);
846  cuddDeref(e);
847  }
848 
849  cuddCacheInsert2(zdd, cuddZddChangeAux, P, zvar, res);
850 
851  return(res);
852 
853 } /* end of cuddZddChangeAux */
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:610
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
int * permZ
Definition: cuddInt.h:387
#define statLine(dd)
Definition: cuddInt.h:1037
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * cuddZddChangeAux(DdManager *zdd, DdNode *P, DdNode *zvar)
Definition: cuddZddSetop.c:799
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
static DdNode * empty
Definition: cuddZddLin.c:98
#define DD_ONE(dd)
Definition: cuddInt.h:911
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 1522 of file cuddZddFuncs.c.

1525 {
1526  DdNode *b, *isop, *zdd_I;
1527 
1528  /* Check cache */
1529  zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node);
1530  if (zdd_I)
1531  return(zdd_I);
1532 
1533  b = cuddMakeBddFromZddCover(dd, node);
1534  if (!b)
1535  return(NULL);
1536  cuddRef(b);
1537  isop = cuddZddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I);
1538  if (!isop) {
1539  Cudd_RecursiveDeref(dd, b);
1540  return(NULL);
1541  }
1542  cuddRef(isop);
1543  cuddRef(zdd_I);
1544  Cudd_RecursiveDeref(dd, b);
1545  Cudd_RecursiveDeref(dd, isop);
1546 
1547  cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I);
1548  cuddDeref(zdd_I);
1549  return(zdd_I);
1550 } /* end of cuddZddComplement */
#define cuddRef(n)
Definition: cuddInt.h:584
#define cuddDeref(n)
Definition: cuddInt.h:604
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
DdNode * cuddZddIsop(DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)
Definition: cuddZddIsop.c:234
DdNode * cuddMakeBddFromZddCover(DdManager *dd, DdNode *node)
Definition: cuddZddIsop.c:800
DdNode * cuddZddComplement(DdManager *dd, DdNode *node)
DdNode * cuddCacheLookup1Zdd(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddCache.c:664
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddCache.c:323
DdNode* cuddZddDiff ( DdManager zdd,
DdNode P,
DdNode Q 
)

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

Synopsis [Performs the recursive step of Cudd_zddDiff.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 717 of file cuddZddSetop.c.

721 {
722  int p_top, q_top;
723  DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
724  DdManager *table = zdd;
725 
726  statLine(zdd);
727  if (P == empty)
728  return(empty);
729  if (Q == empty)
730  return(P);
731  if (P == Q)
732  return(empty);
733 
734  /* Check cache. The cache is shared by Cudd_zddDiffConst(). */
735  res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q);
736  if (res != NULL && res != DD_NON_CONSTANT)
737  return(res);
738 
739  if (cuddIsConstant(P))
740  p_top = P->index;
741  else
742  p_top = zdd->permZ[P->index];
743  if (cuddIsConstant(Q))
744  q_top = Q->index;
745  else
746  q_top = zdd->permZ[Q->index];
747  if (p_top < q_top) {
748  e = cuddZddDiff(zdd, cuddE(P), Q);
749  if (e == NULL) return(NULL);
750  cuddRef(e);
751  res = cuddZddGetNode(zdd, P->index, cuddT(P), e);
752  if (res == NULL) {
753  Cudd_RecursiveDerefZdd(table, e);
754  return(NULL);
755  }
756  cuddDeref(e);
757  } else if (p_top > q_top) {
758  res = cuddZddDiff(zdd, P, cuddE(Q));
759  if (res == NULL) return(NULL);
760  } else {
761  t = cuddZddDiff(zdd, cuddT(P), cuddT(Q));
762  if (t == NULL) return(NULL);
763  cuddRef(t);
764  e = cuddZddDiff(zdd, cuddE(P), cuddE(Q));
765  if (e == NULL) {
766  Cudd_RecursiveDerefZdd(table, t);
767  return(NULL);
768  }
769  cuddRef(e);
770  res = cuddZddGetNode(zdd, P->index, t, e);
771  if (res == NULL) {
772  Cudd_RecursiveDerefZdd(table, t);
773  Cudd_RecursiveDerefZdd(table, e);
774  return(NULL);
775  }
776  cuddDeref(t);
777  cuddDeref(e);
778  }
779 
780  cuddCacheInsert2(table, cuddZddDiff, P, Q, res);
781 
782  return(res);
783 
784 } /* end of cuddZddDiff */
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:610
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
int * permZ
Definition: cuddInt.h:387
#define statLine(dd)
Definition: cuddInt.h:1037
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * cuddZddDiff(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:717
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
static DdNode * empty
Definition: cuddZddLin.c:98
#define DD_NON_CONSTANT
Definition: cuddInt.h:123
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 1159 of file cuddZddFuncs.c.

1163 {
1164  int v;
1165  DdNode *one = DD_ONE(dd);
1166  DdNode *zero = DD_ZERO(dd);
1167  DdNode *f0, *f1, *g0, *g1;
1168  DdNode *q, *r, *tmp;
1169  int flag;
1170 
1171  statLine(dd);
1172  if (g == one)
1173  return(f);
1174  if (f == zero || f == one)
1175  return(zero);
1176  if (f == g)
1177  return(one);
1178 
1179  /* Check cache. */
1180  r = cuddCacheLookup2Zdd(dd, cuddZddDivide, f, g);
1181  if (r)
1182  return(r);
1183 
1184  v = g->index;
1185 
1186  flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
1187  if (flag == 1)
1188  return(NULL);
1189  Cudd_Ref(f1);
1190  Cudd_Ref(f0);
1191  flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */
1192  if (flag == 1) {
1193  Cudd_RecursiveDerefZdd(dd, f1);
1194  Cudd_RecursiveDerefZdd(dd, f0);
1195  return(NULL);
1196  }
1197  Cudd_Ref(g1);
1198  Cudd_Ref(g0);
1199 
1200  r = cuddZddDivide(dd, f1, g1);
1201  if (r == NULL) {
1202  Cudd_RecursiveDerefZdd(dd, f1);
1203  Cudd_RecursiveDerefZdd(dd, f0);
1204  Cudd_RecursiveDerefZdd(dd, g1);
1205  Cudd_RecursiveDerefZdd(dd, g0);
1206  return(NULL);
1207  }
1208  Cudd_Ref(r);
1209 
1210  if (r != zero && g0 != zero) {
1211  tmp = r;
1212  q = cuddZddDivide(dd, f0, g0);
1213  if (q == NULL) {
1214  Cudd_RecursiveDerefZdd(dd, f1);
1215  Cudd_RecursiveDerefZdd(dd, f0);
1216  Cudd_RecursiveDerefZdd(dd, g1);
1217  Cudd_RecursiveDerefZdd(dd, g0);
1218  return(NULL);
1219  }
1220  Cudd_Ref(q);
1221  r = cuddZddIntersect(dd, r, q);
1222  if (r == NULL) {
1223  Cudd_RecursiveDerefZdd(dd, f1);
1224  Cudd_RecursiveDerefZdd(dd, f0);
1225  Cudd_RecursiveDerefZdd(dd, g1);
1226  Cudd_RecursiveDerefZdd(dd, g0);
1227  Cudd_RecursiveDerefZdd(dd, q);
1228  return(NULL);
1229  }
1230  Cudd_Ref(r);
1231  Cudd_RecursiveDerefZdd(dd, q);
1232  Cudd_RecursiveDerefZdd(dd, tmp);
1233  }
1234 
1235  Cudd_RecursiveDerefZdd(dd, f1);
1236  Cudd_RecursiveDerefZdd(dd, f0);
1237  Cudd_RecursiveDerefZdd(dd, g1);
1238  Cudd_RecursiveDerefZdd(dd, g0);
1239 
1240  cuddCacheInsert2(dd, cuddZddDivide, f, g, r);
1241  Cudd_Deref(r);
1242  return(r);
1243 
1244 } /* end of cuddZddDivide */
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:610
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
DdNode * cuddZddDivide(DdManager *dd, DdNode *f, DdNode *g)
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
int cuddZddGetCofactors2(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0)
#define statLine(dd)
Definition: cuddInt.h:1037
static DdNode * one
Definition: cuddDecomp.c:112
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:642
DdHalfWord index
Definition: cudd.h:279
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
#define DD_ONE(dd)
Definition: cuddInt.h:911
static DdNode * zero
Definition: cuddApa.c:100
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 1259 of file cuddZddFuncs.c.

1263 {
1264  int v;
1265  DdNode *one = DD_ONE(dd);
1266  DdNode *zero = DD_ZERO(dd);
1267  DdNode *f0, *f1, *g0, *g1;
1268  DdNode *q, *r, *tmp;
1269  int flag;
1270 
1271  statLine(dd);
1272  if (g == one)
1273  return(f);
1274  if (f == zero || f == one)
1275  return(zero);
1276  if (f == g)
1277  return(one);
1278 
1279  /* Check cache. */
1280  r = cuddCacheLookup2Zdd(dd, cuddZddDivideF, f, g);
1281  if (r)
1282  return(r);
1283 
1284  v = g->index;
1285 
1286  flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
1287  if (flag == 1)
1288  return(NULL);
1289  Cudd_Ref(f1);
1290  Cudd_Ref(f0);
1291  flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */
1292  if (flag == 1) {
1293  Cudd_RecursiveDerefZdd(dd, f1);
1294  Cudd_RecursiveDerefZdd(dd, f0);
1295  return(NULL);
1296  }
1297  Cudd_Ref(g1);
1298  Cudd_Ref(g0);
1299 
1300  r = cuddZddDivideF(dd, f1, g1);
1301  if (r == NULL) {
1302  Cudd_RecursiveDerefZdd(dd, f1);
1303  Cudd_RecursiveDerefZdd(dd, f0);
1304  Cudd_RecursiveDerefZdd(dd, g1);
1305  Cudd_RecursiveDerefZdd(dd, g0);
1306  return(NULL);
1307  }
1308  Cudd_Ref(r);
1309 
1310  if (r != zero && g0 != zero) {
1311  tmp = r;
1312  q = cuddZddDivideF(dd, f0, g0);
1313  if (q == NULL) {
1314  Cudd_RecursiveDerefZdd(dd, f1);
1315  Cudd_RecursiveDerefZdd(dd, f0);
1316  Cudd_RecursiveDerefZdd(dd, g1);
1317  Cudd_RecursiveDerefZdd(dd, g0);
1318  return(NULL);
1319  }
1320  Cudd_Ref(q);
1321  r = cuddZddIntersect(dd, r, q);
1322  if (r == NULL) {
1323  Cudd_RecursiveDerefZdd(dd, f1);
1324  Cudd_RecursiveDerefZdd(dd, f0);
1325  Cudd_RecursiveDerefZdd(dd, g1);
1326  Cudd_RecursiveDerefZdd(dd, g0);
1327  Cudd_RecursiveDerefZdd(dd, q);
1328  return(NULL);
1329  }
1330  Cudd_Ref(r);
1331  Cudd_RecursiveDerefZdd(dd, q);
1332  Cudd_RecursiveDerefZdd(dd, tmp);
1333  }
1334 
1335  Cudd_RecursiveDerefZdd(dd, f1);
1336  Cudd_RecursiveDerefZdd(dd, f0);
1337  Cudd_RecursiveDerefZdd(dd, g1);
1338  Cudd_RecursiveDerefZdd(dd, g0);
1339 
1340  cuddCacheInsert2(dd, cuddZddDivideF, f, g, r);
1341  Cudd_Deref(r);
1342  return(r);
1343 
1344 } /* end of cuddZddDivideF */
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:610
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
Definition: cudd.h:278
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
int cuddZddGetCofactors2(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0)
#define statLine(dd)
Definition: cuddInt.h:1037
static DdNode * one
Definition: cuddDecomp.c:112
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:642
DdHalfWord index
Definition: cudd.h:279
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode * cuddZddDivideF(DdManager *dd, DdNode *f, DdNode *g)
static DdNode * zero
Definition: cuddApa.c:100
#define DD_ZERO(dd)
Definition: cuddInt.h:927
void cuddZddFreeUniv ( DdManager zdd)

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

Synopsis [Frees the ZDD universe.]

Description [Frees the ZDD universe.]

SideEffects [None]

SeeAlso [cuddZddInitUniv]

Definition at line 301 of file cuddInit.c.

303 {
304  if (zdd->univ) {
305  Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]);
306  ABC_FREE(zdd->univ);
307  }
308 
309 } /* end of cuddZddFreeUniv */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdNode ** univ
Definition: cuddInt.h:392
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 1487 of file cuddZddFuncs.c.

1493 {
1494  *f1 = cuddZddSubset1(dd, f, v);
1495  if (*f1 == NULL)
1496  return(1);
1497  *f0 = cuddZddSubset0(dd, f, v);
1498  if (*f0 == NULL) {
1499  Cudd_RecursiveDerefZdd(dd, *f1);
1500  return(1);
1501  }
1502  return(0);
1503 
1504 } /* end of cuddZddGetCofactors2 */
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
DdNode * cuddZddSubset1(DdManager *dd, DdNode *P, int var)
Definition: cuddZddSetop.c:874
DdNode * cuddZddSubset0(DdManager *dd, DdNode *P, int var)
Definition: cuddZddSetop.c:923
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 1360 of file cuddZddFuncs.c.

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

1589 {
1590  int nv = index | 0x1;
1591  return(nv);
1592 } /* end of cuddZddGetPosVarIndex */
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 1628 of file cuddZddFuncs.c.

1631 {
1632  int nv = cuddZddGetNegVarIndex(dd, index);
1633  return(dd->permZ[nv]);
1634 } /* end of cuddZddGetNegVarLevel */
int * permZ
Definition: cuddInt.h:387
int cuddZddGetNegVarIndex(DdManager *dd, int index)
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 1041 of file cuddTable.c.

1046 {
1047  DdNode *node;
1048 
1049  if (T == DD_ZERO(zdd))
1050  return(E);
1051  node = cuddUniqueInterZdd(zdd, id, T, E);
1052  return(node);
1053 
1054 } /* end of cuddZddGetNode */
Definition: cudd.h:278
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1343
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 1074 of file cuddTable.c.

1079 {
1080  DdNode *f, *r, *t;
1081  DdNode *zdd_one = DD_ONE(dd);
1082  DdNode *zdd_zero = DD_ZERO(dd);
1083 
1084  f = cuddUniqueInterZdd(dd, index, zdd_one, zdd_zero);
1085  if (f == NULL) {
1086  return(NULL);
1087  }
1088  cuddRef(f);
1089  t = cuddZddProduct(dd, f, g);
1090  if (t == NULL) {
1091  Cudd_RecursiveDerefZdd(dd, f);
1092  return(NULL);
1093  }
1094  cuddRef(t);
1095  Cudd_RecursiveDerefZdd(dd, f);
1096  r = cuddZddUnion(dd, t, h);
1097  if (r == NULL) {
1098  Cudd_RecursiveDerefZdd(dd, t);
1099  return(NULL);
1100  }
1101  cuddRef(r);
1102  Cudd_RecursiveDerefZdd(dd, t);
1103 
1104  cuddDeref(r);
1105  return(r);
1106 
1107 } /* end of cuddZddGetNodeIVO */
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
DdNode * cuddZddProduct(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddZddFuncs.c:380
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:553
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1343
#define DD_ONE(dd)
Definition: cuddInt.h:911
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 1565 of file cuddZddFuncs.c.

1568 {
1569  int pv = (index >> 1) << 1;
1570  return(pv);
1571 } /* end of cuddZddGetPosVarIndex */
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 1607 of file cuddZddFuncs.c.

1610 {
1611  int pv = cuddZddGetPosVarIndex(dd, index);
1612  return(dd->permZ[pv]);
1613 } /* end of cuddZddGetPosVarLevel */
int * permZ
Definition: cuddInt.h:387
int cuddZddGetPosVarIndex(DdManager *dd, int index)
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 252 of file cuddInit.c.

254 {
255  DdNode *p, *res;
256  int i;
257 
258  zdd->univ = ABC_ALLOC(DdNodePtr, zdd->sizeZ);
259  if (zdd->univ == NULL) {
260  zdd->errorCode = CUDD_MEMORY_OUT;
261  return(0);
262  }
263 
264  res = DD_ONE(zdd);
265  cuddRef(res);
266  for (i = zdd->sizeZ - 1; i >= 0; i--) {
267  unsigned int index = zdd->invpermZ[i];
268  p = res;
269  res = cuddUniqueInterZdd(zdd, index, p, p);
270  if (res == NULL) {
271  Cudd_RecursiveDerefZdd(zdd,p);
272  ABC_FREE(zdd->univ);
273  return(0);
274  }
275  cuddRef(res);
276  cuddDeref(p);
277  zdd->univ[i] = res;
278  }
279 
280 #ifdef DD_VERBOSE
281  cuddZddP(zdd, zdd->univ[0]);
282 #endif
283 
284  return(1);
285 
286 } /* end of cuddZddInitUniv */
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
static Llb_Mgr_t * p
Definition: llb3Image.c:950
int * invpermZ
Definition: cuddInt.h:389
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1343
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define DD_ONE(dd)
Definition: cuddInt.h:911
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
int cuddZddP(DdManager *zdd, DdNode *f)
Definition: cuddZddUtil.c:822
DdNode ** univ
Definition: cuddInt.h:392
DdNode* cuddZddIntersect ( DdManager zdd,
DdNode P,
DdNode Q 
)

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

Synopsis [Performs the recursive step of Cudd_zddIntersect.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 642 of file cuddZddSetop.c.

646 {
647  int p_top, q_top;
648  DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
649  DdManager *table = zdd;
650 
651  statLine(zdd);
652  if (P == empty)
653  return(empty);
654  if (Q == empty)
655  return(empty);
656  if (P == Q)
657  return(P);
658 
659  /* Check cache. */
660  res = cuddCacheLookup2Zdd(table, cuddZddIntersect, P, Q);
661  if (res != NULL)
662  return(res);
663 
664  if (cuddIsConstant(P))
665  p_top = P->index;
666  else
667  p_top = zdd->permZ[P->index];
668  if (cuddIsConstant(Q))
669  q_top = Q->index;
670  else
671  q_top = zdd->permZ[Q->index];
672  if (p_top < q_top) {
673  res = cuddZddIntersect(zdd, cuddE(P), Q);
674  if (res == NULL) return(NULL);
675  } else if (p_top > q_top) {
676  res = cuddZddIntersect(zdd, P, cuddE(Q));
677  if (res == NULL) return(NULL);
678  } else {
679  t = cuddZddIntersect(zdd, cuddT(P), cuddT(Q));
680  if (t == NULL) return(NULL);
681  cuddRef(t);
682  e = cuddZddIntersect(zdd, cuddE(P), cuddE(Q));
683  if (e == NULL) {
684  Cudd_RecursiveDerefZdd(table, t);
685  return(NULL);
686  }
687  cuddRef(e);
688  res = cuddZddGetNode(zdd, P->index, t, e);
689  if (res == NULL) {
690  Cudd_RecursiveDerefZdd(table, t);
691  Cudd_RecursiveDerefZdd(table, e);
692  return(NULL);
693  }
694  cuddDeref(t);
695  cuddDeref(e);
696  }
697 
698  cuddCacheInsert2(table, cuddZddIntersect, P, Q, res);
699 
700  return(res);
701 
702 } /* end of cuddZddIntersect */
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:610
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
int * permZ
Definition: cuddInt.h:387
#define statLine(dd)
Definition: cuddInt.h:1037
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:642
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
static DdNode * empty
Definition: cuddZddLin.c:98
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 234 of file cuddZddIsop.c.

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

432 {
434  DdNode *r,*Gv,*Gvn,*Hv,*Hvn,*t,*e;
435  unsigned int topf,topg,toph,v,top;
436  int index;
437 
438  statLine(dd);
439  /* Trivial cases. */
440  /* One variable cases. */
441  if (f == (empty = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
442  return(h);
443  }
444  topf = cuddIZ(dd,f->index);
445  topg = cuddIZ(dd,g->index);
446  toph = cuddIZ(dd,h->index);
447  v = ddMin(topg,toph);
448  top = ddMin(topf,v);
449 
450  tautology = (top == CUDD_MAXINDEX) ? DD_ONE(dd) : dd->univ[top];
451  if (f == tautology) { /* ITE(1,G,H) = G */
452  return(g);
453  }
454 
455  /* From now on, f is known to not be a constant. */
456  zddVarToConst(f,&g,&h,tautology,empty);
457 
458  /* Check remaining one variable cases. */
459  if (g == h) { /* ITE(F,G,G) = G */
460  return(g);
461  }
462 
463  if (g == tautology) { /* ITE(F,1,0) = F */
464  if (h == empty) return(f);
465  }
466 
467  /* Check cache. */
468  r = cuddCacheLookupZdd(dd,DD_ZDD_ITE_TAG,f,g,h);
469  if (r != NULL) {
470  return(r);
471  }
472 
473  /* Recompute these because they may have changed in zddVarToConst. */
474  topg = cuddIZ(dd,g->index);
475  toph = cuddIZ(dd,h->index);
476  v = ddMin(topg,toph);
477 
478  if (topf < v) {
479  r = cuddZddIte(dd,cuddE(f),g,h);
480  if (r == NULL) return(NULL);
481  } else if (topf > v) {
482  if (topg > v) {
483  Gvn = g;
484  index = h->index;
485  } else {
486  Gvn = cuddE(g);
487  index = g->index;
488  }
489  if (toph > v) {
490  Hv = empty; Hvn = h;
491  } else {
492  Hv = cuddT(h); Hvn = cuddE(h);
493  }
494  e = cuddZddIte(dd,f,Gvn,Hvn);
495  if (e == NULL) return(NULL);
496  cuddRef(e);
497  r = cuddZddGetNode(dd,index,Hv,e);
498  if (r == NULL) {
500  return(NULL);
501  }
502  cuddDeref(e);
503  } else {
504  index = f->index;
505  if (topg > v) {
506  Gv = empty; Gvn = g;
507  } else {
508  Gv = cuddT(g); Gvn = cuddE(g);
509  }
510  if (toph > v) {
511  Hv = empty; Hvn = h;
512  } else {
513  Hv = cuddT(h); Hvn = cuddE(h);
514  }
515  e = cuddZddIte(dd,cuddE(f),Gvn,Hvn);
516  if (e == NULL) return(NULL);
517  cuddRef(e);
518  t = cuddZddIte(dd,cuddT(f),Gv,Hv);
519  if (t == NULL) {
521  return(NULL);
522  }
523  cuddRef(t);
524  r = cuddZddGetNode(dd,index,t,e);
525  if (r == NULL) {
528  return(NULL);
529  }
530  cuddDeref(t);
531  cuddDeref(e);
532  }
533 
534  cuddCacheInsert(dd,DD_ZDD_ITE_TAG,f,g,h,r);
535 
536  return(r);
537 
538 } /* end of cuddZddIte */
DdNode * cuddZddIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddZddSetop.c:427
DdNode * cuddCacheLookupZdd(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddCache.c:435
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
#define cuddIZ(dd, index)
Definition: cuddInt.h:704
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
bool tautology()
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddCache.c:222
#define statLine(dd)
Definition: cuddInt.h:1037
static void zddVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty)
#define ddMin(x, y)
Definition: cuddInt.h:818
#define cuddT(node)
Definition: cuddInt.h:636
#define DD_ZDD_ITE_TAG
Definition: cuddInt.h:183
DdHalfWord index
Definition: cudd.h:279
#define CUDD_MAXINDEX
Definition: cudd.h:112
#define cuddE(node)
Definition: cuddInt.h:652
static DdNode * empty
Definition: cuddZddLin.c:98
#define DD_ONE(dd)
Definition: cuddInt.h:911
DdNode ** univ
Definition: cuddInt.h:392
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 156 of file cuddZddLin.c.

160 {
161  int i;
162  int *var;
163  int size;
164  int x;
165  int result;
166 #ifdef DD_STATS
167  int previousSize;
168 #endif
169 
170  size = table->sizeZ;
171  empty = table->zero;
172 
173  /* Find order in which to sift variables. */
174  var = NULL;
175  zdd_entry = ABC_ALLOC(int, size);
176  if (zdd_entry == NULL) {
177  table->errorCode = CUDD_MEMORY_OUT;
178  goto cuddZddSiftingOutOfMem;
179  }
180  var = ABC_ALLOC(int, size);
181  if (var == NULL) {
182  table->errorCode = CUDD_MEMORY_OUT;
183  goto cuddZddSiftingOutOfMem;
184  }
185 
186  for (i = 0; i < size; i++) {
187  x = table->permZ[i];
188  zdd_entry[i] = table->subtableZ[x].keys;
189  var[i] = i;
190  }
191 
192  qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
193 
194  /* Now sift. */
195  for (i = 0; i < ddMin(table->siftMaxVar, size); i++) {
196  if (zddTotalNumberSwapping >= table->siftMaxSwap)
197  break;
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  ABC_FREE(var);
221 
222  return(1);
223 
224 cuddZddSiftingOutOfMem:
225 
226  if (zdd_entry != NULL) ABC_FREE(zdd_entry);
227  if (var != NULL) ABC_FREE(var);
228 
229  return(0);
230 
231 } /* end of cuddZddLinearSifting */
unsigned int keys
Definition: cuddInt.h:330
int siftMaxSwap
Definition: cuddInt.h:412
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:326
int var(Lit p)
Definition: SolverTypes.h:62
DdNode * zero
Definition: cuddInt.h:346
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int * permZ
Definition: cuddInt.h:387
FILE * out
Definition: cuddInt.h:441
static int cuddZddLinearAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddZddLin.c:577
static int size
Definition: cuddSign.c:86
#define ddMin(x, y)
Definition: cuddInt.h:818
int siftMaxVar
Definition: cuddInt.h:411
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int result
Definition: cuddGenetic.c:125
static DdNode * empty
Definition: cuddZddLin.c:98
unsigned int keysZ
Definition: cuddInt.h:370
int * zdd_entry
Definition: cuddZddReord.c:108
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddZddReord.c:459
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
int zddTotalNumberSwapping
Definition: cuddZddReord.c:110
DdSubtable * subtableZ
Definition: cuddInt.h:366
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 413 of file cuddZddReord.c.

416 {
417  return(x + 1);
418 
419 } /* end of cuddZddNextHigh */
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 435 of file cuddZddReord.c.

438 {
439  return(x - 1);
440 
441 } /* end of cuddZddNextLow */
int cuddZddP ( DdManager zdd,
DdNode f 
)

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

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

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

SideEffects [None]

SeeAlso [Cudd_zddPrintDebug]

Definition at line 822 of file cuddZddUtil.c.

825 {
826  int retval;
828 
829  if (table == NULL) return(0);
830 
831  retval = zp2(zdd, f, table);
832  st__free_table(table);
833  (void) fputc('\n', zdd->out);
834  return(retval);
835 
836 } /* end of cuddZddP */
void st__free_table(st__table *table)
Definition: st.c:81
int st__ptrcmp(const char *, const char *)
Definition: st.c:480
static int zp2(DdManager *zdd, DdNode *f, st__table *t)
Definition: cuddZddUtil.c:857
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition: st.c:72
FILE * out
Definition: cuddInt.h:441
Definition: st.h:52
int st__ptrhash(const char *, int)
Definition: st.c:468
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 380 of file cuddZddFuncs.c.

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

871 {
872  int i;
873  int *var;
874  int size;
875  int x;
876  int result;
877 #ifdef DD_STATS
878  int previousSize;
879 #endif
880 
881  size = table->sizeZ;
882 
883  /* Find order in which to sift variables. */
884  var = NULL;
885  zdd_entry = ABC_ALLOC(int, size);
886  if (zdd_entry == NULL) {
887  table->errorCode = CUDD_MEMORY_OUT;
888  goto cuddZddSiftingOutOfMem;
889  }
890  var = ABC_ALLOC(int, size);
891  if (var == NULL) {
892  table->errorCode = CUDD_MEMORY_OUT;
893  goto cuddZddSiftingOutOfMem;
894  }
895 
896  for (i = 0; i < size; i++) {
897  x = table->permZ[i];
898  zdd_entry[i] = table->subtableZ[x].keys;
899  var[i] = i;
900  }
901 
902  qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
903 
904  /* Now sift. */
905  for (i = 0; i < ddMin(table->siftMaxVar, size); i++) {
906  if (zddTotalNumberSwapping >= table->siftMaxSwap)
907  break;
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  ABC_FREE(var);
931 
932  return(1);
933 
934 cuddZddSiftingOutOfMem:
935 
936  if (zdd_entry != NULL) ABC_FREE(zdd_entry);
937  if (var != NULL) ABC_FREE(var);
938 
939  return(0);
940 
941 } /* end of cuddZddSifting */
unsigned int keys
Definition: cuddInt.h:330
int siftMaxSwap
Definition: cuddInt.h:412
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:326
int var(Lit p)
Definition: SolverTypes.h:62
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int * permZ
Definition: cuddInt.h:387
static int cuddZddSiftingAux(DdManager *table, int x, int x_low, int x_high)
int zddTotalNumberSwapping
Definition: cuddZddReord.c:110
FILE * out
Definition: cuddInt.h:441
static int size
Definition: cuddSign.c:86
#define ddMin(x, y)
Definition: cuddInt.h:818
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddZddReord.c:459
int siftMaxVar
Definition: cuddInt.h:411
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int result
Definition: cuddGenetic.c:125
unsigned int keysZ
Definition: cuddInt.h:370
int * zdd_entry
Definition: cuddZddReord.c:108
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdSubtable * subtableZ
Definition: cuddInt.h:366
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 923 of file cuddZddSetop.c.

927 {
928  DdNode *zvar, *r;
929  DdNode *base, *empty;
930 
931  base = DD_ONE(dd);
932  empty = DD_ZERO(dd);
933 
934  zvar = cuddUniqueInterZdd(dd, var, base, empty);
935  if (zvar == NULL) {
936  return(NULL);
937  } else {
938  cuddRef(zvar);
939  r = zdd_subset0_aux(dd, P, zvar);
940  if (r == NULL) {
941  Cudd_RecursiveDerefZdd(dd, zvar);
942  return(NULL);
943  }
944  cuddRef(r);
945  Cudd_RecursiveDerefZdd(dd, zvar);
946  }
947 
948  cuddDeref(r);
949  return(r);
950 
951 } /* end of cuddZddSubset0 */
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
int var(Lit p)
Definition: SolverTypes.h:62
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1343
static DdNode * zdd_subset0_aux(DdManager *zdd, DdNode *P, DdNode *zvar)
static DdNode * empty
Definition: cuddZddLin.c:98
#define DD_ONE(dd)
Definition: cuddInt.h:911
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 874 of file cuddZddSetop.c.

878 {
879  DdNode *zvar, *r;
880  DdNode *base, *empty;
881 
882  base = DD_ONE(dd);
883  empty = DD_ZERO(dd);
884 
885  zvar = cuddUniqueInterZdd(dd, var, base, empty);
886  if (zvar == NULL) {
887  return(NULL);
888  } else {
889  cuddRef(zvar);
890  r = zdd_subset1_aux(dd, P, zvar);
891  if (r == NULL) {
892  Cudd_RecursiveDerefZdd(dd, zvar);
893  return(NULL);
894  }
895  cuddRef(r);
896  Cudd_RecursiveDerefZdd(dd, zvar);
897  }
898 
899  cuddDeref(r);
900  return(r);
901 
902 } /* end of cuddZddSubset1 */
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
int var(Lit p)
Definition: SolverTypes.h:62
static DdNode * zdd_subset1_aux(DdManager *zdd, DdNode *P, DdNode *zvar)
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddTable.c:1343
static DdNode * empty
Definition: cuddZddLin.c:98
#define DD_ONE(dd)
Definition: cuddInt.h:911
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 484 of file cuddZddReord.c.

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

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

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

306 {
307  int i;
308  int *var;
309  int nvars;
310  int x;
311  int result;
312  int symvars;
313  int symgroups;
314  int iteration;
315 #ifdef DD_STATS
316  int previousSize;
317 #endif
318 
319  nvars = table->sizeZ;
320 
321  /* Find order in which to sift variables. */
322  var = NULL;
323  zdd_entry = ABC_ALLOC(int, nvars);
324  if (zdd_entry == NULL) {
325  table->errorCode = CUDD_MEMORY_OUT;
326  goto cuddZddSymmSiftingOutOfMem;
327  }
328  var = ABC_ALLOC(int, nvars);
329  if (var == NULL) {
330  table->errorCode = CUDD_MEMORY_OUT;
331  goto cuddZddSymmSiftingOutOfMem;
332  }
333 
334  for (i = 0; i < nvars; i++) {
335  x = table->permZ[i];
336  zdd_entry[i] = table->subtableZ[x].keys;
337  var[i] = i;
338  }
339 
340  qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
341 
342  /* Initialize the symmetry of each subtable to itself. */
343  for (i = lower; i <= upper; i++)
344  table->subtableZ[i].next = i;
345 
346  iteration = ddMin(table->siftMaxVar, nvars);
347  for (i = 0; i < iteration; i++) {
348  if (zddTotalNumberSwapping >= table->siftMaxSwap)
349  break;
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  ABC_FREE(var);
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)
391  if (var != NULL)
392  ABC_FREE(var);
393 
394  return(0);
395 
396 } /* end of cuddZddSymmSifting */
unsigned int keys
Definition: cuddInt.h:330
int siftMaxSwap
Definition: cuddInt.h:412
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:326
int var(Lit p)
Definition: SolverTypes.h:62
int * zdd_entry
Definition: cuddZddReord.c:108
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int * permZ
Definition: cuddInt.h:387
int zddTotalNumberSwapping
Definition: cuddZddReord.c:110
FILE * out
Definition: cuddInt.h:441
#define ddMin(x, y)
Definition: cuddInt.h:818
int siftMaxVar
Definition: cuddInt.h:411
static void cuddZddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
Definition: cuddZddSymm.c:1671
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int next
Definition: cuddInt.h:333
static int result
Definition: cuddGenetic.c:125
unsigned int keysZ
Definition: cuddInt.h:370
static int cuddZddSymmSiftingAux(DdManager *table, int x, int x_low, int x_high)
Definition: cuddZddSymm.c:601
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddZddReord.c:459
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdSubtable * subtableZ
Definition: cuddInt.h:366
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 = ABC_ALLOC(int, nvars);
449  if (zdd_entry == NULL) {
450  table->errorCode = CUDD_MEMORY_OUT;
451  goto cuddZddSymmSiftingConvOutOfMem;
452  }
453  var = ABC_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  x = table->permZ[var[i]];
478  if (x < lower || x > upper) continue;
479  /* Only sift if not in symmetry group already. */
480  if (table->subtableZ[x].next == (unsigned) x) {
481 #ifdef DD_STATS
482  previousSize = table->keysZ;
483 #endif
484  result = cuddZddSymmSiftingAux(table, x, lower, upper);
485  if (!result)
486  goto cuddZddSymmSiftingConvOutOfMem;
487 #ifdef DD_STATS
488  if (table->keysZ < (unsigned) previousSize) {
489  (void) fprintf(table->out,"-");
490  } else if (table->keysZ > (unsigned) previousSize) {
491  (void) fprintf(table->out,"+");
492 #ifdef DD_VERBOSE
493  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]);
494 #endif
495  } else {
496  (void) fprintf(table->out,"=");
497  }
498  fflush(table->out);
499 #endif
500  }
501  }
502 
503  /* Sifting now until convergence. */
504  while ((unsigned) initialSize > table->keysZ) {
505  initialSize = table->keysZ;
506 #ifdef DD_STATS
507  (void) fprintf(table->out,"\n");
508 #endif
509  /* Here we consider only one representative for each symmetry class. */
510  for (x = lower, classes = 0; x <= upper; x++, classes++) {
511  while ((unsigned) x < table->subtableZ[x].next)
512  x = table->subtableZ[x].next;
513  /* Here x is the largest index in a group.
514  ** Groups consists of adjacent variables.
515  ** Hence, the next increment of x will move it to a new group.
516  */
517  i = table->invpermZ[x];
518  zdd_entry[i] = table->subtableZ[x].keys;
519  var[classes] = i;
520  }
521 
522  qsort((void *)var,classes,sizeof(int),(DD_QSFP)cuddZddUniqueCompare);
523 
524  /* Now sift. */
525  iteration = ddMin(table->siftMaxVar, nvars);
526  for (i = 0; i < iteration; i++) {
527  if (zddTotalNumberSwapping >= table->siftMaxSwap)
528  break;
529  x = table->permZ[var[i]];
530  if ((unsigned) x >= table->subtableZ[x].next) {
531 #ifdef DD_STATS
532  previousSize = table->keysZ;
533 #endif
534  result = cuddZddSymmSiftingConvAux(table, x, lower, upper);
535  if (!result)
536  goto cuddZddSymmSiftingConvOutOfMem;
537 #ifdef DD_STATS
538  if (table->keysZ < (unsigned) previousSize) {
539  (void) fprintf(table->out,"-");
540  } else if (table->keysZ > (unsigned) previousSize) {
541  (void) fprintf(table->out,"+");
542 #ifdef DD_VERBOSE
543  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]);
544 #endif
545  } else {
546  (void) fprintf(table->out,"=");
547  }
548  fflush(table->out);
549 #endif
550  }
551  } /* for */
552  }
553 
554  cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups);
555 
556 #ifdef DD_STATS
557  (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",
558  symvars);
559  (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",
560  symgroups);
561 #endif
562 
563  ABC_FREE(var);
565 
566  return(1+symvars);
567 
568 cuddZddSymmSiftingConvOutOfMem:
569 
570  if (zdd_entry != NULL)
572  if (var != NULL)
573  ABC_FREE(var);
574 
575  return(0);
576 
577 } /* end of cuddZddSymmSiftingConv */
unsigned int keys
Definition: cuddInt.h:330
int siftMaxSwap
Definition: cuddInt.h:412
int * invpermZ
Definition: cuddInt.h:389
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:326
int var(Lit p)
Definition: SolverTypes.h:62
int * zdd_entry
Definition: cuddZddReord.c:108
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int * permZ
Definition: cuddInt.h:387
int zddTotalNumberSwapping
Definition: cuddZddReord.c:110
FILE * out
Definition: cuddInt.h:441
#define ddMin(x, y)
Definition: cuddInt.h:818
int siftMaxVar
Definition: cuddInt.h:411
static void cuddZddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
Definition: cuddZddSymm.c:1671
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int next
Definition: cuddInt.h:333
static int result
Definition: cuddGenetic.c:125
unsigned int keysZ
Definition: cuddInt.h:370
static int cuddZddSymmSiftingAux(DdManager *table, int x, int x_low, int x_high)
Definition: cuddZddSymm.c:601
static int cuddZddSymmSiftingConvAux(DdManager *table, int x, int x_low, int x_high)
Definition: cuddZddSymm.c:941
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddZddReord.c:459
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
DdSubtable * subtableZ
Definition: cuddInt.h:366
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 232 of file cuddZddGroup.c.

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

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

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

Synopsis [Performs the recursive step of Cudd_zddUnion.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 553 of file cuddZddSetop.c.

557 {
558  int p_top, q_top;
559  DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
560  DdManager *table = zdd;
561 
562  statLine(zdd);
563  if (P == empty)
564  return(Q);
565  if (Q == empty)
566  return(P);
567  if (P == Q)
568  return(P);
569 
570  /* Check cache */
571  res = cuddCacheLookup2Zdd(table, cuddZddUnion, P, Q);
572  if (res != NULL)
573  return(res);
574 
575  if (cuddIsConstant(P))
576  p_top = P->index;
577  else
578  p_top = zdd->permZ[P->index];
579  if (cuddIsConstant(Q))
580  q_top = Q->index;
581  else
582  q_top = zdd->permZ[Q->index];
583  if (p_top < q_top) {
584  e = cuddZddUnion(zdd, cuddE(P), Q);
585  if (e == NULL) return (NULL);
586  cuddRef(e);
587  res = cuddZddGetNode(zdd, P->index, cuddT(P), e);
588  if (res == NULL) {
589  Cudd_RecursiveDerefZdd(table, e);
590  return(NULL);
591  }
592  cuddDeref(e);
593  } else if (p_top > q_top) {
594  e = cuddZddUnion(zdd, P, cuddE(Q));
595  if (e == NULL) return(NULL);
596  cuddRef(e);
597  res = cuddZddGetNode(zdd, Q->index, cuddT(Q), e);
598  if (res == NULL) {
599  Cudd_RecursiveDerefZdd(table, e);
600  return(NULL);
601  }
602  cuddDeref(e);
603  } else {
604  t = cuddZddUnion(zdd, cuddT(P), cuddT(Q));
605  if (t == NULL) return(NULL);
606  cuddRef(t);
607  e = cuddZddUnion(zdd, cuddE(P), cuddE(Q));
608  if (e == NULL) {
609  Cudd_RecursiveDerefZdd(table, t);
610  return(NULL);
611  }
612  cuddRef(e);
613  res = cuddZddGetNode(zdd, P->index, t, e);
614  if (res == NULL) {
615  Cudd_RecursiveDerefZdd(table, t);
616  Cudd_RecursiveDerefZdd(table, e);
617  return(NULL);
618  }
619  cuddDeref(t);
620  cuddDeref(e);
621  }
622 
623  cuddCacheInsert2(table, cuddZddUnion, P, Q, res);
624 
625  return(res);
626 
627 } /* end of cuddZddUnion */
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddCache.c:610
#define cuddRef(n)
Definition: cuddInt.h:584
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
#define cuddDeref(n)
Definition: cuddInt.h:604
Definition: cudd.h:278
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddTable.c:1041
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddCache.c:277
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddZddSetop.c:553
int * permZ
Definition: cuddInt.h:387
#define statLine(dd)
Definition: cuddInt.h:1037
#define cuddIsConstant(node)
Definition: cuddInt.h:620
#define cuddT(node)
Definition: cuddInt.h:636
DdHalfWord index
Definition: cudd.h:279
#define cuddE(node)
Definition: cuddInt.h:652
static DdNode * empty
Definition: cuddZddLin.c:98
#define DD_ZERO(dd)
Definition: cuddInt.h:927
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 459 of file cuddZddReord.c.

462 {
463  return(zdd_entry[*ptr_y] - zdd_entry[*ptr_x]);
464 
465 } /* end of cuddZddUniqueCompare */
int * zdd_entry
Definition: cuddZddReord.c:108
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 761 of file cuddZddFuncs.c.

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

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