src/cuBdd/cudd.h File Reference

#include "mtr.h"
#include "epd.h"
Include dependency graph for cudd.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  DdChildren
struct  DdNode

Defines

#define CUDD_VERSION   "2.4.2"
#define SIZEOF_VOID_P   4
#define SIZEOF_INT   4
#define SIZEOF_LONG   4
#define CUDD_VALUE_TYPE   double
#define CUDD_OUT_OF_MEM   -1
#define CUDD_UNIQUE_SLOTS   256
#define CUDD_CACHE_SLOTS   262144
#define CUDD_RESIDUE_DEFAULT   0
#define CUDD_RESIDUE_MSB   1
#define CUDD_RESIDUE_TC   2
#define CUDD_MAXINDEX   ((DdHalfWord) ~0)
#define CUDD_CONST_INDEX   CUDD_MAXINDEX
#define DD_APA_BITS   16
#define DD_APA_BASE   (1 << DD_APA_BITS)
#define DD_APA_HEXPRINT   "%04x"
#define DD_APA_MASK   (DD_APA_BASE - 1)
#define Cudd_IsConstant(node)   ((Cudd_Regular(node))->index == CUDD_CONST_INDEX)
#define Cudd_Not(node)   ((DdNode *)((long)(node) ^ 01))
#define Cudd_NotCond(node, c)   ((DdNode *)((long)(node) ^ (c)))
#define Cudd_Regular(node)   ((DdNode *)((unsigned long)(node) & ~01))
#define Cudd_Complement(node)   ((DdNode *)((unsigned long)(node) | 01))
#define Cudd_IsComplement(node)   ((int) ((long) (node) & 01))
#define Cudd_T(node)   ((Cudd_Regular(node))->type.kids.T)
#define Cudd_E(node)   ((Cudd_Regular(node))->type.kids.E)
#define Cudd_V(node)   ((Cudd_Regular(node))->type.value)
#define Cudd_ReadIndex(dd, index)   (Cudd_ReadPerm(dd,index))
#define Cudd_ForeachCube(manager, f, gen, cube, value)
#define Cudd_ForeachPrime(manager, l, u, gen, cube)
#define Cudd_ForeachNode(manager, f, gen, node)
#define Cudd_zddForeachPath(manager, f, gen, path)

Typedefs

typedef unsigned short DdHalfWord
typedef struct DdNode DdNode
typedef struct DdManager DdManager
typedef struct DdGen DdGen
typedef unsigned short int DdApaDigit
typedef unsigned int DdApaDoubleDigit
typedef DdApaDigitDdApaNumber
typedef struct DdTlcInfo DdTlcInfo
typedef int(* DD_HFP )(DdManager *, const char *, void *)
typedef DdNode *(* DD_PRFP )(DdManager *, int, DdNode **, DdNode **, DdNode **)
typedef DdNode *(* DD_AOP )(DdManager *, DdNode **, DdNode **)
typedef DdNode *(* DD_MAOP )(DdManager *, DdNode *)
typedef DdNode *(* DD_CTFP )(DdManager *, DdNode *, DdNode *)
typedef DdNode *(* DD_CTFP1 )(DdManager *, DdNode *)
typedef void(* DD_OOMFP )(long)
typedef int(* DD_QSFP )(const void *, const void *)

Enumerations

enum  Cudd_ReorderingType {
  CUDD_REORDER_SAME, CUDD_REORDER_NONE, CUDD_REORDER_RANDOM, CUDD_REORDER_RANDOM_PIVOT,
  CUDD_REORDER_SIFT, CUDD_REORDER_SIFT_CONVERGE, CUDD_REORDER_SYMM_SIFT, CUDD_REORDER_SYMM_SIFT_CONV,
  CUDD_REORDER_WINDOW2, CUDD_REORDER_WINDOW3, CUDD_REORDER_WINDOW4, CUDD_REORDER_WINDOW2_CONV,
  CUDD_REORDER_WINDOW3_CONV, CUDD_REORDER_WINDOW4_CONV, CUDD_REORDER_GROUP_SIFT, CUDD_REORDER_GROUP_SIFT_CONV,
  CUDD_REORDER_ANNEALING, CUDD_REORDER_GENETIC, CUDD_REORDER_LINEAR, CUDD_REORDER_LINEAR_CONVERGE,
  CUDD_REORDER_LAZY_SIFT, CUDD_REORDER_EXACT
}
enum  Cudd_AggregationType {
  CUDD_NO_CHECK, CUDD_GROUP_CHECK, CUDD_GROUP_CHECK2, CUDD_GROUP_CHECK3,
  CUDD_GROUP_CHECK4, CUDD_GROUP_CHECK5, CUDD_GROUP_CHECK6, CUDD_GROUP_CHECK7,
  CUDD_GROUP_CHECK8, CUDD_GROUP_CHECK9
}
enum  Cudd_HookType { CUDD_PRE_GC_HOOK, CUDD_POST_GC_HOOK, CUDD_PRE_REORDERING_HOOK, CUDD_POST_REORDERING_HOOK }
enum  Cudd_ErrorType {
  CUDD_NO_ERROR, CUDD_MEMORY_OUT, CUDD_TOO_MANY_NODES, CUDD_MAX_MEM_EXCEEDED,
  CUDD_INVALID_ARG, CUDD_INTERNAL_ERROR
}
enum  Cudd_LazyGroupType { CUDD_LAZY_NONE, CUDD_LAZY_SOFT_GROUP, CUDD_LAZY_HARD_GROUP, CUDD_LAZY_UNGROUP }
enum  Cudd_VariableType { CUDD_VAR_PRIMARY_INPUT, CUDD_VAR_PRESENT_STATE, CUDD_VAR_NEXT_STATE }

Functions

DdNodeCudd_addNewVar (DdManager *dd)
DdNodeCudd_addNewVarAtLevel (DdManager *dd, int level)
DdNodeCudd_bddNewVar (DdManager *dd)
DdNodeCudd_bddNewVarAtLevel (DdManager *dd, int level)
DdNodeCudd_addIthVar (DdManager *dd, int i)
DdNodeCudd_bddIthVar (DdManager *dd, int i)
DdNodeCudd_zddIthVar (DdManager *dd, int i)
int Cudd_zddVarsFromBddVars (DdManager *dd, int multiplicity)
DdNodeCudd_addConst (DdManager *dd, CUDD_VALUE_TYPE c)
int Cudd_IsNonConstant (DdNode *f)
void Cudd_AutodynEnable (DdManager *unique, Cudd_ReorderingType method)
void Cudd_AutodynDisable (DdManager *unique)
int Cudd_ReorderingStatus (DdManager *unique, Cudd_ReorderingType *method)
void Cudd_AutodynEnableZdd (DdManager *unique, Cudd_ReorderingType method)
void Cudd_AutodynDisableZdd (DdManager *unique)
int Cudd_ReorderingStatusZdd (DdManager *unique, Cudd_ReorderingType *method)
int Cudd_zddRealignmentEnabled (DdManager *unique)
void Cudd_zddRealignEnable (DdManager *unique)
void Cudd_zddRealignDisable (DdManager *unique)
int Cudd_bddRealignmentEnabled (DdManager *unique)
void Cudd_bddRealignEnable (DdManager *unique)
void Cudd_bddRealignDisable (DdManager *unique)
DdNodeCudd_ReadOne (DdManager *dd)
DdNodeCudd_ReadZddOne (DdManager *dd, int i)
DdNodeCudd_ReadZero (DdManager *dd)
DdNodeCudd_ReadLogicZero (DdManager *dd)
DdNodeCudd_ReadPlusInfinity (DdManager *dd)
DdNodeCudd_ReadMinusInfinity (DdManager *dd)
DdNodeCudd_ReadBackground (DdManager *dd)
void Cudd_SetBackground (DdManager *dd, DdNode *bck)
unsigned int Cudd_ReadCacheSlots (DdManager *dd)
double Cudd_ReadCacheUsedSlots (DdManager *dd)
double Cudd_ReadCacheLookUps (DdManager *dd)
double Cudd_ReadCacheHits (DdManager *dd)
double Cudd_ReadRecursiveCalls (DdManager *dd)
unsigned int Cudd_ReadMinHit (DdManager *dd)
void Cudd_SetMinHit (DdManager *dd, unsigned int hr)
unsigned int Cudd_ReadLooseUpTo (DdManager *dd)
void Cudd_SetLooseUpTo (DdManager *dd, unsigned int lut)
unsigned int Cudd_ReadMaxCache (DdManager *dd)
unsigned int Cudd_ReadMaxCacheHard (DdManager *dd)
void Cudd_SetMaxCacheHard (DdManager *dd, unsigned int mc)
int Cudd_ReadSize (DdManager *dd)
int Cudd_ReadZddSize (DdManager *dd)
unsigned int Cudd_ReadSlots (DdManager *dd)
double Cudd_ReadUsedSlots (DdManager *dd)
double Cudd_ExpectedUsedSlots (DdManager *dd)
unsigned int Cudd_ReadKeys (DdManager *dd)
unsigned int Cudd_ReadDead (DdManager *dd)
unsigned int Cudd_ReadMinDead (DdManager *dd)
int Cudd_ReadReorderings (DdManager *dd)
long Cudd_ReadReorderingTime (DdManager *dd)
int Cudd_ReadGarbageCollections (DdManager *dd)
long Cudd_ReadGarbageCollectionTime (DdManager *dd)
double Cudd_ReadNodesFreed (DdManager *dd)
double Cudd_ReadNodesDropped (DdManager *dd)
double Cudd_ReadUniqueLookUps (DdManager *dd)
double Cudd_ReadUniqueLinks (DdManager *dd)
int Cudd_ReadSiftMaxVar (DdManager *dd)
void Cudd_SetSiftMaxVar (DdManager *dd, int smv)
int Cudd_ReadSiftMaxSwap (DdManager *dd)
void Cudd_SetSiftMaxSwap (DdManager *dd, int sms)
double Cudd_ReadMaxGrowth (DdManager *dd)
void Cudd_SetMaxGrowth (DdManager *dd, double mg)
double Cudd_ReadMaxGrowthAlternate (DdManager *dd)
void Cudd_SetMaxGrowthAlternate (DdManager *dd, double mg)
int Cudd_ReadReorderingCycle (DdManager *dd)
void Cudd_SetReorderingCycle (DdManager *dd, int cycle)
MtrNodeCudd_ReadTree (DdManager *dd)
void Cudd_SetTree (DdManager *dd, MtrNode *tree)
void Cudd_FreeTree (DdManager *dd)
MtrNodeCudd_ReadZddTree (DdManager *dd)
void Cudd_SetZddTree (DdManager *dd, MtrNode *tree)
void Cudd_FreeZddTree (DdManager *dd)
unsigned int Cudd_NodeReadIndex (DdNode *node)
int Cudd_ReadPerm (DdManager *dd, int i)
int Cudd_ReadPermZdd (DdManager *dd, int i)
int Cudd_ReadInvPerm (DdManager *dd, int i)
int Cudd_ReadInvPermZdd (DdManager *dd, int i)
DdNodeCudd_ReadVars (DdManager *dd, int i)
CUDD_VALUE_TYPE Cudd_ReadEpsilon (DdManager *dd)
void Cudd_SetEpsilon (DdManager *dd, CUDD_VALUE_TYPE ep)
Cudd_AggregationType Cudd_ReadGroupcheck (DdManager *dd)
void Cudd_SetGroupcheck (DdManager *dd, Cudd_AggregationType gc)
int Cudd_GarbageCollectionEnabled (DdManager *dd)
void Cudd_EnableGarbageCollection (DdManager *dd)
void Cudd_DisableGarbageCollection (DdManager *dd)
int Cudd_DeadAreCounted (DdManager *dd)
void Cudd_TurnOnCountDead (DdManager *dd)
void Cudd_TurnOffCountDead (DdManager *dd)
int Cudd_ReadRecomb (DdManager *dd)
void Cudd_SetRecomb (DdManager *dd, int recomb)
int Cudd_ReadSymmviolation (DdManager *dd)
void Cudd_SetSymmviolation (DdManager *dd, int symmviolation)
int Cudd_ReadArcviolation (DdManager *dd)
void Cudd_SetArcviolation (DdManager *dd, int arcviolation)
int Cudd_ReadPopulationSize (DdManager *dd)
void Cudd_SetPopulationSize (DdManager *dd, int populationSize)
int Cudd_ReadNumberXovers (DdManager *dd)
void Cudd_SetNumberXovers (DdManager *dd, int numberXovers)
unsigned long Cudd_ReadMemoryInUse (DdManager *dd)
int Cudd_PrintInfo (DdManager *dd, FILE *fp)
long Cudd_ReadPeakNodeCount (DdManager *dd)
int Cudd_ReadPeakLiveNodeCount (DdManager *dd)
long Cudd_ReadNodeCount (DdManager *dd)
long Cudd_zddReadNodeCount (DdManager *dd)
int Cudd_AddHook (DdManager *dd, DD_HFP f, Cudd_HookType where)
int Cudd_RemoveHook (DdManager *dd, DD_HFP f, Cudd_HookType where)
int Cudd_IsInHook (DdManager *dd, DD_HFP f, Cudd_HookType where)
int Cudd_StdPreReordHook (DdManager *dd, const char *str, void *data)
int Cudd_StdPostReordHook (DdManager *dd, const char *str, void *data)
int Cudd_EnableReorderingReporting (DdManager *dd)
int Cudd_DisableReorderingReporting (DdManager *dd)
int Cudd_ReorderingReporting (DdManager *dd)
Cudd_ErrorType Cudd_ReadErrorCode (DdManager *dd)
void Cudd_ClearErrorCode (DdManager *dd)
FILE * Cudd_ReadStdout (DdManager *dd)
void Cudd_SetStdout (DdManager *dd, FILE *fp)
FILE * Cudd_ReadStderr (DdManager *dd)
void Cudd_SetStderr (DdManager *dd, FILE *fp)
unsigned int Cudd_ReadNextReordering (DdManager *dd)
void Cudd_SetNextReordering (DdManager *dd, unsigned int next)
double Cudd_ReadSwapSteps (DdManager *dd)
unsigned int Cudd_ReadMaxLive (DdManager *dd)
void Cudd_SetMaxLive (DdManager *dd, unsigned int maxLive)
unsigned long Cudd_ReadMaxMemory (DdManager *dd)
void Cudd_SetMaxMemory (DdManager *dd, unsigned long maxMemory)
int Cudd_bddBindVar (DdManager *dd, int index)
int Cudd_bddUnbindVar (DdManager *dd, int index)
int Cudd_bddVarIsBound (DdManager *dd, int index)
DdNodeCudd_addExistAbstract (DdManager *manager, DdNode *f, DdNode *cube)
DdNodeCudd_addUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube)
DdNodeCudd_addOrAbstract (DdManager *manager, DdNode *f, DdNode *cube)
DdNodeCudd_addApply (DdManager *dd, DdNode *(*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g)
DdNodeCudd_addPlus (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addTimes (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addThreshold (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addSetNZ (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addDivide (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addMinus (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addMinimum (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addMaximum (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addOneZeroMaximum (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addDiff (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addAgreement (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addOr (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addNand (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addNor (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addXor (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addXnor (DdManager *dd, DdNode **f, DdNode **g)
DdNodeCudd_addMonadicApply (DdManager *dd, DdNode *(*op)(DdManager *, DdNode *), DdNode *f)
DdNodeCudd_addLog (DdManager *dd, DdNode *f)
DdNodeCudd_addFindMax (DdManager *dd, DdNode *f)
DdNodeCudd_addFindMin (DdManager *dd, DdNode *f)
DdNodeCudd_addIthBit (DdManager *dd, DdNode *f, int bit)
DdNodeCudd_addScalarInverse (DdManager *dd, DdNode *f, DdNode *epsilon)
DdNodeCudd_addIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
DdNodeCudd_addIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
DdNodeCudd_addEvalConst (DdManager *dd, DdNode *f, DdNode *g)
int Cudd_addLeq (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_addCmpl (DdManager *dd, DdNode *f)
DdNodeCudd_addNegate (DdManager *dd, DdNode *f)
DdNodeCudd_addRoundOff (DdManager *dd, DdNode *f, int N)
DdNodeCudd_addWalsh (DdManager *dd, DdNode **x, DdNode **y, int n)
DdNodeCudd_addResidue (DdManager *dd, int n, int m, int options, int top)
DdNodeCudd_bddAndAbstract (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
DdNodeCudd_bddAndAbstractLimit (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, unsigned int limit)
int Cudd_ApaNumberOfDigits (int binaryDigits)
DdApaNumber Cudd_NewApaNumber (int digits)
void Cudd_ApaCopy (int digits, DdApaNumber source, DdApaNumber dest)
DdApaDigit Cudd_ApaAdd (int digits, DdApaNumber a, DdApaNumber b, DdApaNumber sum)
DdApaDigit Cudd_ApaSubtract (int digits, DdApaNumber a, DdApaNumber b, DdApaNumber diff)
DdApaDigit Cudd_ApaShortDivision (int digits, DdApaNumber dividend, DdApaDigit divisor, DdApaNumber quotient)
unsigned int Cudd_ApaIntDivision (int digits, DdApaNumber dividend, unsigned int divisor, DdApaNumber quotient)
void Cudd_ApaShiftRight (int digits, DdApaDigit in, DdApaNumber a, DdApaNumber b)
void Cudd_ApaSetToLiteral (int digits, DdApaNumber number, DdApaDigit literal)
void Cudd_ApaPowerOfTwo (int digits, DdApaNumber number, int power)
int Cudd_ApaCompare (int digitsFirst, DdApaNumber first, int digitsSecond, DdApaNumber second)
int Cudd_ApaCompareRatios (int digitsFirst, DdApaNumber firstNum, unsigned int firstDen, int digitsSecond, DdApaNumber secondNum, unsigned int secondDen)
int Cudd_ApaPrintHex (FILE *fp, int digits, DdApaNumber number)
int Cudd_ApaPrintDecimal (FILE *fp, int digits, DdApaNumber number)
int Cudd_ApaPrintExponential (FILE *fp, int digits, DdApaNumber number, int precision)
DdApaNumber Cudd_ApaCountMinterm (DdManager *manager, DdNode *node, int nvars, int *digits)
int Cudd_ApaPrintMinterm (FILE *fp, DdManager *dd, DdNode *node, int nvars)
int Cudd_ApaPrintMintermExp (FILE *fp, DdManager *dd, DdNode *node, int nvars, int precision)
int Cudd_ApaPrintDensity (FILE *fp, DdManager *dd, DdNode *node, int nvars)
DdNodeCudd_UnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality)
DdNodeCudd_OverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality)
DdNodeCudd_RemapUnderApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality)
DdNodeCudd_RemapOverApprox (DdManager *dd, DdNode *f, int numVars, int threshold, double quality)
DdNodeCudd_BiasedUnderApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0)
DdNodeCudd_BiasedOverApprox (DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0)
DdNodeCudd_bddExistAbstract (DdManager *manager, DdNode *f, DdNode *cube)
DdNodeCudd_bddXorExistAbstract (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
DdNodeCudd_bddUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube)
DdNodeCudd_bddBooleanDiff (DdManager *manager, DdNode *f, int x)
int Cudd_bddVarIsDependent (DdManager *dd, DdNode *f, DdNode *var)
double Cudd_bddCorrelation (DdManager *manager, DdNode *f, DdNode *g)
double Cudd_bddCorrelationWeights (DdManager *manager, DdNode *f, DdNode *g, double *prob)
DdNodeCudd_bddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
DdNodeCudd_bddIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
DdNodeCudd_bddIntersect (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_bddAnd (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_bddAndLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit)
DdNodeCudd_bddOr (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_bddNand (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_bddNor (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_bddXor (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_bddXnor (DdManager *dd, DdNode *f, DdNode *g)
int Cudd_bddLeq (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_addBddThreshold (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value)
DdNodeCudd_addBddStrictThreshold (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value)
DdNodeCudd_addBddInterval (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper)
DdNodeCudd_addBddIthBit (DdManager *dd, DdNode *f, int bit)
DdNodeCudd_BddToAdd (DdManager *dd, DdNode *B)
DdNodeCudd_addBddPattern (DdManager *dd, DdNode *f)
DdNodeCudd_bddTransfer (DdManager *ddSource, DdManager *ddDestination, DdNode *f)
int Cudd_DebugCheck (DdManager *table)
int Cudd_CheckKeys (DdManager *table)
DdNodeCudd_bddClippingAnd (DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction)
DdNodeCudd_bddClippingAndAbstract (DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction)
DdNodeCudd_Cofactor (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_bddCompose (DdManager *dd, DdNode *f, DdNode *g, int v)
DdNodeCudd_addCompose (DdManager *dd, DdNode *f, DdNode *g, int v)
DdNodeCudd_addPermute (DdManager *manager, DdNode *node, int *permut)
DdNodeCudd_addSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n)
DdNodeCudd_bddPermute (DdManager *manager, DdNode *node, int *permut)
DdNodeCudd_bddVarMap (DdManager *manager, DdNode *f)
int Cudd_SetVarMap (DdManager *manager, DdNode **x, DdNode **y, int n)
DdNodeCudd_bddSwapVariables (DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n)
DdNodeCudd_bddAdjPermuteX (DdManager *dd, DdNode *B, DdNode **x, int n)
DdNodeCudd_addVectorCompose (DdManager *dd, DdNode *f, DdNode **vector)
DdNodeCudd_addGeneralVectorCompose (DdManager *dd, DdNode *f, DdNode **vectorOn, DdNode **vectorOff)
DdNodeCudd_addNonSimCompose (DdManager *dd, DdNode *f, DdNode **vector)
DdNodeCudd_bddVectorCompose (DdManager *dd, DdNode *f, DdNode **vector)
int Cudd_bddApproxConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts)
int Cudd_bddApproxDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts)
int Cudd_bddIterConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts)
int Cudd_bddIterDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts)
int Cudd_bddGenConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts)
int Cudd_bddGenDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts)
int Cudd_bddVarConjDecomp (DdManager *dd, DdNode *f, DdNode ***conjuncts)
int Cudd_bddVarDisjDecomp (DdManager *dd, DdNode *f, DdNode ***disjuncts)
DdNodeCudd_FindEssential (DdManager *dd, DdNode *f)
int Cudd_bddIsVarEssential (DdManager *manager, DdNode *f, int id, int phase)
DdTlcInfoCudd_FindTwoLiteralClauses (DdManager *dd, DdNode *f)
int Cudd_PrintTwoLiteralClauses (DdManager *dd, DdNode *f, char **names, FILE *fp)
int Cudd_ReadIthClause (DdTlcInfo *tlc, int i, DdHalfWord *var1, DdHalfWord *var2, int *phase1, int *phase2)
void Cudd_tlcInfoFree (DdTlcInfo *t)
int Cudd_DumpBlif (DdManager *dd, int n, DdNode **f, char **inames, char **onames, char *mname, FILE *fp, int mv)
int Cudd_DumpBlifBody (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp, int mv)
int Cudd_DumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)
int Cudd_DumpDaVinci (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)
int Cudd_DumpDDcal (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)
int Cudd_DumpFactoredForm (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)
DdNodeCudd_bddConstrain (DdManager *dd, DdNode *f, DdNode *c)
DdNodeCudd_bddRestrict (DdManager *dd, DdNode *f, DdNode *c)
DdNodeCudd_bddNPAnd (DdManager *dd, DdNode *f, DdNode *c)
DdNodeCudd_addConstrain (DdManager *dd, DdNode *f, DdNode *c)
DdNode ** Cudd_bddConstrainDecomp (DdManager *dd, DdNode *f)
DdNodeCudd_addRestrict (DdManager *dd, DdNode *f, DdNode *c)
DdNode ** Cudd_bddCharToVect (DdManager *dd, DdNode *f)
DdNodeCudd_bddLICompaction (DdManager *dd, DdNode *f, DdNode *c)
DdNodeCudd_bddSqueeze (DdManager *dd, DdNode *l, DdNode *u)
DdNodeCudd_bddMinimize (DdManager *dd, DdNode *f, DdNode *c)
DdNodeCudd_SubsetCompress (DdManager *dd, DdNode *f, int nvars, int threshold)
DdNodeCudd_SupersetCompress (DdManager *dd, DdNode *f, int nvars, int threshold)
MtrNodeCudd_MakeTreeNode (DdManager *dd, unsigned int low, unsigned int size, unsigned int type)
int Cudd_addHarwell (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, DdNode ***xn, DdNode ***yn_, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy, int pr)
DdManagerCudd_Init (unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory)
void Cudd_Quit (DdManager *unique)
int Cudd_PrintLinear (DdManager *table)
int Cudd_ReadLinear (DdManager *table, int x, int y)
DdNodeCudd_bddLiteralSetIntersection (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_addMatrixMultiply (DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz)
DdNodeCudd_addTimesPlus (DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz)
DdNodeCudd_addTriangle (DdManager *dd, DdNode *f, DdNode *g, DdNode **z, int nz)
DdNodeCudd_addOuterSum (DdManager *dd, DdNode *M, DdNode *r, DdNode *c)
DdNodeCudd_PrioritySelect (DdManager *dd, DdNode *R, DdNode **x, DdNode **y, DdNode **z, DdNode *Pi, int n, DdNode *(*)(DdManager *, int, DdNode **, DdNode **, DdNode **))
DdNodeCudd_Xgty (DdManager *dd, int N, DdNode **z, DdNode **x, DdNode **y)
DdNodeCudd_Xeqy (DdManager *dd, int N, DdNode **x, DdNode **y)
DdNodeCudd_addXeqy (DdManager *dd, int N, DdNode **x, DdNode **y)
DdNodeCudd_Dxygtdxz (DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z)
DdNodeCudd_Dxygtdyz (DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z)
DdNodeCudd_Inequality (DdManager *dd, int N, int c, DdNode **x, DdNode **y)
DdNodeCudd_Disequality (DdManager *dd, int N, int c, DdNode **x, DdNode **y)
DdNodeCudd_bddInterval (DdManager *dd, int N, DdNode **x, unsigned int lowerB, unsigned int upperB)
DdNodeCudd_CProjection (DdManager *dd, DdNode *R, DdNode *Y)
DdNodeCudd_addHamming (DdManager *dd, DdNode **xVars, DdNode **yVars, int nVars)
int Cudd_MinHammingDist (DdManager *dd, DdNode *f, int *minterm, int upperBound)
DdNodeCudd_bddClosestCube (DdManager *dd, DdNode *f, DdNode *g, int *distance)
int Cudd_addRead (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, DdNode ***xn, DdNode ***yn_, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy)
int Cudd_bddRead (FILE *fp, DdManager *dd, DdNode **E, DdNode ***x, DdNode ***y, int *nx, int *ny, int *m, int *n, int bx, int sx, int by, int sy)
void Cudd_Ref (DdNode *n)
void Cudd_RecursiveDeref (DdManager *table, DdNode *n)
void Cudd_IterDerefBdd (DdManager *table, DdNode *n)
void Cudd_DelayedDerefBdd (DdManager *table, DdNode *n)
void Cudd_RecursiveDerefZdd (DdManager *table, DdNode *n)
void Cudd_Deref (DdNode *node)
int Cudd_CheckZeroRef (DdManager *manager)
int Cudd_ReduceHeap (DdManager *table, Cudd_ReorderingType heuristic, int minsize)
int Cudd_ShuffleHeap (DdManager *table, int *permutation)
DdNodeCudd_Eval (DdManager *dd, DdNode *f, int *inputs)
DdNodeCudd_ShortestPath (DdManager *manager, DdNode *f, int *weight, int *support, int *length)
DdNodeCudd_LargestCube (DdManager *manager, DdNode *f, int *length)
int Cudd_ShortestLength (DdManager *manager, DdNode *f, int *weight)
DdNodeCudd_Decreasing (DdManager *dd, DdNode *f, int i)
DdNodeCudd_Increasing (DdManager *dd, DdNode *f, int i)
int Cudd_EquivDC (DdManager *dd, DdNode *F, DdNode *G, DdNode *D)
int Cudd_bddLeqUnless (DdManager *dd, DdNode *f, DdNode *g, DdNode *D)
int Cudd_EqualSupNorm (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr)
DdNodeCudd_bddMakePrime (DdManager *dd, DdNode *cube, DdNode *f)
double * Cudd_CofMinterm (DdManager *dd, DdNode *node)
DdNodeCudd_SolveEqn (DdManager *bdd, DdNode *F, DdNode *Y, DdNode **G, int **yIndex, int n)
DdNodeCudd_VerifySol (DdManager *bdd, DdNode *F, DdNode **G, int *yIndex, int n)
DdNodeCudd_SplitSet (DdManager *manager, DdNode *S, DdNode **xVars, int n, double m)
DdNodeCudd_SubsetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold)
DdNodeCudd_SupersetHeavyBranch (DdManager *dd, DdNode *f, int numVars, int threshold)
DdNodeCudd_SubsetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)
DdNodeCudd_SupersetShortPaths (DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)
void Cudd_SymmProfile (DdManager *table, int lower, int upper)
unsigned int Cudd_Prime (unsigned int p)
int Cudd_PrintMinterm (DdManager *manager, DdNode *node)
int Cudd_bddPrintCover (DdManager *dd, DdNode *l, DdNode *u)
int Cudd_PrintDebug (DdManager *dd, DdNode *f, int n, int pr)
int Cudd_DagSize (DdNode *node)
int Cudd_EstimateCofactor (DdManager *dd, DdNode *node, int i, int phase)
int Cudd_EstimateCofactorSimple (DdNode *node, int i)
int Cudd_SharingSize (DdNode **nodeArray, int n)
double Cudd_CountMinterm (DdManager *manager, DdNode *node, int nvars)
int Cudd_EpdCountMinterm (DdManager *manager, DdNode *node, int nvars, EpDouble *epd)
double Cudd_CountPath (DdNode *node)
double Cudd_CountPathsToNonZero (DdNode *node)
DdNodeCudd_Support (DdManager *dd, DdNode *f)
int * Cudd_SupportIndex (DdManager *dd, DdNode *f)
int Cudd_SupportSize (DdManager *dd, DdNode *f)
DdNodeCudd_VectorSupport (DdManager *dd, DdNode **F, int n)
int * Cudd_VectorSupportIndex (DdManager *dd, DdNode **F, int n)
int Cudd_VectorSupportSize (DdManager *dd, DdNode **F, int n)
int Cudd_ClassifySupport (DdManager *dd, DdNode *f, DdNode *g, DdNode **common, DdNode **onlyF, DdNode **onlyG)
int Cudd_CountLeaves (DdNode *node)
int Cudd_bddPickOneCube (DdManager *ddm, DdNode *node, char *string)
DdNodeCudd_bddPickOneMinterm (DdManager *dd, DdNode *f, DdNode **vars, int n)
DdNode ** Cudd_bddPickArbitraryMinterms (DdManager *dd, DdNode *f, DdNode **vars, int n, int k)
DdNodeCudd_SubsetWithMaskVars (DdManager *dd, DdNode *f, DdNode **vars, int nvars, DdNode **maskVars, int mvars)
DdGenCudd_FirstCube (DdManager *dd, DdNode *f, int **cube, CUDD_VALUE_TYPE *value)
int Cudd_NextCube (DdGen *gen, int **cube, CUDD_VALUE_TYPE *value)
DdGenCudd_FirstPrime (DdManager *dd, DdNode *l, DdNode *u, int **cube)
int Cudd_NextPrime (DdGen *gen, int **cube)
DdNodeCudd_bddComputeCube (DdManager *dd, DdNode **vars, int *phase, int n)
DdNodeCudd_addComputeCube (DdManager *dd, DdNode **vars, int *phase, int n)
DdNodeCudd_CubeArrayToBdd (DdManager *dd, int *array)
int Cudd_BddToCubeArray (DdManager *dd, DdNode *cube, int *array)
DdGenCudd_FirstNode (DdManager *dd, DdNode *f, DdNode **node)
int Cudd_NextNode (DdGen *gen, DdNode **node)
int Cudd_GenFree (DdGen *gen)
int Cudd_IsGenEmpty (DdGen *gen)
DdNodeCudd_IndicesToCube (DdManager *dd, int *array, int n)
void Cudd_PrintVersion (FILE *fp)
double Cudd_AverageDistance (DdManager *dd)
long Cudd_Random (void)
void Cudd_Srandom (long seed)
double Cudd_Density (DdManager *dd, DdNode *f, int nvars)
void Cudd_OutOfMem (long size)
int Cudd_zddCount (DdManager *zdd, DdNode *P)
double Cudd_zddCountDouble (DdManager *zdd, DdNode *P)
DdNodeCudd_zddProduct (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_zddUnateProduct (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_zddWeakDiv (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_zddDivide (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_zddWeakDivF (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_zddDivideF (DdManager *dd, DdNode *f, DdNode *g)
DdNodeCudd_zddComplement (DdManager *dd, DdNode *node)
MtrNodeCudd_MakeZddTreeNode (DdManager *dd, unsigned int low, unsigned int size, unsigned int type)
DdNodeCudd_zddIsop (DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)
DdNodeCudd_bddIsop (DdManager *dd, DdNode *L, DdNode *U)
DdNodeCudd_MakeBddFromZddCover (DdManager *dd, DdNode *node)
int Cudd_zddDagSize (DdNode *p_node)
double Cudd_zddCountMinterm (DdManager *zdd, DdNode *node, int path)
void Cudd_zddPrintSubtable (DdManager *table)
DdNodeCudd_zddPortFromBdd (DdManager *dd, DdNode *B)
DdNodeCudd_zddPortToBdd (DdManager *dd, DdNode *f)
int Cudd_zddReduceHeap (DdManager *table, Cudd_ReorderingType heuristic, int minsize)
int Cudd_zddShuffleHeap (DdManager *table, int *permutation)
DdNodeCudd_zddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
DdNodeCudd_zddUnion (DdManager *dd, DdNode *P, DdNode *Q)
DdNodeCudd_zddIntersect (DdManager *dd, DdNode *P, DdNode *Q)
DdNodeCudd_zddDiff (DdManager *dd, DdNode *P, DdNode *Q)
DdNodeCudd_zddDiffConst (DdManager *zdd, DdNode *P, DdNode *Q)
DdNodeCudd_zddSubset1 (DdManager *dd, DdNode *P, int var)
DdNodeCudd_zddSubset0 (DdManager *dd, DdNode *P, int var)
DdNodeCudd_zddChange (DdManager *dd, DdNode *P, int var)
void Cudd_zddSymmProfile (DdManager *table, int lower, int upper)
int Cudd_zddPrintMinterm (DdManager *zdd, DdNode *node)
int Cudd_zddPrintCover (DdManager *zdd, DdNode *node)
int Cudd_zddPrintDebug (DdManager *zdd, DdNode *f, int n, int pr)
DdGenCudd_zddFirstPath (DdManager *zdd, DdNode *f, int **path)
int Cudd_zddNextPath (DdGen *gen, int **path)
char * Cudd_zddCoverPathToString (DdManager *zdd, int *path, char *str)
int Cudd_zddDumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)
int Cudd_bddSetPiVar (DdManager *dd, int index)
int Cudd_bddSetPsVar (DdManager *dd, int index)
int Cudd_bddSetNsVar (DdManager *dd, int index)
int Cudd_bddIsPiVar (DdManager *dd, int index)
int Cudd_bddIsPsVar (DdManager *dd, int index)
int Cudd_bddIsNsVar (DdManager *dd, int index)
int Cudd_bddSetPairIndex (DdManager *dd, int index, int pairIndex)
int Cudd_bddReadPairIndex (DdManager *dd, int index)
int Cudd_bddSetVarToBeGrouped (DdManager *dd, int index)
int Cudd_bddSetVarHardGroup (DdManager *dd, int index)
int Cudd_bddResetVarToBeGrouped (DdManager *dd, int index)
int Cudd_bddIsVarToBeGrouped (DdManager *dd, int index)
int Cudd_bddSetVarToBeUngrouped (DdManager *dd, int index)
int Cudd_bddIsVarToBeUngrouped (DdManager *dd, int index)
int Cudd_bddIsVarHardGroup (DdManager *dd, int index)

Define Documentation

#define CUDD_CACHE_SLOTS   262144

Definition at line 98 of file cudd.h.

#define Cudd_Complement ( node   )     ((DdNode *)((unsigned long)(node) | 01))

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

Synopsis [Returns the complemented version of a pointer.]

Description []

SideEffects [none]

SeeAlso [Cudd_Regular Cudd_IsComplement]

Definition at line 410 of file cudd.h.

#define CUDD_CONST_INDEX   CUDD_MAXINDEX

Definition at line 117 of file cudd.h.

#define Cudd_E ( node   )     ((Cudd_Regular(node))->type.kids.E)

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

Synopsis [Returns the else child of an internal node.]

Description [Returns the else child of an internal node. If node is a constant node, the result is unpredictable.]

SideEffects [none]

SeeAlso [Cudd_T Cudd_V]

Definition at line 454 of file cudd.h.

#define Cudd_ForeachCube ( manager,
f,
gen,
cube,
value   ) 
Value:
for((gen) = Cudd_FirstCube(manager, f, &cube, &value);\
        Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\
        (void) Cudd_NextCube(gen, &cube, &value))

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

Synopsis [Iterates over the cubes of a decision diagram.]

Description [Iterates over the cubes of a decision diagram f.

Cudd_ForeachCube allocates and frees the generator. Therefore the application should not try to do that. Also, the cube is freed at the end of Cudd_ForeachCube and hence is not available outside of the loop.

CAUTION: It is assumed that dynamic reordering will not occur while there are open generators. It is the user's responsibility to make sure that dynamic reordering does not occur. As long as new nodes are not created during generation, and dynamic reordering is not called explicitly, dynamic reordering will not occur. Alternatively, it is sufficient to disable dynamic reordering. It is a mistake to dispose of a diagram on which generation is ongoing.]

SideEffects [none]

SeeAlso [Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_GenFree Cudd_IsGenEmpty Cudd_AutodynDisable]

Definition at line 518 of file cudd.h.

#define Cudd_ForeachNode ( manager,
f,
gen,
node   ) 
Value:
for((gen) = Cudd_FirstNode(manager, f, &node);\
        Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\
        (void) Cudd_NextNode(gen, &node))

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

Synopsis [Iterates over the nodes of a decision diagram.]

Description [Iterates over the nodes of a decision diagram f.

The nodes are returned in a seemingly random order. Cudd_ForeachNode allocates and frees the generator. Therefore the application should not try to do that.

CAUTION: It is assumed that dynamic reordering will not occur while there are open generators. It is the user's responsibility to make sure that dynamic reordering does not occur. As long as new nodes are not created during generation, and dynamic reordering is not called explicitly, dynamic reordering will not occur. Alternatively, it is sufficient to disable dynamic reordering. It is a mistake to dispose of a diagram on which generation is ongoing.]

SideEffects [none]

SeeAlso [Cudd_ForeachCube Cudd_FirstNode Cudd_NextNode Cudd_GenFree Cudd_IsGenEmpty Cudd_AutodynDisable]

Definition at line 584 of file cudd.h.

#define Cudd_ForeachPrime ( manager,
l,
u,
gen,
cube   ) 
Value:
for((gen) = Cudd_FirstPrime(manager, l, u, &cube);\
        Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\
        (void) Cudd_NextPrime(gen, &cube))

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

Synopsis [Iterates over the primes of a Boolean function.]

Description [Iterates over the primes of a Boolean function producing a prime and irredundant cover.

The Boolean function is described by an upper bound and a lower bound. If the function is completely specified, the two bounds coincide. Cudd_ForeachPrime allocates and frees the generator. Therefore the application should not try to do that. Also, the cube is freed at the end of Cudd_ForeachPrime and hence is not available outside of the loop.

CAUTION: It is a mistake to change a diagram on which generation is ongoing.]

SideEffects [none]

SeeAlso [Cudd_ForeachCube Cudd_FirstPrime Cudd_NextPrime Cudd_GenFree Cudd_IsGenEmpty]

Definition at line 550 of file cudd.h.

#define Cudd_IsComplement ( node   )     ((int) ((long) (node) & 01))

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

Synopsis [Returns 1 if a pointer is complemented.]

Description []

SideEffects [none]

SeeAlso [Cudd_Regular Cudd_Complement]

Definition at line 424 of file cudd.h.

#define Cudd_IsConstant ( node   )     ((Cudd_Regular(node))->index == CUDD_CONST_INDEX)

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

Synopsis [Returns 1 if the node is a constant node.]

Description [Returns 1 if the node is a constant node (rather than an internal node). All constant nodes have the same index (CUDD_CONST_INDEX). The pointer passed to Cudd_IsConstant may be either regular or complemented.]

SideEffects [none]

SeeAlso []

Definition at line 351 of file cudd.h.

#define CUDD_MAXINDEX   ((DdHalfWord) ~0)

Definition at line 112 of file cudd.h.

#define Cudd_Not ( node   )     ((DdNode *)((long)(node) ^ 01))

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

Synopsis [Complements a DD.]

Description [Complements a DD by flipping the complement attribute of the pointer (the least significant bit).]

SideEffects [none]

SeeAlso [Cudd_NotCond]

Definition at line 366 of file cudd.h.

#define Cudd_NotCond ( node,
 )     ((DdNode *)((long)(node) ^ (c)))

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

Synopsis [Complements a DD if a condition is true.]

Description [Complements a DD if condition c is true; c should be either 0 or 1, because it is used directly (for efficiency). If in doubt on the values c may take, use "(c) ? Cudd_Not(node) : node".]

SideEffects [none]

SeeAlso [Cudd_Not]

Definition at line 382 of file cudd.h.

#define CUDD_OUT_OF_MEM   -1

Definition at line 95 of file cudd.h.

#define Cudd_ReadIndex ( dd,
index   )     (Cudd_ReadPerm(dd,index))

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

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

Description [Returns the current position in the order of variable index. This macro is obsolete and is kept for compatibility. New applications should use Cudd_ReadPerm instead.]

SideEffects [none]

SeeAlso [Cudd_ReadPerm]

Definition at line 486 of file cudd.h.

#define Cudd_Regular ( node   )     ((DdNode *)((unsigned long)(node) & ~01))

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

Synopsis [Returns the regular version of a pointer.]

Description []

SideEffects [none]

SeeAlso [Cudd_Complement Cudd_IsComplement]

Definition at line 396 of file cudd.h.

#define CUDD_RESIDUE_DEFAULT   0

Definition at line 101 of file cudd.h.

#define CUDD_RESIDUE_MSB   1

Definition at line 102 of file cudd.h.

#define CUDD_RESIDUE_TC   2

Definition at line 103 of file cudd.h.

#define Cudd_T ( node   )     ((Cudd_Regular(node))->type.kids.T)

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

Synopsis [Returns the then child of an internal node.]

Description [Returns the then child of an internal node. If node is a constant node, the result is unpredictable.]

SideEffects [none]

SeeAlso [Cudd_E Cudd_V]

Definition at line 439 of file cudd.h.

#define CUDD_UNIQUE_SLOTS   256

Definition at line 97 of file cudd.h.

#define Cudd_V ( node   )     ((Cudd_Regular(node))->type.value)

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

Synopsis [Returns the value of a constant node.]

Description [Returns the value of a constant node. If node is an internal node, the result is unpredictable.]

SideEffects [none]

SeeAlso [Cudd_T Cudd_E]

Definition at line 469 of file cudd.h.

#define CUDD_VALUE_TYPE   double

Definition at line 94 of file cudd.h.

#define CUDD_VERSION   "2.4.2"

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

FileName [cudd.h]

PackageName [cudd]

Synopsis [The University of Colorado decision diagram package.]

Description [External functions and data strucures of the CUDD package.

  • To turn on the gathering of statistics, define DD_STATS.
  • To link with mis, define DD_MIS.

Modified by Abelardo Pardo to interface it to VIS. ]

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado

All rights reserved.

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

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

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

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

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

Revision [

Id
cudd.h,v 1.174 2009/02/21 05:55:18 fabio Exp

]

Definition at line 75 of file cudd.h.

#define Cudd_zddForeachPath ( manager,
f,
gen,
path   ) 
Value:
for((gen) = Cudd_zddFirstPath(manager, f, &path);\
        Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\
        (void) Cudd_zddNextPath(gen, &path))

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

Synopsis [Iterates over the paths of a ZDD.]

Description [Iterates over the paths of a ZDD f.

Cudd_zddForeachPath allocates and frees the generator. Therefore the application should not try to do that. Also, the path is freed at the end of Cudd_zddForeachPath and hence is not available outside of the loop.

CAUTION: It is assumed that dynamic reordering will not occur while there are open generators. It is the user's responsibility to make sure that dynamic reordering does not occur. As long as new nodes are not created during generation, and dynamic reordering is not called explicitly, dynamic reordering will not occur. Alternatively, it is sufficient to disable dynamic reordering. It is a mistake to dispose of a diagram on which generation is ongoing.]

SideEffects [none]

SeeAlso [Cudd_zddFirstPath Cudd_zddNextPath Cudd_GenFree Cudd_IsGenEmpty Cudd_AutodynDisable]

Definition at line 618 of file cudd.h.

#define DD_APA_BASE   (1 << DD_APA_BITS)

Definition at line 130 of file cudd.h.

#define DD_APA_BITS   16

Definition at line 129 of file cudd.h.

#define DD_APA_HEXPRINT   "%04x"

Definition at line 131 of file cudd.h.

#define DD_APA_MASK   (DD_APA_BASE - 1)

Definition at line 133 of file cudd.h.

#define SIZEOF_INT   4

Definition at line 81 of file cudd.h.

#define SIZEOF_LONG   4

Definition at line 84 of file cudd.h.

#define SIZEOF_VOID_P   4

Definition at line 78 of file cudd.h.


Typedef Documentation

typedef DdNode*(* DD_AOP)(DdManager *, DdNode **, DdNode **)

Definition at line 316 of file cudd.h.

typedef DdNode*(* DD_CTFP)(DdManager *, DdNode *, DdNode *)

Definition at line 320 of file cudd.h.

typedef DdNode*(* DD_CTFP1)(DdManager *, DdNode *)

Definition at line 321 of file cudd.h.

typedef int(* DD_HFP)(DdManager *, const char *, void *)

Definition at line 311 of file cudd.h.

typedef DdNode*(* DD_MAOP)(DdManager *, DdNode *)

Definition at line 318 of file cudd.h.

typedef void(* DD_OOMFP)(long)

Definition at line 323 of file cudd.h.

typedef DdNode*(* DD_PRFP)(DdManager *, int, DdNode **, DdNode **, DdNode **)

Definition at line 313 of file cudd.h.

typedef int(* DD_QSFP)(const void *, const void *)

Definition at line 325 of file cudd.h.

typedef unsigned short int DdApaDigit

Definition at line 302 of file cudd.h.

typedef unsigned int DdApaDoubleDigit

Definition at line 303 of file cudd.h.

Definition at line 305 of file cudd.h.

typedef struct DdGen DdGen

Definition at line 294 of file cudd.h.

typedef unsigned short DdHalfWord

Definition at line 262 of file cudd.h.

typedef struct DdManager DdManager

Definition at line 292 of file cudd.h.

typedef struct DdNode DdNode

Definition at line 270 of file cudd.h.

typedef struct DdTlcInfo DdTlcInfo

Definition at line 308 of file cudd.h.


Enumeration Type Documentation

Enum************************************************************************

Synopsis [Type of aggregation methods.]

Description [Type of aggregation methods.]

Enumerator:
CUDD_NO_CHECK 
CUDD_GROUP_CHECK 
CUDD_GROUP_CHECK2 
CUDD_GROUP_CHECK3 
CUDD_GROUP_CHECK4 
CUDD_GROUP_CHECK5 
CUDD_GROUP_CHECK6 
CUDD_GROUP_CHECK7 
CUDD_GROUP_CHECK8 
CUDD_GROUP_CHECK9 

Definition at line 184 of file cudd.h.

Enum************************************************************************

Synopsis [Type of error codes.]

Description [Type of error codes.]

Enumerator:
CUDD_NO_ERROR 
CUDD_MEMORY_OUT 
CUDD_TOO_MANY_NODES 
CUDD_MAX_MEM_EXCEEDED 
CUDD_INVALID_ARG 
CUDD_INTERNAL_ERROR 

Definition at line 220 of file cudd.h.

Enum************************************************************************

Synopsis [Type of hooks.]

Description [Type of hooks.]

Enumerator:
CUDD_PRE_GC_HOOK 
CUDD_POST_GC_HOOK 
CUDD_PRE_REORDERING_HOOK 
CUDD_POST_REORDERING_HOOK 

Definition at line 205 of file cudd.h.

Enum************************************************************************

Synopsis [Group type for lazy sifting.]

Description [Group type for lazy sifting.]

Enumerator:
CUDD_LAZY_NONE 
CUDD_LAZY_SOFT_GROUP 
CUDD_LAZY_HARD_GROUP 
CUDD_LAZY_UNGROUP 

Definition at line 237 of file cudd.h.

Enum************************************************************************

Synopsis [Type of reordering algorithm.]

Description [Type of reordering algorithm.]

Enumerator:
CUDD_REORDER_SAME 
CUDD_REORDER_NONE 
CUDD_REORDER_RANDOM 
CUDD_REORDER_RANDOM_PIVOT 
CUDD_REORDER_SIFT 
CUDD_REORDER_SIFT_CONVERGE 
CUDD_REORDER_SYMM_SIFT 
CUDD_REORDER_SYMM_SIFT_CONV 
CUDD_REORDER_WINDOW2 
CUDD_REORDER_WINDOW3 
CUDD_REORDER_WINDOW4 
CUDD_REORDER_WINDOW2_CONV 
CUDD_REORDER_WINDOW3_CONV 
CUDD_REORDER_WINDOW4_CONV 
CUDD_REORDER_GROUP_SIFT 
CUDD_REORDER_GROUP_SIFT_CONV 
CUDD_REORDER_ANNEALING 
CUDD_REORDER_GENETIC 
CUDD_REORDER_LINEAR 
CUDD_REORDER_LINEAR_CONVERGE 
CUDD_REORDER_LAZY_SIFT 
CUDD_REORDER_EXACT 

Definition at line 151 of file cudd.h.

Enum************************************************************************

Synopsis [Variable type.]

Description [Variable type. Currently used only in lazy sifting.]

Enumerator:
CUDD_VAR_PRIMARY_INPUT 
CUDD_VAR_PRESENT_STATE 
CUDD_VAR_NEXT_STATE 

Definition at line 252 of file cudd.h.


Function Documentation

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

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

Synopsis [f if f==g; background if f!=g.]

Description [Returns NULL if not a terminal case; f op g otherwise, where f op g is f if f==g; background if f!=g.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 547 of file cuddAddApply.c.

00551 {
00552     DdNode *F, *G;
00553 
00554     F = *f; G = *g;
00555     if (F == G) return(F);
00556     if (F == dd->background) return(F);
00557     if (G == dd->background) return(G);
00558     if (cuddIsConstant(F) && cuddIsConstant(G)) return(dd->background);
00559     return(NULL);
00560 
00561 } /* end of Cudd_addAgreement */

DdNode* Cudd_addApply ( DdManager dd,
DdNode *)(DdManager *, DdNode **, DdNode **,
DdNode f,
DdNode g 
)
DdNode* Cudd_addBddInterval ( DdManager dd,
DdNode f,
CUDD_VALUE_TYPE  lower,
CUDD_VALUE_TYPE  upper 
)

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

Synopsis [Converts an ADD to a BDD.]

Description [Converts an ADD to a BDD by replacing all discriminants greater than or equal to lower and less than or equal to upper with 1, and all other discriminants with 0. Returns a pointer to the resulting BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addBddThreshold Cudd_addBddStrictThreshold Cudd_addBddPattern Cudd_BddToAdd]

Definition at line 240 of file cuddBridge.c.

00245 {
00246     DdNode *res;
00247     DdNode *l;
00248     DdNode *u;
00249     
00250     /* Create constant nodes for the interval bounds, so that we can use
00251     ** the global cache.
00252     */
00253     l = cuddUniqueConst(dd,lower);
00254     if (l == NULL) return(NULL);
00255     cuddRef(l);
00256     u = cuddUniqueConst(dd,upper);
00257     if (u == NULL) {
00258         Cudd_RecursiveDeref(dd,l);
00259         return(NULL);
00260     }
00261     cuddRef(u);
00262 
00263     do {
00264         dd->reordered = 0;
00265         res = addBddDoInterval(dd, f, l, u);
00266     } while (dd->reordered == 1);
00267 
00268     if (res == NULL) {
00269         Cudd_RecursiveDeref(dd, l);
00270         Cudd_RecursiveDeref(dd, u);
00271         return(NULL);
00272     }
00273     cuddRef(res);
00274     Cudd_RecursiveDeref(dd, l);
00275     Cudd_RecursiveDeref(dd, u);
00276     cuddDeref(res);
00277     return(res);
00278 
00279 } /* end of Cudd_addBddInterval */

DdNode* Cudd_addBddIthBit ( DdManager dd,
DdNode f,
int  bit 
)

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

Synopsis [Converts an ADD to a BDD by extracting the i-th bit from the leaves.]

Description [Converts an ADD to a BDD by replacing all discriminants whose i-th bit is equal to 1 with 1, and all other discriminants with 0. The i-th bit refers to the integer representation of the leaf value. If the value is has a fractional part, it is ignored. Repeated calls to this procedure allow one to transform an integer-valued ADD into an array of BDDs, one for each bit of the leaf values. Returns a pointer to the resulting BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd]

Definition at line 302 of file cuddBridge.c.

00306 {
00307     DdNode *res;
00308     DdNode *index;
00309     
00310     index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit);
00311     if (index == NULL) return(NULL);
00312     cuddRef(index);
00313 
00314     do {
00315         dd->reordered = 0;
00316         res = addBddDoIthBit(dd, f, index);
00317     } while (dd->reordered == 1);
00318 
00319     if (res == NULL) {
00320         Cudd_RecursiveDeref(dd, index);
00321         return(NULL);
00322     }
00323     cuddRef(res);
00324     Cudd_RecursiveDeref(dd, index);
00325     cuddDeref(res);
00326     return(res);
00327 
00328 } /* end of Cudd_addBddIthBit */

DdNode* Cudd_addBddPattern ( DdManager dd,
DdNode f 
)

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

Synopsis [Converts an ADD to a BDD.]

Description [Converts an ADD to a BDD by replacing all discriminants different from 0 with 1. Returns a pointer to the resulting BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_BddToAdd Cudd_addBddThreshold Cudd_addBddInterval Cudd_addBddStrictThreshold]

Definition at line 375 of file cuddBridge.c.

00378 {
00379     DdNode *res;
00380     
00381     do {
00382         dd->reordered = 0;
00383         res = cuddAddBddDoPattern(dd, f);
00384     } while (dd->reordered == 1);
00385     return(res);
00386 
00387 } /* end of Cudd_addBddPattern */

DdNode* Cudd_addBddStrictThreshold ( DdManager dd,
DdNode f,
CUDD_VALUE_TYPE  value 
)

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

Synopsis [Converts an ADD to a BDD.]

Description [Converts an ADD to a BDD by replacing all discriminants STRICTLY greater than value with 1, and all other discriminants with 0. Returns a pointer to the resulting BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd Cudd_addBddThreshold]

Definition at line 195 of file cuddBridge.c.

00199 {
00200     DdNode *res;
00201     DdNode *val;
00202     
00203     val = cuddUniqueConst(dd,value);
00204     if (val == NULL) return(NULL);
00205     cuddRef(val);
00206 
00207     do {
00208         dd->reordered = 0;
00209         res = addBddDoStrictThreshold(dd, f, val);
00210     } while (dd->reordered == 1);
00211 
00212     if (res == NULL) {
00213         Cudd_RecursiveDeref(dd, val);
00214         return(NULL);
00215     }
00216     cuddRef(res);
00217     Cudd_RecursiveDeref(dd, val);
00218     cuddDeref(res);
00219     return(res);
00220 
00221 } /* end of Cudd_addBddStrictThreshold */

DdNode* Cudd_addBddThreshold ( DdManager dd,
DdNode f,
CUDD_VALUE_TYPE  value 
)

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

Synopsis [Converts an ADD to a BDD.]

Description [Converts an ADD to a BDD by replacing all discriminants greater than or equal to value with 1, and all other discriminants with 0. Returns a pointer to the resulting BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addBddInterval Cudd_addBddPattern Cudd_BddToAdd Cudd_addBddStrictThreshold]

Definition at line 150 of file cuddBridge.c.

00154 {
00155     DdNode *res;
00156     DdNode *val;
00157     
00158     val = cuddUniqueConst(dd,value);
00159     if (val == NULL) return(NULL);
00160     cuddRef(val);
00161 
00162     do {
00163         dd->reordered = 0;
00164         res = addBddDoThreshold(dd, f, val);
00165     } while (dd->reordered == 1);
00166 
00167     if (res == NULL) {
00168         Cudd_RecursiveDeref(dd, val);
00169         return(NULL);
00170     }
00171     cuddRef(res);
00172     Cudd_RecursiveDeref(dd, val);
00173     cuddDeref(res);
00174     return(res);
00175 
00176 } /* end of Cudd_addBddThreshold */

DdNode* Cudd_addCmpl ( DdManager dd,
DdNode f 
)

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

Synopsis [Computes the complement of an ADD a la C language.]

Description [Computes the complement of an ADD a la C language: The complement of 0 is 1 and the complement of everything else is 0. Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addNegate]

Definition at line 343 of file cuddAddIte.c.

00346 {
00347     DdNode *res;
00348 
00349     do {
00350         dd->reordered = 0;
00351         res = cuddAddCmplRecur(dd,f);
00352     } while (dd->reordered == 1);
00353     return(res);
00354 
00355 } /* end of Cudd_addCmpl */

DdNode* Cudd_addCompose ( DdManager dd,
DdNode f,
DdNode g,
int  v 
)

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

Synopsis [Substitutes g for x_v in the ADD for f.]

Description [Substitutes g for x_v in the ADD for f. v is the index of the variable to be substituted. g must be a 0-1 ADD. Cudd_bddCompose passes the corresponding projection function to the recursive procedure, so that the cache may be used. Returns the composed ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddCompose]

Definition at line 200 of file cuddCompose.c.

00205 {
00206     DdNode *proj, *res;
00207 
00208     /* Sanity check. */
00209     if (v < 0 || v >= dd->size) return(NULL);
00210 
00211     proj =  dd->vars[v];
00212     do {
00213         dd->reordered = 0;
00214         res = cuddAddComposeRecur(dd,f,g,proj);
00215     } while (dd->reordered == 1);
00216     return(res);
00217 
00218 } /* end of Cudd_addCompose */

DdNode* Cudd_addComputeCube ( DdManager dd,
DdNode **  vars,
int *  phase,
int  n 
)

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

Synopsis [Computes the cube of an array of ADD variables.]

Description [Computes the cube of an array of ADD variables. If non-null, the phase argument indicates which literal of each variable should appear in the cube. If phase\[i\] is nonzero, then the positive literal is used. If phase is NULL, the cube is positive unate. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [none]

SeeAlso [Cudd_bddComputeCube]

Definition at line 2242 of file cuddUtil.c.

02247 {
02248     DdNode      *cube, *zero;
02249     DdNode      *fn;
02250     int         i;
02251 
02252     cube = DD_ONE(dd);
02253     cuddRef(cube);
02254     zero = DD_ZERO(dd);
02255 
02256     for (i = n - 1; i >= 0; i--) {
02257         if (phase == NULL || phase[i] != 0) {
02258             fn = Cudd_addIte(dd,vars[i],cube,zero);
02259         } else {
02260             fn = Cudd_addIte(dd,vars[i],zero,cube);
02261         }
02262         if (fn == NULL) {
02263             Cudd_RecursiveDeref(dd,cube);
02264             return(NULL);
02265         }
02266         cuddRef(fn);
02267         Cudd_RecursiveDeref(dd,cube);
02268         cube = fn;
02269     }
02270     cuddDeref(cube);
02271 
02272     return(cube);
02273 
02274 } /* end of Cudd_addComputeCube */

DdNode* Cudd_addConst ( DdManager dd,
CUDD_VALUE_TYPE  c 
)

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

Synopsis [Returns the ADD for constant c.]

Description [Retrieves the ADD for constant c if it already exists, or creates a new ADD. Returns a pointer to the ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addNewVar Cudd_addIthVar]

Definition at line 616 of file cuddAPI.c.

00619 {
00620     return(cuddUniqueConst(dd,c));
00621 
00622 } /* end of Cudd_addConst */

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

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

Synopsis [Computes f constrain c for ADDs.]

Description [Computes f constrain c (f @ c), for f an ADD and c a 0-1 ADD. List of special cases:

  • F @ 0 = 0
  • F @ 1 = F
  • 0 @ c = 0
  • 1 @ c = 1
  • F @ F = 1

Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddConstrain]

Definition at line 332 of file cuddGenCof.c.

00336 {
00337     DdNode *res;
00338 
00339     do {
00340         dd->reordered = 0;
00341         res = cuddAddConstrainRecur(dd,f,c);
00342     } while (dd->reordered == 1);
00343     return(res);
00344 
00345 } /* end of Cudd_addConstrain */

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

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

Synopsis [Returns plusinfinity if f=g; returns min(f,g) if f!=g.]

Description [Returns NULL if not a terminal case; f op g otherwise, where f op g is plusinfinity if f=g; min(f,g) if f!=g.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 507 of file cuddAddApply.c.

00511 {
00512     DdNode *F, *G;
00513 
00514     F = *f; G = *g;
00515     if (F == G) return(DD_PLUS_INFINITY(dd));
00516     if (F == DD_PLUS_INFINITY(dd)) return(G);
00517     if (G == DD_PLUS_INFINITY(dd)) return(F);
00518     if (cuddIsConstant(F) && cuddIsConstant(G)) {
00519         if (cuddV(F) != cuddV(G)) {
00520             if (cuddV(F) < cuddV(G)) {
00521                 return(F);
00522             } else {
00523                 return(G);
00524             }
00525         } else {
00526             return(DD_PLUS_INFINITY(dd));
00527         }
00528     }
00529     return(NULL);
00530 
00531 } /* end of Cudd_addDiff */

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

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

Synopsis [Integer and floating point division.]

Description [Integer and floating point division. Returns NULL if not a terminal case; f / g otherwise.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 308 of file cuddAddApply.c.

00312 {
00313     DdNode *res;
00314     DdNode *F, *G;
00315     CUDD_VALUE_TYPE value;
00316 
00317     F = *f; G = *g;
00318     /* We would like to use F == G -> F/G == 1, but F and G may
00319     ** contain zeroes. */
00320     if (F == DD_ZERO(dd)) return(DD_ZERO(dd));
00321     if (G == DD_ONE(dd)) return(F);
00322     if (cuddIsConstant(F) && cuddIsConstant(G)) {
00323         value = cuddV(F)/cuddV(G);
00324         res = cuddUniqueConst(dd,value);
00325         return(res);
00326     }
00327     return(NULL);
00328 
00329 } /* end of Cudd_addDivide */

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

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

Synopsis [Checks whether ADD g is constant whenever ADD f is 1.]

Description [Checks whether ADD g is constant whenever ADD f is 1. f must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may or may not be constant) or DD_NON_CONSTANT. If f is identically 0, the check is assumed to be successful, and the background value is returned. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_addIteConstant Cudd_addLeq]

Definition at line 256 of file cuddAddIte.c.

00260 {
00261     DdNode *zero;
00262     DdNode *Fv,*Fnv,*Gv,*Gnv,*r,*t,*e;
00263     unsigned int topf,topg;
00264 
00265 #ifdef DD_DEBUG
00266     assert(!Cudd_IsComplement(f));
00267 #endif
00268 
00269     statLine(dd);
00270     /* Terminal cases. */
00271     if (f == DD_ONE(dd) || cuddIsConstant(g)) {
00272         return(g);
00273     }
00274     if (f == (zero = DD_ZERO(dd))) {
00275         return(dd->background);
00276     }
00277 
00278 #ifdef DD_DEBUG
00279     assert(!cuddIsConstant(f));
00280 #endif
00281     /* From now on, f and g are known not to be constants. */
00282 
00283     topf = cuddI(dd,f->index);
00284     topg = cuddI(dd,g->index);
00285 
00286     /* Check cache. */
00287     r = cuddConstantLookup(dd,DD_ADD_EVAL_CONST_TAG,f,g,g);
00288     if (r != NULL) {
00289         return(r);
00290     }
00291 
00292     /* Compute cofactors. */
00293     if (topf <= topg) {
00294         Fv = cuddT(f); Fnv = cuddE(f);
00295     } else {
00296         Fv = Fnv = f;
00297     }
00298     if (topg <= topf) {
00299         Gv = cuddT(g); Gnv = cuddE(g);
00300     } else {
00301         Gv = Gnv = g;
00302     }
00303     
00304     /* Recursive step. */
00305     if (Fv != zero) {
00306         t = Cudd_addEvalConst(dd,Fv,Gv);
00307         if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) {
00308             cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT);
00309             return(DD_NON_CONSTANT);
00310         }
00311         if (Fnv != zero) {
00312             e = Cudd_addEvalConst(dd,Fnv,Gnv);
00313             if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) {
00314                 cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT);
00315                 return(DD_NON_CONSTANT);
00316             }
00317         }
00318         cuddCacheInsert2(dd,Cudd_addEvalConst,f,g,t);
00319         return(t);
00320     } else { /* Fnv must be != zero */
00321         e = Cudd_addEvalConst(dd,Fnv,Gnv);
00322         cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e);
00323         return(e);
00324     }
00325 
00326 } /* end of Cudd_addEvalConst */

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

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

Synopsis [Existentially Abstracts all the variables in cube from f.]

Description [Abstracts all the variables in cube from f by summing over all possible values taken by the variables. Returns the abstracted ADD.]

SideEffects [None]

SeeAlso [Cudd_addUnivAbstract Cudd_bddExistAbstract Cudd_addOrAbstract]

Definition at line 125 of file cuddAddAbs.c.

00129 {
00130     DdNode *res;
00131 
00132     two = cuddUniqueConst(manager,(CUDD_VALUE_TYPE) 2);
00133     if (two == NULL) return(NULL);
00134     cuddRef(two);
00135 
00136     if (addCheckPositiveCube(manager, cube) == 0) {
00137         (void) fprintf(manager->err,"Error: Can only abstract cubes");
00138         return(NULL);
00139     }
00140 
00141     do {
00142         manager->reordered = 0;
00143         res = cuddAddExistAbstractRecur(manager, f, cube);
00144     } while (manager->reordered == 1);
00145 
00146     if (res == NULL) {
00147         Cudd_RecursiveDeref(manager,two);
00148         return(NULL);
00149     }
00150     cuddRef(res);
00151     Cudd_RecursiveDeref(manager,two);
00152     cuddDeref(res);
00153 
00154     return(res);
00155 
00156 } /* end of Cudd_addExistAbstract */

DdNode* Cudd_addFindMax ( DdManager dd,
DdNode f 
)

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

Synopsis [Finds the maximum discriminant of f.]

Description [Returns a pointer to a constant ADD.]

SideEffects [None]

Definition at line 120 of file cuddAddFind.c.

00123 {
00124     DdNode *t, *e, *res;
00125 
00126     statLine(dd);
00127     if (cuddIsConstant(f)) {
00128         return(f);
00129     }
00130 
00131     res = cuddCacheLookup1(dd,Cudd_addFindMax,f);
00132     if (res != NULL) {
00133         return(res);
00134     }
00135 
00136     t  = Cudd_addFindMax(dd,cuddT(f));
00137     if (t == DD_PLUS_INFINITY(dd)) return(t);
00138 
00139     e  = Cudd_addFindMax(dd,cuddE(f));
00140 
00141     res = (cuddV(t) >= cuddV(e)) ? t : e;
00142 
00143     cuddCacheInsert1(dd,Cudd_addFindMax,f,res);
00144 
00145     return(res);
00146 
00147 } /* end of Cudd_addFindMax */

DdNode* Cudd_addFindMin ( DdManager dd,
DdNode f 
)

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

Synopsis [Finds the minimum discriminant of f.]

Description [Returns a pointer to a constant ADD.]

SideEffects [None]

Definition at line 160 of file cuddAddFind.c.

00163 {
00164     DdNode *t, *e, *res;
00165 
00166     statLine(dd);
00167     if (cuddIsConstant(f)) {
00168         return(f);
00169     }
00170 
00171     res = cuddCacheLookup1(dd,Cudd_addFindMin,f);
00172     if (res != NULL) {
00173         return(res);
00174     }
00175 
00176     t  = Cudd_addFindMin(dd,cuddT(f));
00177     if (t == DD_MINUS_INFINITY(dd)) return(t);
00178 
00179     e  = Cudd_addFindMin(dd,cuddE(f));
00180 
00181     res = (cuddV(t) <= cuddV(e)) ? t : e;
00182 
00183     cuddCacheInsert1(dd,Cudd_addFindMin,f,res);
00184 
00185     return(res);
00186 
00187 } /* end of Cudd_addFindMin */

DdNode* Cudd_addGeneralVectorCompose ( DdManager dd,
DdNode f,
DdNode **  vectorOn,
DdNode **  vectorOff 
)

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

Synopsis [Composes an ADD with a vector of ADDs.]

Description [Given a vector of ADDs, creates a new ADD by substituting the ADDs for the variables of the ADD f. vectorOn contains ADDs to be substituted for the x_v and vectorOff the ADDs to be substituted for x_v'. There should be an entry in vector for each variable in the manager. If no substitution is sought for a given variable, the corresponding projection function should be specified in the vector. This function implements simultaneous composition. Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addVectorCompose Cudd_addNonSimCompose Cudd_addPermute Cudd_addCompose Cudd_bddVectorCompose]

Definition at line 617 of file cuddCompose.c.

00622 {
00623     DdHashTable         *table;
00624     DdNode              *res;
00625     int                 deepest;
00626     int                 i;
00627 
00628     do {
00629         dd->reordered = 0;
00630         /* Initialize local cache. */
00631         table = cuddHashTableInit(dd,1,2);
00632         if (table == NULL) return(NULL);
00633 
00634         /* Find deepest real substitution. */
00635         for (deepest = dd->size - 1; deepest >= 0; deepest--) {
00636             i = dd->invperm[deepest];
00637             if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) {
00638                 break;
00639             }
00640         }
00641 
00642         /* Recursively solve the problem. */
00643         res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn,
00644                                                vectorOff,deepest);
00645         if (res != NULL) cuddRef(res);
00646 
00647         /* Dispose of local cache. */
00648         cuddHashTableQuit(table);
00649     } while (dd->reordered == 1);
00650 
00651     if (res != NULL) cuddDeref(res);
00652     return(res);
00653 
00654 } /* end of Cudd_addGeneralVectorCompose */

DdNode* Cudd_addHamming ( DdManager dd,
DdNode **  xVars,
DdNode **  yVars,
int  nVars 
)

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

Synopsis [Computes the Hamming distance ADD.]

Description [Computes the Hamming distance ADD. Returns an ADD that gives the Hamming distance between its two arguments if successful; NULL otherwise. The two vectors xVars and yVars identify the variables that form the two arguments.]

SideEffects [None]

SeeAlso []

Definition at line 1251 of file cuddPriority.c.

01256 {
01257     DdNode  *result,*tempBdd;
01258     DdNode  *tempAdd,*temp;
01259     int     i;
01260 
01261     result = DD_ZERO(dd);
01262     cuddRef(result);
01263 
01264     for (i = 0; i < nVars; i++) {
01265         tempBdd = Cudd_bddIte(dd,xVars[i],Cudd_Not(yVars[i]),yVars[i]);
01266         if (tempBdd == NULL) {
01267             Cudd_RecursiveDeref(dd,result);
01268             return(NULL);
01269         }
01270         cuddRef(tempBdd);
01271         tempAdd = Cudd_BddToAdd(dd,tempBdd);
01272         if (tempAdd == NULL) {
01273             Cudd_RecursiveDeref(dd,tempBdd);
01274             Cudd_RecursiveDeref(dd,result);
01275             return(NULL);
01276         }
01277         cuddRef(tempAdd);
01278         Cudd_RecursiveDeref(dd,tempBdd);
01279         temp = Cudd_addApply(dd,Cudd_addPlus,tempAdd,result);
01280         if (temp == NULL) {
01281             Cudd_RecursiveDeref(dd,tempAdd);
01282             Cudd_RecursiveDeref(dd,result);
01283             return(NULL);
01284         }
01285         cuddRef(temp);
01286         Cudd_RecursiveDeref(dd,tempAdd);
01287         Cudd_RecursiveDeref(dd,result);
01288         result = temp;
01289     }
01290 
01291     cuddDeref(result);
01292     return(result);
01293 
01294 } /* end of Cudd_addHamming */

int Cudd_addHarwell ( FILE *  fp,
DdManager dd,
DdNode **  E,
DdNode ***  x,
DdNode ***  y,
DdNode ***  xn,
DdNode ***  yn_,
int *  nx,
int *  ny,
int *  m,
int *  n,
int  bx,
int  sx,
int  by,
int  sy,
int  pr 
)

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

Synopsis [Reads in a matrix in the format of the Harwell-Boeing benchmark suite.]

Description [Reads in a matrix in the format of the Harwell-Boeing benchmark suite. The variables are ordered as follows: <blockquote> x\[0\] y\[0\] x\[1\] y\[1\] ... </blockquote> 0 is the most significant bit. On input, nx and ny hold the numbers of row and column variables already in existence. On output, they hold the numbers of row and column variables actually used by the matrix. m and n are set to the numbers of rows and columns of the matrix. Their values on input are immaterial. Returns 1 on success; 0 otherwise. The ADD for the sparse matrix is returned in E, and its reference count is > 0.]

SideEffects [None]

SeeAlso [Cudd_addRead Cudd_bddRead]

Definition at line 120 of file cuddHarwell.c.

00137 {
00138     DdNode *one, *zero;
00139     DdNode *w;
00140     DdNode *cubex, *cubey, *minterm1;
00141     int u, v, err, i, j, nv;
00142     double val;
00143     DdNode **lx, **ly, **lxn, **lyn;    /* local copies of x, y, xn, yn_ */
00144     int lnx, lny;                       /* local copies of nx and ny */
00145     char title[73], key[9], mxtype[4], rhstyp[4];
00146     int totcrd, ptrcrd, indcrd, valcrd, rhscrd,
00147         nrow, ncol, nnzero, neltvl,
00148         nrhs, nrhsix;
00149     int *colptr, *rowind;
00150 #if 0
00151     int nguess, nexact;
00152     int *rhsptr, *rhsind;
00153 #endif
00154 
00155     if (*nx < 0 || *ny < 0) return(0);
00156 
00157     one = DD_ONE(dd);
00158     zero = DD_ZERO(dd);
00159 
00160     /* Read the header */
00161     err = fscanf(fp, "%72c %8c", title, key);
00162     if (err == EOF) {
00163         return(0);
00164     } else if (err != 2) {
00165         return(0);
00166     }
00167     title[72] = (char) 0;
00168     key[8] = (char) 0;
00169 
00170     err = fscanf(fp, "%d %d %d %d %d", &totcrd, &ptrcrd, &indcrd,
00171     &valcrd, &rhscrd);
00172     if (err == EOF) {
00173         return(0);
00174     } else if (err != 5) {
00175         return(0);
00176     }
00177 
00178     err = fscanf(fp, "%3s %d %d %d %d", mxtype, &nrow, &ncol,
00179     &nnzero, &neltvl);
00180     if (err == EOF) {
00181         return(0);
00182     } else if (err != 5) {
00183         return(0);
00184     }
00185 
00186     /* Skip FORTRAN formats */
00187     if (rhscrd == 0) {
00188         err = fscanf(fp, "%*s %*s %*s \n");
00189     } else {
00190         err = fscanf(fp, "%*s %*s %*s %*s \n");
00191     }
00192     if (err == EOF) {
00193         return(0);
00194     } else if (err != 0) {
00195         return(0);
00196     }
00197 
00198     /* Print out some stuff if requested to be verbose */
00199     if (pr>0) {
00200         (void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key,
00201         mxtype, nrow, ncol, nnzero);
00202         if (pr>1) (void) fprintf(dd->out,"%s\n", title);
00203     }
00204 
00205     /* Check matrix type */
00206     if (mxtype[0] != 'R' || mxtype[1] != 'U' || mxtype[2] != 'A') {
00207         (void) fprintf(dd->err,"%s: Illegal matrix type: %s\n",
00208                        key, mxtype);
00209         return(0);
00210     }
00211     if (neltvl != 0) return(0);
00212 
00213     /* Read optional 5-th line */
00214     if (rhscrd != 0) {
00215         err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix);
00216         if (err == EOF) {
00217             return(0);
00218         } else if (err != 3) {
00219             return(0);
00220         }
00221         rhstyp[3] = (char) 0;
00222         if (rhstyp[0] != 'F') {
00223             (void) fprintf(dd->err,
00224             "%s: Sparse right-hand side not yet supported\n", key);
00225             return(0);
00226         }
00227         if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs);
00228     } else {
00229         nrhs = 0;
00230     }
00231 
00232     /* Compute the number of variables */
00233 
00234     /* row and column numbers start from 0 */
00235     u = nrow - 1;
00236     for (i=0; u > 0; i++) {
00237         u >>= 1;
00238     }
00239     lnx = i;
00240     if (nrhs == 0) {
00241         v = ncol - 1;
00242     } else {
00243         v = 2* (ddMax(ncol, nrhs) - 1);
00244     }
00245     for (i=0; v > 0; i++) {
00246         v >>= 1;
00247     }
00248     lny = i;
00249 
00250     /* Allocate or reallocate arrays for variables as needed */
00251     if (*nx == 0) {
00252         if (lnx > 0) {
00253             *x = lx = ALLOC(DdNode *,lnx);
00254             if (lx == NULL) {
00255                 dd->errorCode = CUDD_MEMORY_OUT;
00256                 return(0);
00257             }
00258             *xn = lxn =  ALLOC(DdNode *,lnx);
00259             if (lxn == NULL) {
00260                 dd->errorCode = CUDD_MEMORY_OUT;
00261                 return(0);
00262             }
00263         } else {
00264             *x = *xn = NULL;
00265         }
00266     } else if (lnx > *nx) {
00267         *x = lx = REALLOC(DdNode *, *x, lnx);
00268         if (lx == NULL) {
00269             dd->errorCode = CUDD_MEMORY_OUT;
00270             return(0);
00271         }
00272         *xn = lxn =  REALLOC(DdNode *, *xn, lnx);
00273         if (lxn == NULL) {
00274             dd->errorCode = CUDD_MEMORY_OUT;
00275             return(0);
00276         }
00277     } else {
00278         lx = *x;
00279         lxn = *xn;
00280     }
00281     if (*ny == 0) {
00282         if (lny >0) {
00283             *y = ly = ALLOC(DdNode *,lny);
00284             if (ly == NULL) {
00285                 dd->errorCode = CUDD_MEMORY_OUT;
00286                 return(0);
00287             }
00288             *yn_ = lyn = ALLOC(DdNode *,lny);
00289             if (lyn == NULL) {
00290                 dd->errorCode = CUDD_MEMORY_OUT;
00291                 return(0);
00292             }
00293         } else {
00294             *y = *yn_ = NULL;
00295         }
00296     } else if (lny > *ny) {
00297         *y = ly = REALLOC(DdNode *, *y, lny);
00298         if (ly == NULL) {
00299             dd->errorCode = CUDD_MEMORY_OUT;
00300             return(0);
00301         }
00302         *yn_ = lyn = REALLOC(DdNode *, *yn_, lny);
00303         if (lyn == NULL) {
00304             dd->errorCode = CUDD_MEMORY_OUT;
00305             return(0);
00306         }
00307     } else {
00308         ly = *y;
00309         lyn = *yn_;
00310     }
00311 
00312     /* Create new variables as needed */
00313     for (i= *nx,nv=bx+(*nx)*sx; i < lnx; i++,nv+=sx) {
00314         do {
00315             dd->reordered = 0;
00316             lx[i] = cuddUniqueInter(dd, nv, one, zero);
00317         } while (dd->reordered == 1);
00318         if (lx[i] == NULL) return(0);
00319         cuddRef(lx[i]);
00320         do {
00321             dd->reordered = 0;
00322             lxn[i] = cuddUniqueInter(dd, nv, zero, one);
00323         } while (dd->reordered == 1);
00324         if (lxn[i] == NULL) return(0);
00325         cuddRef(lxn[i]);
00326     }
00327     for (i= *ny,nv=by+(*ny)*sy; i < lny; i++,nv+=sy) {
00328         do {
00329             dd->reordered = 0;
00330             ly[i] = cuddUniqueInter(dd, nv, one, zero);
00331         } while (dd->reordered == 1);
00332         if (ly[i] == NULL) return(0);
00333         cuddRef(ly[i]);
00334         do {
00335             dd->reordered = 0;
00336             lyn[i] = cuddUniqueInter(dd, nv, zero, one);
00337         } while (dd->reordered == 1);
00338         if (lyn[i] == NULL) return(0);
00339         cuddRef(lyn[i]);
00340     }
00341 
00342     /* Update matrix parameters */
00343     *nx = lnx;
00344     *ny = lny;
00345     *m = nrow;
00346     if (nrhs == 0) {
00347         *n = ncol;
00348     } else {
00349         *n = (1 << (lny - 1)) + nrhs;
00350     }
00351     
00352     /* Read structure data */
00353     colptr = ALLOC(int, ncol+1);
00354     if (colptr == NULL) {
00355         dd->errorCode = CUDD_MEMORY_OUT;
00356         return(0);
00357     }
00358     rowind = ALLOC(int, nnzero);
00359     if (rowind == NULL) {
00360         dd->errorCode = CUDD_MEMORY_OUT;
00361         return(0);
00362     }
00363 
00364     for (i=0; i<ncol+1; i++) {
00365         err = fscanf(fp, " %d ", &u);
00366         if (err == EOF){ 
00367             FREE(colptr);
00368             FREE(rowind);
00369             return(0);
00370         } else if (err != 1) {
00371             FREE(colptr);
00372             FREE(rowind);
00373             return(0);
00374         }
00375         colptr[i] = u - 1;
00376     }
00377     if (colptr[0] != 0) {
00378         (void) fprintf(dd->err,"%s: Unexpected colptr[0] (%d)\n",
00379                        key,colptr[0]);
00380         FREE(colptr);
00381         FREE(rowind);
00382         return(0);
00383     }
00384     for (i=0; i<nnzero; i++) {
00385         err = fscanf(fp, " %d ", &u);
00386         if (err == EOF){ 
00387             FREE(colptr);
00388             FREE(rowind);
00389             return(0);
00390         } else if (err != 1) {
00391             FREE(colptr);
00392             FREE(rowind);
00393             return(0);
00394         }
00395         rowind[i] = u - 1;
00396     }
00397 
00398     *E = zero; cuddRef(*E);
00399 
00400     for (j=0; j<ncol; j++) {
00401         v = j;
00402         cubey = one; cuddRef(cubey);
00403         for (nv = lny - 1; nv>=0; nv--) {
00404             if (v & 1) {
00405                 w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]);
00406             } else {
00407                 w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]);
00408             }
00409             if (w == NULL) {
00410                 Cudd_RecursiveDeref(dd, cubey);
00411                 FREE(colptr);
00412                 FREE(rowind);
00413                 return(0);
00414             }
00415             cuddRef(w);
00416             Cudd_RecursiveDeref(dd, cubey);
00417             cubey = w;
00418             v >>= 1;
00419         }
00420         for (i=colptr[j]; i<colptr[j+1]; i++) {
00421             u = rowind[i];
00422             err = fscanf(fp, " %lf ", &val);
00423             if (err == EOF || err != 1){ 
00424                 Cudd_RecursiveDeref(dd, cubey);
00425                 FREE(colptr);
00426                 FREE(rowind);
00427                 return(0);
00428             }
00429             /* Create new Constant node if necessary */
00430             cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val);
00431             if (cubex == NULL) {
00432                 Cudd_RecursiveDeref(dd, cubey);
00433                 FREE(colptr);
00434                 FREE(rowind);
00435                 return(0);
00436             }
00437             cuddRef(cubex);
00438 
00439             for (nv = lnx - 1; nv>=0; nv--) {
00440                 if (u & 1) {
00441                     w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]);
00442                 } else { 
00443                     w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]);
00444                 }
00445                 if (w == NULL) {
00446                     Cudd_RecursiveDeref(dd, cubey);
00447                     Cudd_RecursiveDeref(dd, cubex);
00448                     FREE(colptr);
00449                     FREE(rowind);
00450                     return(0);
00451                 }
00452                 cuddRef(w);
00453                 Cudd_RecursiveDeref(dd, cubex);
00454                 cubex = w;
00455                 u >>= 1;
00456             }
00457             minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex);
00458             if (minterm1 == NULL) {
00459                 Cudd_RecursiveDeref(dd, cubey);
00460                 Cudd_RecursiveDeref(dd, cubex);
00461                 FREE(colptr);
00462                 FREE(rowind);
00463                 return(0);
00464             }
00465             cuddRef(minterm1);
00466             Cudd_RecursiveDeref(dd, cubex);
00467             w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1);
00468             if (w == NULL) {
00469                 Cudd_RecursiveDeref(dd, cubey);
00470                 FREE(colptr);
00471                 FREE(rowind);
00472                 return(0);
00473             }
00474             cuddRef(w);
00475             Cudd_RecursiveDeref(dd, minterm1);
00476             Cudd_RecursiveDeref(dd, *E);
00477             *E = w;
00478         }
00479         Cudd_RecursiveDeref(dd, cubey);
00480     }
00481     FREE(colptr);
00482     FREE(rowind);
00483 
00484     /* Read right-hand sides */
00485     for (j=0; j<nrhs; j++) {
00486         v = j + (1<< (lny-1));
00487         cubey = one; cuddRef(cubey);
00488         for (nv = lny - 1; nv>=0; nv--) {
00489             if (v & 1) {
00490                 w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]);
00491             } else {
00492                 w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]);
00493             }
00494             if (w == NULL) {
00495                 Cudd_RecursiveDeref(dd, cubey);
00496                 return(0);
00497             }
00498             cuddRef(w);
00499             Cudd_RecursiveDeref(dd, cubey);
00500             cubey = w;
00501             v >>= 1;
00502         }
00503         for (i=0; i<nrow; i++) {
00504             u = i;
00505             err = fscanf(fp, " %lf ", &val);
00506             if (err == EOF || err != 1){ 
00507                 Cudd_RecursiveDeref(dd, cubey);
00508                 return(0);
00509             }
00510             /* Create new Constant node if necessary */
00511             if (val == (double) 0.0) continue;
00512             cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val);
00513             if (cubex == NULL) {
00514                 Cudd_RecursiveDeref(dd, cubey);
00515                 return(0);
00516             }
00517             cuddRef(cubex);
00518 
00519             for (nv = lnx - 1; nv>=0; nv--) {
00520                 if (u & 1) {
00521                    w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]);
00522                 } else { 
00523                     w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]);
00524                 }
00525                 if (w == NULL) {
00526                     Cudd_RecursiveDeref(dd, cubey);
00527                     Cudd_RecursiveDeref(dd, cubex);
00528                     return(0);
00529                 }
00530                 cuddRef(w);
00531                 Cudd_RecursiveDeref(dd, cubex);
00532                 cubex = w;
00533                 u >>= 1;
00534             }
00535             minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex);
00536             if (minterm1 == NULL) {
00537                 Cudd_RecursiveDeref(dd, cubey);
00538                 Cudd_RecursiveDeref(dd, cubex);
00539                 return(0);
00540             }
00541             cuddRef(minterm1);
00542             Cudd_RecursiveDeref(dd, cubex);
00543             w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1);
00544             if (w == NULL) {
00545                 Cudd_RecursiveDeref(dd, cubey);
00546                 return(0);
00547             }
00548             cuddRef(w);
00549             Cudd_RecursiveDeref(dd, minterm1);
00550             Cudd_RecursiveDeref(dd, *E);
00551             *E = w;
00552         }
00553         Cudd_RecursiveDeref(dd, cubey);
00554     }
00555 
00556     return(1);
00557 
00558 } /* end of Cudd_addHarwell */

int Cudd_AddHook ( DdManager dd,
DD_HFP  f,
Cudd_HookType  where 
)

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

Synopsis [Adds a function to a hook.]

Description [Adds a function to a hook. A hook is a list of application-provided functions called on certain occasions by the package. Returns 1 if the function is successfully added; 2 if the function was already in the list; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_RemoveHook]

Definition at line 3241 of file cuddAPI.c.

03245 {
03246     DdHook **hook, *nextHook, *newHook;
03247 
03248     switch (where) {
03249     case CUDD_PRE_GC_HOOK:
03250         hook = &(dd->preGCHook);
03251         break;
03252     case CUDD_POST_GC_HOOK:
03253         hook = &(dd->postGCHook);
03254         break;
03255     case CUDD_PRE_REORDERING_HOOK:
03256         hook = &(dd->preReorderingHook);
03257         break;
03258     case CUDD_POST_REORDERING_HOOK:
03259         hook = &(dd->postReorderingHook);
03260         break;
03261     default:
03262         return(0);
03263     }
03264     /* Scan the list and find whether the function is already there.
03265     ** If so, just return. */
03266     nextHook = *hook;
03267     while (nextHook != NULL) {
03268         if (nextHook->f == f) {
03269             return(2);
03270         }
03271         hook = &(nextHook->next);
03272         nextHook = nextHook->next;
03273     }
03274     /* The function was not in the list. Create a new item and append it
03275     ** to the end of the list. */
03276     newHook = ALLOC(DdHook,1);
03277     if (newHook == NULL) {
03278         dd->errorCode = CUDD_MEMORY_OUT;
03279         return(0);
03280     }
03281     newHook->next = NULL;
03282     newHook->f = f;
03283     *hook = newHook;
03284     return(1);
03285 
03286 } /* end of Cudd_AddHook */

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

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

Synopsis [Implements ITE(f,g,h).]

Description [Implements ITE(f,g,h). This procedure assumes that f is a 0-1 ADD. Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addIteConstant Cudd_addApply]

Definition at line 125 of file cuddAddIte.c.

00130 {
00131     DdNode *res;
00132 
00133     do {
00134         dd->reordered = 0;
00135         res = cuddAddIteRecur(dd,f,g,h);
00136     } while (dd->reordered == 1);
00137     return(res);
00138 
00139 } /* end of Cudd_addIte */

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

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

Synopsis [Implements ITEconstant for ADDs.]

Description [Implements ITEconstant for ADDs. f must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may or may not be constant) or DD_NON_CONSTANT. No new nodes are created. This function can be used, for instance, to check that g has a constant value (specified by h) whenever f is 1. If the constant value is unknown, then one should use Cudd_addEvalConst.]

SideEffects [None]

SeeAlso [Cudd_addIte Cudd_addEvalConst Cudd_bddIteConstant]

Definition at line 159 of file cuddAddIte.c.

00164 {
00165     DdNode *one,*zero;
00166     DdNode *Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*r,*t,*e;
00167     unsigned int topf,topg,toph,v;
00168 
00169     statLine(dd);
00170     /* Trivial cases. */
00171     if (f == (one = DD_ONE(dd))) {      /* ITE(1,G,H) = G */
00172         return(g);
00173     }
00174     if (f == (zero = DD_ZERO(dd))) {    /* ITE(0,G,H) = H */
00175         return(h);
00176     }
00177 
00178     /* From now on, f is known not to be a constant. */
00179     addVarToConst(f,&g,&h,one,zero);
00180 
00181     /* Check remaining one variable cases. */
00182     if (g == h) {                       /* ITE(F,G,G) = G */
00183         return(g);
00184     }
00185     if (cuddIsConstant(g) && cuddIsConstant(h)) {
00186         return(DD_NON_CONSTANT);
00187     }
00188 
00189     topf = cuddI(dd,f->index);
00190     topg = cuddI(dd,g->index);
00191     toph = cuddI(dd,h->index);
00192     v = ddMin(topg,toph);
00193 
00194     /* ITE(F,G,H) = (x,G,H) (non constant) if F = (x,1,0), x < top(G,H). */
00195     if (topf < v && cuddIsConstant(cuddT(f)) && cuddIsConstant(cuddE(f))) {
00196         return(DD_NON_CONSTANT);
00197     }
00198 
00199     /* Check cache. */
00200     r = cuddConstantLookup(dd,DD_ADD_ITE_CONSTANT_TAG,f,g,h);
00201     if (r != NULL) {
00202         return(r);
00203     }
00204 
00205     /* Compute cofactors. */
00206     if (topf <= v) {
00207         v = ddMin(topf,v);      /* v = top_var(F,G,H) */
00208         Fv = cuddT(f); Fnv = cuddE(f);
00209     } else {
00210         Fv = Fnv = f;
00211     }
00212     if (topg == v) {
00213         Gv = cuddT(g); Gnv = cuddE(g);
00214     } else {
00215         Gv = Gnv = g;
00216     }
00217     if (toph == v) {
00218         Hv = cuddT(h); Hnv = cuddE(h);
00219     } else {
00220         Hv = Hnv = h;
00221     }
00222     
00223     /* Recursive step. */
00224     t = Cudd_addIteConstant(dd,Fv,Gv,Hv);
00225     if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) {
00226         cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT);
00227         return(DD_NON_CONSTANT);
00228     }
00229     e = Cudd_addIteConstant(dd,Fnv,Gnv,Hnv);
00230     if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) {
00231         cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT);
00232         return(DD_NON_CONSTANT);
00233     }
00234     cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, t);
00235     return(t);
00236 
00237 } /* end of Cudd_addIteConstant */

DdNode* Cudd_addIthBit ( DdManager dd,
DdNode f,
int  bit 
)

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

Synopsis [Extracts the i-th bit from an ADD.]

Description [Produces an ADD from another ADD by replacing all discriminants whose i-th bit is equal to 1 with 1, and all other discriminants with 0. The i-th bit refers to the integer representation of the leaf value. If the value is has a fractional part, it is ignored. Repeated calls to this procedure allow one to transform an integer-valued ADD into an array of ADDs, one for each bit of the leaf values. Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addBddIthBit]

Definition at line 209 of file cuddAddFind.c.

00213 {
00214     DdNode *res;
00215     DdNode *index;
00216     
00217     /* Use a constant node to remember the bit, so that we can use the
00218     ** global cache.
00219     */
00220     index = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) bit);
00221     if (index == NULL) return(NULL);
00222     cuddRef(index);
00223 
00224     do {
00225         dd->reordered = 0;
00226         res = addDoIthBit(dd, f, index);
00227     } while (dd->reordered == 1);
00228 
00229     if (res == NULL) {
00230         Cudd_RecursiveDeref(dd, index);
00231         return(NULL);
00232     }
00233     cuddRef(res);
00234     Cudd_RecursiveDeref(dd, index);
00235     cuddDeref(res);
00236     return(res);
00237 
00238 } /* end of Cudd_addIthBit */

DdNode* Cudd_addIthVar ( DdManager dd,
int  i 
)

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

Synopsis [Returns the ADD variable with index i.]

Description [Retrieves the ADD variable with index i if it already exists, or creates a new ADD variable. Returns a pointer to the variable if successful; NULL otherwise. An ADD variable differs from a BDD variable because it points to the arithmetic zero, instead of having a complement pointer to 1. ]

SideEffects [None]

SeeAlso [Cudd_addNewVar Cudd_bddIthVar Cudd_addConst Cudd_addNewVarAtLevel]

Definition at line 380 of file cuddAPI.c.

00383 {
00384     DdNode *res;
00385 
00386     if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL);
00387     do {
00388         dd->reordered = 0;
00389         res = cuddUniqueInter(dd,i,DD_ONE(dd),DD_ZERO(dd));
00390     } while (dd->reordered == 1);
00391 
00392     return(res);
00393 
00394 } /* end of Cudd_addIthVar */

int Cudd_addLeq ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Determines whether f is less than or equal to g.]

Description [Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are created. This procedure works for arbitrary ADDs. For 0-1 ADDs Cudd_addEvalConst is more efficient.]

SideEffects [None]

SeeAlso [Cudd_addIteConstant Cudd_addEvalConst Cudd_bddLeq]

Definition at line 372 of file cuddAddIte.c.

00376 {
00377     DdNode *tmp, *fv, *fvn, *gv, *gvn;
00378     unsigned int topf, topg, res;
00379 
00380     /* Terminal cases. */
00381     if (f == g) return(1);
00382 
00383     statLine(dd);
00384     if (cuddIsConstant(f)) {
00385         if (cuddIsConstant(g)) return(cuddV(f) <= cuddV(g));
00386         if (f == DD_MINUS_INFINITY(dd)) return(1);
00387         if (f == DD_PLUS_INFINITY(dd)) return(0); /* since f != g */
00388     }
00389     if (g == DD_PLUS_INFINITY(dd)) return(1);
00390     if (g == DD_MINUS_INFINITY(dd)) return(0); /* since f != g */
00391 
00392     /* Check cache. */
00393     tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g);
00394     if (tmp != NULL) {
00395         return(tmp == DD_ONE(dd));
00396     }
00397 
00398     /* Compute cofactors. One of f and g is not constant. */
00399     topf = cuddI(dd,f->index);
00400     topg = cuddI(dd,g->index);
00401     if (topf <= topg) {
00402         fv = cuddT(f); fvn = cuddE(f);
00403     } else {
00404         fv = fvn = f;
00405     }
00406     if (topg <= topf) {
00407         gv = cuddT(g); gvn = cuddE(g);
00408     } else {
00409         gv = gvn = g;
00410     }
00411 
00412     res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv);
00413 
00414     /* Store result in cache and return. */
00415     cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq,f,g,
00416                      Cudd_NotCond(DD_ONE(dd),res==0));
00417     return(res);
00418 
00419 } /* end of Cudd_addLeq */

DdNode* Cudd_addLog ( DdManager dd,
DdNode f 
)

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

Synopsis [Natural logarithm of an ADD.]

Description [Natural logarithm of an ADDs. Returns NULL if not a terminal case; log(f) otherwise. The discriminants of f must be positive double's.]

SideEffects [None]

SeeAlso [Cudd_addMonadicApply]

Definition at line 773 of file cuddAddApply.c.

00776 {
00777     if (cuddIsConstant(f)) {
00778         CUDD_VALUE_TYPE value = log(cuddV(f));
00779         DdNode *res = cuddUniqueConst(dd,value);
00780         return(res);
00781     }
00782     return(NULL);
00783 
00784 } /* end of Cudd_addLog */

DdNode* Cudd_addMatrixMultiply ( DdManager dd,
DdNode A,
DdNode B,
DdNode **  z,
int  nz 
)

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

Synopsis [Calculates the product of two matrices represented as ADDs.]

Description [Calculates the product of two matrices, A and B, represented as ADDs. This procedure implements the quasiring multiplication algorithm. A is assumed to depend on variables x (rows) and z (columns). B is assumed to depend on variables z (rows) and y (columns). The product of A and B then depends on x (rows) and y (columns). Only the z variables have to be explicitly identified; they are the "summation" variables. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addTimesPlus Cudd_addTriangle Cudd_bddAndAbstract]

Definition at line 128 of file cuddMatMult.c.

00134 {
00135     int i, nvars, *vars;
00136     DdNode *res; 
00137 
00138     /* Array vars says what variables are "summation" variables. */
00139     nvars = dd->size;
00140     vars = ALLOC(int,nvars);
00141     if (vars == NULL) {
00142         dd->errorCode = CUDD_MEMORY_OUT;
00143         return(NULL);
00144     }
00145     for (i = 0; i < nvars; i++) {
00146         vars[i] = 0;
00147     }
00148     for (i = 0; i < nz; i++) {
00149         vars[z[i]->index] = 1;
00150     }
00151 
00152     do {
00153         dd->reordered = 0;
00154         res = addMMRecur(dd,A,B,-1,vars);
00155     } while (dd->reordered == 1);
00156     FREE(vars);
00157     return(res);
00158 
00159 } /* end of Cudd_addMatrixMultiply */

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

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

Synopsis [Integer and floating point max.]

Description [Integer and floating point max for Cudd_addApply. Returns NULL if not a terminal case; max(f,g) otherwise.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 426 of file cuddAddApply.c.

00430 {
00431     DdNode *F, *G;
00432 
00433     F = *f; G = *g;
00434     if (F == G) return(F);
00435     if (F == DD_MINUS_INFINITY(dd)) return(G);
00436     if (G == DD_MINUS_INFINITY(dd)) return(F);
00437 #if 0
00438     /* These special cases probably do not pay off. */
00439     if (F == DD_PLUS_INFINITY(dd)) return(F);
00440     if (G == DD_PLUS_INFINITY(dd)) return(G);
00441 #endif
00442     if (cuddIsConstant(F) && cuddIsConstant(G)) {
00443         if (cuddV(F) >= cuddV(G)) {
00444             return(F);
00445         } else {
00446             return(G);
00447         }
00448     }
00449     if (F > G) { /* swap f and g */
00450         *f = G;
00451         *g = F;
00452     }
00453     return(NULL);
00454 
00455 } /* end of Cudd_addMaximum */

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

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

Synopsis [Integer and floating point min.]

Description [Integer and floating point min for Cudd_addApply. Returns NULL if not a terminal case; min(f,g) otherwise.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 381 of file cuddAddApply.c.

00385 {
00386     DdNode *F, *G;
00387 
00388     F = *f; G = *g;
00389     if (F == DD_PLUS_INFINITY(dd)) return(G);
00390     if (G == DD_PLUS_INFINITY(dd)) return(F);
00391     if (F == G) return(F);
00392 #if 0
00393     /* These special cases probably do not pay off. */
00394     if (F == DD_MINUS_INFINITY(dd)) return(F);
00395     if (G == DD_MINUS_INFINITY(dd)) return(G);
00396 #endif
00397     if (cuddIsConstant(F) && cuddIsConstant(G)) {
00398         if (cuddV(F) <= cuddV(G)) {
00399             return(F);
00400         } else {
00401             return(G);
00402         }
00403     }
00404     if (F > G) { /* swap f and g */
00405         *f = G;
00406         *g = F;
00407     }
00408     return(NULL);
00409 
00410 } /* end of Cudd_addMinimum */

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

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

Synopsis [Integer and floating point subtraction.]

Description [Integer and floating point subtraction. Returns NULL if not a terminal case; f - g otherwise.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 345 of file cuddAddApply.c.

00349 {
00350     DdNode *res;
00351     DdNode *F, *G;
00352     CUDD_VALUE_TYPE value;
00353 
00354     F = *f; G = *g;
00355     if (F == G) return(DD_ZERO(dd));
00356     if (F == DD_ZERO(dd)) return(cuddAddNegateRecur(dd,G));
00357     if (G == DD_ZERO(dd)) return(F);
00358     if (cuddIsConstant(F) && cuddIsConstant(G)) {
00359         value = cuddV(F)-cuddV(G);
00360         res = cuddUniqueConst(dd,value);
00361         return(res);
00362     }
00363     return(NULL);
00364 
00365 } /* end of Cudd_addMinus */

DdNode* Cudd_addMonadicApply ( DdManager dd,
DdNode *(*)(DdManager *, DdNode *)  op,
DdNode f 
)
DdNode* Cudd_addNand ( DdManager dd,
DdNode **  f,
DdNode **  g 
)

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

Synopsis [NAND of two 0-1 ADDs.]

Description [NAND of two 0-1 ADDs. Returns NULL if not a terminal case; f NAND g otherwise.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 611 of file cuddAddApply.c.

00615 {
00616     DdNode *F, *G;
00617 
00618     F = *f; G = *g;
00619     if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ONE(dd));
00620     if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd));
00621     if (F > G) { /* swap f and g */
00622         *f = G;
00623         *g = F;
00624     }
00625     return(NULL);
00626 
00627 } /* end of Cudd_addNand */

DdNode* Cudd_addNegate ( DdManager dd,
DdNode f 
)

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

Synopsis [Computes the additive inverse of an ADD.]

Description [Computes the additive inverse of an ADD. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addCmpl]

Definition at line 116 of file cuddAddNeg.c.

00119 {
00120     DdNode *res;
00121 
00122     do {
00123         res = cuddAddNegateRecur(dd,f);
00124     } while (dd->reordered == 1);
00125     return(res);
00126 
00127 } /* end of Cudd_addNegate */

DdNode* Cudd_addNewVar ( DdManager dd  ) 

AutomaticStart

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

Synopsis [Returns a new ADD variable.]

Description [Creates a new ADD variable. The new variable has an index equal to the largest previous index plus 1. Returns a pointer to the new variable if successful; NULL otherwise. An ADD variable differs from a BDD variable because it points to the arithmetic zero, instead of having a complement pointer to 1. ]

SideEffects [None]

SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_addConst Cudd_addNewVarAtLevel]

Definition at line 255 of file cuddAPI.c.

00257 {
00258     DdNode *res;
00259 
00260     if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL);
00261     do {
00262         dd->reordered = 0;
00263         res = cuddUniqueInter(dd,dd->size,DD_ONE(dd),DD_ZERO(dd));
00264     } while (dd->reordered == 1);
00265 
00266     return(res);
00267 
00268 } /* end of Cudd_addNewVar */

DdNode* Cudd_addNewVarAtLevel ( DdManager dd,
int  level 
)

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

Synopsis [Returns a new ADD variable at a specified level.]

Description [Creates a new ADD variable. The new variable has an index equal to the largest previous index plus 1 and is positioned at the specified level in the order. Returns a pointer to the new variable if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel]

Definition at line 286 of file cuddAPI.c.

00289 {
00290     DdNode *res;
00291 
00292     if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL);
00293     if (level >= dd->size) return(Cudd_addIthVar(dd,level));
00294     if (!cuddInsertSubtables(dd,1,level)) return(NULL);
00295     do {
00296         dd->reordered = 0;
00297         res = cuddUniqueInter(dd,dd->size - 1,DD_ONE(dd),DD_ZERO(dd));
00298     } while (dd->reordered == 1);
00299 
00300     return(res);
00301 
00302 } /* end of Cudd_addNewVarAtLevel */

DdNode* Cudd_addNonSimCompose ( DdManager dd,
DdNode f,
DdNode **  vector 
)

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

Synopsis [Composes an ADD with a vector of 0-1 ADDs.]

Description [Given a vector of 0-1 ADDs, creates a new ADD by substituting the 0-1 ADDs for the variables of the ADD f. There should be an entry in vector for each variable in the manager. This function implements non-simultaneous composition. If any of the functions being composed depends on any of the variables being substituted, then the result depends on the order of composition, which in turn depends on the variable order: The variables farther from the roots in the order are substituted first. Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addVectorCompose Cudd_addPermute Cudd_addCompose]

Definition at line 678 of file cuddCompose.c.

00682 {
00683     DdNode              *cube, *key, *var, *tmp, *piece;
00684     DdNode              *res;
00685     int                 i, lastsub;
00686 
00687     /* The cache entry for this function is composed of three parts:
00688     ** f itself, the replacement relation, and the cube of the
00689     ** variables being substituted.
00690     ** The replacement relation is the product of the terms (yi EXNOR gi).
00691     ** This apporach allows us to use the global cache for this function,
00692     ** with great savings in memory with respect to using arrays for the
00693     ** cache entries.
00694     ** First we build replacement relation and cube of substituted
00695     ** variables from the vector specifying the desired composition.
00696     */
00697     key = DD_ONE(dd);
00698     cuddRef(key);
00699     cube = DD_ONE(dd);
00700     cuddRef(cube);
00701     for (i = (int) dd->size - 1; i >= 0; i--) {
00702         if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) {
00703             continue;
00704         }
00705         var = Cudd_addIthVar(dd,i);
00706         if (var == NULL) {
00707             Cudd_RecursiveDeref(dd,key);
00708             Cudd_RecursiveDeref(dd,cube);
00709             return(NULL);
00710         }
00711         cuddRef(var);
00712         /* Update cube. */
00713         tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube);
00714         if (tmp == NULL) {
00715             Cudd_RecursiveDeref(dd,key);
00716             Cudd_RecursiveDeref(dd,cube);
00717             Cudd_RecursiveDeref(dd,var);
00718             return(NULL);
00719         }
00720         cuddRef(tmp);
00721         Cudd_RecursiveDeref(dd,cube);
00722         cube = tmp;
00723         /* Update replacement relation. */
00724         piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]);
00725         if (piece == NULL) {
00726             Cudd_RecursiveDeref(dd,key);
00727             Cudd_RecursiveDeref(dd,var);
00728             return(NULL);
00729         }
00730         cuddRef(piece);
00731         Cudd_RecursiveDeref(dd,var);
00732         tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece);
00733         if (tmp == NULL) {
00734             Cudd_RecursiveDeref(dd,key);
00735             Cudd_RecursiveDeref(dd,piece);
00736             return(NULL);
00737         }
00738         cuddRef(tmp);
00739         Cudd_RecursiveDeref(dd,key);
00740         Cudd_RecursiveDeref(dd,piece);
00741         key = tmp;
00742     }
00743 
00744     /* Now try composition, until no reordering occurs. */
00745     do {
00746         /* Find real substitution with largest index. */
00747         for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) {
00748             if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) {
00749                 break;
00750             }
00751         }
00752 
00753         /* Recursively solve the problem. */
00754         dd->reordered = 0;
00755         res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1);
00756         if (res != NULL) cuddRef(res);
00757 
00758     } while (dd->reordered == 1);
00759 
00760     Cudd_RecursiveDeref(dd,key);
00761     Cudd_RecursiveDeref(dd,cube);
00762     if (res != NULL) cuddDeref(res);
00763     return(res);
00764 
00765 } /* end of Cudd_addNonSimCompose */

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

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

Synopsis [NOR of two 0-1 ADDs.]

Description [NOR of two 0-1 ADDs. Returns NULL if not a terminal case; f NOR g otherwise.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 643 of file cuddAddApply.c.

00647 {
00648     DdNode *F, *G;
00649 
00650     F = *f; G = *g;
00651     if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ZERO(dd));
00652     if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ONE(dd));
00653     if (F > G) { /* swap f and g */
00654         *f = G;
00655         *g = F;
00656     }
00657     return(NULL);
00658 
00659 } /* end of Cudd_addNor */

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

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

Synopsis [Returns 1 if f > g and 0 otherwise.]

Description [Returns 1 if f > g and 0 otherwise. Used in conjunction with Cudd_addApply. Returns NULL if not a terminal case.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 472 of file cuddAddApply.c.

00476 {
00477 
00478     if (*f == *g) return(DD_ZERO(dd));
00479     if (*g == DD_PLUS_INFINITY(dd))
00480         return DD_ZERO(dd);
00481     if (cuddIsConstant(*f) && cuddIsConstant(*g)) {
00482         if (cuddV(*f) > cuddV(*g)) {
00483             return(DD_ONE(dd));
00484         } else {
00485             return(DD_ZERO(dd));
00486         }
00487     }
00488 
00489     return(NULL);
00490 
00491 } /* end of Cudd_addOneZeroMaximum */

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

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

Synopsis [Disjunction of two 0-1 ADDs.]

Description [Disjunction of two 0-1 ADDs. Returns NULL if not a terminal case; f OR g otherwise.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 577 of file cuddAddApply.c.

00581 {
00582     DdNode *F, *G;
00583 
00584     F = *f; G = *g;
00585     if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ONE(dd));
00586     if (cuddIsConstant(F)) return(G);
00587     if (cuddIsConstant(G)) return(F);
00588     if (F == G) return(F);
00589     if (F > G) { /* swap f and g */
00590         *f = G;
00591         *g = F;
00592     }
00593     return(NULL);
00594 
00595 } /* end of Cudd_addOr */

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

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

Synopsis [Disjunctively abstracts all the variables in cube from the 0-1 ADD f.]

Description [Abstracts all the variables in cube from the 0-1 ADD f by taking the disjunction over all possible values taken by the variables. Returns the abstracted ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addUnivAbstract Cudd_addExistAbstract]

Definition at line 212 of file cuddAddAbs.c.

00216 {
00217     DdNode *res;
00218 
00219     if (addCheckPositiveCube(manager, cube) == 0) {
00220         (void) fprintf(manager->err,"Error: Can only abstract cubes");
00221         return(NULL);
00222     }
00223 
00224     do {
00225         manager->reordered = 0;
00226         res = cuddAddOrAbstractRecur(manager, f, cube);
00227     } while (manager->reordered == 1);
00228     return(res);
00229 
00230 } /* end of Cudd_addOrAbstract */

DdNode* Cudd_addOuterSum ( DdManager dd,
DdNode M,
DdNode r,
DdNode c 
)

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

Synopsis [Takes the minimum of a matrix and the outer sum of two vectors.]

Description [Takes the pointwise minimum of a matrix and the outer sum of two vectors. This procedure is used in the Floyd-Warshall all-pair shortest path algorithm. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 292 of file cuddMatMult.c.

00297 {
00298     DdNode *res;
00299 
00300     do {
00301         dd->reordered = 0;
00302         res = cuddAddOuterSumRecur(dd, M, r, c);
00303     } while (dd->reordered == 1);
00304     return(res);
00305 
00306 } /* end of Cudd_addOuterSum */

DdNode* Cudd_addPermute ( DdManager manager,
DdNode node,
int *  permut 
)

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

Synopsis [Permutes the variables of an ADD.]

Description [Given a permutation in array permut, creates a new ADD with permuted variables. There should be an entry in array permut for each variable in the manager. The i-th entry of permut holds the index of the variable that is to substitute the i-th variable. Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddPermute Cudd_addSwapVariables]

Definition at line 238 of file cuddCompose.c.

00242 {
00243     DdHashTable         *table;
00244     DdNode              *res;
00245 
00246     do {
00247         manager->reordered = 0;
00248         table = cuddHashTableInit(manager,1,2);
00249         if (table == NULL) return(NULL);
00250         /* Recursively solve the problem. */
00251         res = cuddAddPermuteRecur(manager,table,node,permut);
00252         if (res != NULL) cuddRef(res);
00253         /* Dispose of local cache. */
00254         cuddHashTableQuit(table);
00255     } while (manager->reordered == 1);
00256 
00257     if (res != NULL) cuddDeref(res);
00258     return(res);
00259 
00260 } /* end of Cudd_addPermute */

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

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

Synopsis [Integer and floating point addition.]

Description [Integer and floating point addition. Returns NULL if not a terminal case; f+g otherwise.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 164 of file cuddAddApply.c.

00168 {
00169     DdNode *res;
00170     DdNode *F, *G;
00171     CUDD_VALUE_TYPE value;
00172 
00173     F = *f; G = *g;
00174     if (F == DD_ZERO(dd)) return(G);
00175     if (G == DD_ZERO(dd)) return(F);
00176     if (cuddIsConstant(F) && cuddIsConstant(G)) {
00177         value = cuddV(F)+cuddV(G);
00178         res = cuddUniqueConst(dd,value);
00179         return(res);
00180     }
00181     if (F > G) { /* swap f and g */
00182         *f = G;
00183         *g = F;
00184     }
00185     return(NULL);
00186 
00187 } /* end of Cudd_addPlus */

int Cudd_addRead ( FILE *  fp,
DdManager dd,
DdNode **  E,
DdNode ***  x,
DdNode ***  y,
DdNode ***  xn,
DdNode ***  yn_,
int *  nx,
int *  ny,
int *  m,
int *  n,
int  bx,
int  sx,
int  by,
int  sy 
)

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

Synopsis [Reads in a sparse matrix.]

Description [Reads in a sparse matrix specified in a simple format. The first line of the input contains the numbers of rows and columns. The remaining lines contain the elements of the matrix, one per line. Given a background value (specified by the background field of the manager), only the values different from it are explicitly listed. Each foreground element is described by two integers, i.e., the row and column number, and a real number, i.e., the value.

Cudd_addRead produces an ADD that depends on two sets of variables: x and y. The x variables (x\[0\] ... x\[nx-1\]) encode the row index and the y variables (y\[0\] ... y\[ny-1\]) encode the column index. x\[0\] and y\[0\] are the most significant bits in the indices. The variables may already exist or may be created by the function. The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.

On input, nx and ny hold the numbers of row and column variables already in existence. On output, they hold the numbers of row and column variables actually used by the matrix. When Cudd_addRead creates the variable arrays, the index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy. When some variables already exist Cudd_addRead expects the indices of the existing x variables to be bx+i*sx, and the indices of the existing y variables to be by+i*sy.

m and n are set to the numbers of rows and columns of the matrix. Their values on input are immaterial. The ADD for the sparse matrix is returned in E, and its reference count is > 0. Cudd_addRead returns 1 in case of success; 0 otherwise.]

SideEffects [nx and ny are set to the numbers of row and column variables. m and n are set to the numbers of rows and columns. x and y are possibly extended to represent the array of row and column variables. Similarly for xn and yn_, which hold on return from Cudd_addRead the complements of the row and column variables.]

SeeAlso [Cudd_addHarwell Cudd_bddRead]

Definition at line 142 of file cuddRead.c.

00158 {
00159     DdNode *one, *zero;
00160     DdNode *w, *neW;
00161     DdNode *minterm1;
00162     int u, v, err, i, nv;
00163     int lnx, lny;
00164     CUDD_VALUE_TYPE val;
00165     DdNode **lx, **ly, **lxn, **lyn;
00166 
00167     one = DD_ONE(dd);
00168     zero = DD_ZERO(dd);
00169 
00170     err = fscanf(fp, "%d %d", &u, &v);
00171     if (err == EOF) {
00172         return(0);
00173     } else if (err != 2) {
00174         return(0);
00175     }
00176 
00177     *m = u;
00178     /* Compute the number of x variables. */
00179     lx = *x; lxn = *xn;
00180     u--;        /* row and column numbers start from 0 */
00181     for (lnx=0; u > 0; lnx++) {
00182         u >>= 1;
00183     }
00184     /* Here we rely on the fact that REALLOC of a null pointer is
00185     ** translates to an ALLOC.
00186     */
00187     if (lnx > *nx) {
00188         *x = lx = REALLOC(DdNode *, *x, lnx);
00189         if (lx == NULL) {
00190             dd->errorCode = CUDD_MEMORY_OUT;
00191             return(0);
00192         }
00193         *xn = lxn =  REALLOC(DdNode *, *xn, lnx);
00194         if (lxn == NULL) {
00195             dd->errorCode = CUDD_MEMORY_OUT;
00196             return(0);
00197         }
00198     }
00199 
00200     *n = v;
00201     /* Compute the number of y variables. */
00202     ly = *y; lyn = *yn_;
00203     v--;        /* row and column numbers start from 0 */
00204     for (lny=0; v > 0; lny++) {
00205         v >>= 1;
00206     }
00207     /* Here we rely on the fact that REALLOC of a null pointer is
00208     ** translates to an ALLOC.
00209     */
00210     if (lny > *ny) {
00211         *y = ly = REALLOC(DdNode *, *y, lny);
00212         if (ly == NULL) {
00213             dd->errorCode = CUDD_MEMORY_OUT;
00214             return(0);
00215         }
00216         *yn_ = lyn =  REALLOC(DdNode *, *yn_, lny);
00217         if (lyn == NULL) {
00218             dd->errorCode = CUDD_MEMORY_OUT;
00219             return(0);
00220         }
00221     }
00222 
00223     /* Create all new variables. */
00224     for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) {
00225         do {
00226             dd->reordered = 0;
00227             lx[i] = cuddUniqueInter(dd, nv, one, zero);
00228         } while (dd->reordered == 1);
00229         if (lx[i] == NULL) return(0);
00230         cuddRef(lx[i]);
00231         do {
00232             dd->reordered = 0;
00233             lxn[i] = cuddUniqueInter(dd, nv, zero, one);
00234         } while (dd->reordered == 1);
00235         if (lxn[i] == NULL) return(0);
00236         cuddRef(lxn[i]);
00237     }
00238     for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) {
00239         do {
00240             dd->reordered = 0;
00241             ly[i] = cuddUniqueInter(dd, nv, one, zero);
00242         } while (dd->reordered == 1);
00243         if (ly[i] == NULL) return(0);
00244         cuddRef(ly[i]);
00245         do {
00246             dd->reordered = 0;
00247             lyn[i] = cuddUniqueInter(dd, nv, zero, one);
00248         } while (dd->reordered == 1);
00249         if (lyn[i] == NULL) return(0);
00250         cuddRef(lyn[i]);
00251     }
00252     *nx = lnx;
00253     *ny = lny;
00254 
00255     *E = dd->background; /* this call will never cause reordering */
00256     cuddRef(*E);
00257 
00258     while (! feof(fp)) {
00259         err = fscanf(fp, "%d %d %lf", &u, &v, &val);
00260         if (err == EOF) {
00261             break;
00262         } else if (err != 3) {
00263             return(0);
00264         } else if (u >= *m || v >= *n || u < 0 || v < 0) {
00265             return(0);
00266         }
00267  
00268         minterm1 = one; cuddRef(minterm1);
00269 
00270         /* Build minterm1 corresponding to this arc */
00271         for (i = lnx - 1; i>=0; i--) {
00272             if (u & 1) {
00273                 w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lx[i]);
00274             } else {
00275                 w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lxn[i]);
00276             }
00277             if (w == NULL) {
00278                 Cudd_RecursiveDeref(dd, minterm1);
00279                 return(0);
00280             }
00281             cuddRef(w);
00282             Cudd_RecursiveDeref(dd, minterm1);
00283             minterm1 = w;
00284             u >>= 1;
00285         }
00286         for (i = lny - 1; i>=0; i--) {
00287             if (v & 1) {
00288                 w = Cudd_addApply(dd, Cudd_addTimes, minterm1, ly[i]);
00289             } else {
00290                 w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lyn[i]);
00291             }
00292             if (w == NULL) {
00293                 Cudd_RecursiveDeref(dd, minterm1);
00294                 return(0);
00295             }
00296             cuddRef(w);
00297             Cudd_RecursiveDeref(dd, minterm1);
00298             minterm1 = w;
00299             v >>= 1;
00300         }
00301         /* Create new constant node if necessary.
00302         ** This call will never cause reordering.
00303         */
00304         neW = cuddUniqueConst(dd, val);
00305         if (neW == NULL) {
00306             Cudd_RecursiveDeref(dd, minterm1);
00307             return(0);
00308         }
00309         cuddRef(neW);
00310 
00311         w = Cudd_addIte(dd, minterm1, neW, *E);
00312         if (w == NULL) {
00313             Cudd_RecursiveDeref(dd, minterm1);
00314             Cudd_RecursiveDeref(dd, neW);
00315             return(0);
00316         }
00317         cuddRef(w);
00318         Cudd_RecursiveDeref(dd, minterm1);
00319         Cudd_RecursiveDeref(dd, neW);
00320         Cudd_RecursiveDeref(dd, *E);
00321         *E = w;
00322     }
00323     return(1);
00324 
00325 } /* end of Cudd_addRead */

DdNode* Cudd_addResidue ( DdManager dd,
int  n,
int  m,
int  options,
int  top 
)

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

Synopsis [Builds an ADD for the residue modulo m of an n-bit number.]

Description [Builds an ADD for the residue modulo m of an n-bit number. The modulus must be at least 2, and the number of bits at least 1. Parameter options specifies whether the MSB should be on top or the LSB; and whther the number whose residue is computed is in two's complement notation or not. The macro CUDD_RESIDUE_DEFAULT specifies LSB on top and unsigned number. The macro CUDD_RESIDUE_MSB specifies MSB on top, and the macro CUDD_RESIDUE_TC specifies two's complement residue. To request MSB on top and two's complement residue simultaneously, one can OR the two macros: CUDD_RESIDUE_MSB | CUDD_RESIDUE_TC. Cudd_addResidue returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 157 of file cuddAddWalsh.c.

00163 {
00164     int msbLsb; /* MSB on top (1) or LSB on top (0) */
00165     int tc;     /* two's complement (1) or unsigned (0) */
00166     int i, j, k, t, residue, thisOne, previous, index;
00167     DdNode **array[2], *var, *tmp, *res;
00168 
00169     /* Sanity check. */
00170     if (n < 1 && m < 2) return(NULL);
00171 
00172     msbLsb = options & CUDD_RESIDUE_MSB;
00173     tc = options & CUDD_RESIDUE_TC;
00174 
00175     /* Allocate and initialize working arrays. */
00176     array[0] = ALLOC(DdNode *,m);
00177     if (array[0] == NULL) {
00178         dd->errorCode = CUDD_MEMORY_OUT;
00179         return(NULL);
00180     }
00181     array[1] = ALLOC(DdNode *,m);
00182     if (array[1] == NULL) {
00183         FREE(array[0]);
00184         dd->errorCode = CUDD_MEMORY_OUT;
00185         return(NULL);
00186     }
00187     for (i = 0; i < m; i++) {
00188         array[0][i] = array[1][i] = NULL;
00189     }
00190 
00191     /* Initialize residues. */
00192     for (i = 0; i < m; i++) {
00193         tmp = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) i);
00194         if (tmp == NULL) {
00195             for (j = 0; j < i; j++) {
00196                 Cudd_RecursiveDeref(dd,array[1][j]);
00197             }
00198             FREE(array[0]);
00199             FREE(array[1]);
00200             return(NULL);
00201         }
00202         cuddRef(tmp);
00203         array[1][i] = tmp;
00204     }
00205 
00206     /* Main iteration. */
00207     residue = 1;        /* residue of 2**0 */
00208     for (k = 0; k < n; k++) {
00209         /* Choose current and previous arrays. */
00210         thisOne = k & 1;
00211         previous = thisOne ^ 1;
00212         /* Build an ADD projection function. */
00213         if (msbLsb) {
00214             index = top+n-k-1;
00215         } else {
00216             index = top+k;
00217         }
00218         var = cuddUniqueInter(dd,index,DD_ONE(dd),DD_ZERO(dd));
00219         if (var == NULL) {
00220             for (j = 0; j < m; j++) {
00221                 Cudd_RecursiveDeref(dd,array[previous][j]);
00222             }
00223             FREE(array[0]);
00224             FREE(array[1]);
00225             return(NULL);
00226         }
00227         cuddRef(var);
00228         for (i = 0; i < m; i ++) {
00229             t = (i + residue) % m;
00230             tmp = Cudd_addIte(dd,var,array[previous][t],array[previous][i]);
00231             if (tmp == NULL) {
00232                 for (j = 0; j < i; j++) {
00233                     Cudd_RecursiveDeref(dd,array[thisOne][j]);
00234                 }
00235                 for (j = 0; j < m; j++) {
00236                     Cudd_RecursiveDeref(dd,array[previous][j]);
00237                 }
00238                 FREE(array[0]);
00239                 FREE(array[1]);
00240                 return(NULL);
00241             }
00242             cuddRef(tmp);
00243             array[thisOne][i] = tmp;
00244         }
00245         /* One layer completed. Free the other array for the next iteration. */
00246         for (i = 0; i < m; i++) {
00247             Cudd_RecursiveDeref(dd,array[previous][i]);
00248         }
00249         Cudd_RecursiveDeref(dd,var);
00250         /* Update residue of 2**k. */
00251         residue = (2 * residue) % m;
00252         /* Adjust residue for MSB, if this is a two's complement number. */
00253         if (tc && (k == n - 1)) {
00254             residue = (m - residue) % m;
00255         }
00256     }
00257 
00258     /* We are only interested in the 0-residue node of the top layer. */
00259     for (i = 1; i < m; i++) {
00260         Cudd_RecursiveDeref(dd,array[(n - 1) & 1][i]);
00261     }
00262     res = array[(n - 1) & 1][0];
00263 
00264     FREE(array[0]);
00265     FREE(array[1]);
00266 
00267     cuddDeref(res);
00268     return(res);
00269 
00270 } /* end of Cudd_addResidue */

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

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

Synopsis [ADD restrict according to Coudert and Madre's algorithm (ICCAD90).]

Description [ADD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns the restricted ADD if successful; otherwise NULL. If application of restrict results in an ADD larger than the input ADD, the input ADD is returned.]

SideEffects [None]

SeeAlso [Cudd_addConstrain Cudd_bddRestrict]

Definition at line 427 of file cuddGenCof.c.

00431 {
00432     DdNode *supp_f, *supp_c;
00433     DdNode *res, *commonSupport;
00434     int intersection;
00435     int sizeF, sizeRes;
00436 
00437     /* Check if supports intersect. */
00438     supp_f = Cudd_Support(dd, f);
00439     if (supp_f == NULL) {
00440         return(NULL);
00441     }
00442     cuddRef(supp_f);
00443     supp_c = Cudd_Support(dd, c);
00444     if (supp_c == NULL) {
00445         Cudd_RecursiveDeref(dd,supp_f);
00446         return(NULL);
00447     }
00448     cuddRef(supp_c);
00449     commonSupport = Cudd_bddLiteralSetIntersection(dd, supp_f, supp_c);
00450     if (commonSupport == NULL) {
00451         Cudd_RecursiveDeref(dd,supp_f);
00452         Cudd_RecursiveDeref(dd,supp_c);
00453         return(NULL);
00454     }
00455     cuddRef(commonSupport);
00456     Cudd_RecursiveDeref(dd,supp_f);
00457     Cudd_RecursiveDeref(dd,supp_c);
00458     intersection = commonSupport != DD_ONE(dd);
00459     Cudd_RecursiveDeref(dd,commonSupport);
00460 
00461     if (intersection) {
00462         do {
00463             dd->reordered = 0;
00464             res = cuddAddRestrictRecur(dd, f, c);
00465         } while (dd->reordered == 1);
00466         sizeF = Cudd_DagSize(f);
00467         sizeRes = Cudd_DagSize(res);
00468         if (sizeF <= sizeRes) {
00469             cuddRef(res);
00470             Cudd_RecursiveDeref(dd, res);
00471             return(f);
00472         } else {
00473             return(res);
00474         }
00475     } else {
00476         return(f);
00477     }
00478 
00479 } /* end of Cudd_addRestrict */

DdNode* Cudd_addRoundOff ( DdManager dd,
DdNode f,
int  N 
)

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

Synopsis [Rounds off the discriminants of an ADD.]

Description [Rounds off the discriminants of an ADD. The discriminants are rounded off to N digits after the decimal. Returns a pointer to the result ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 144 of file cuddAddNeg.c.

00148 {
00149     DdNode *res;
00150     double trunc = pow(10.0,(double)N);
00151 
00152     do {
00153         res = cuddAddRoundOffRecur(dd,f,trunc);
00154     } while (dd->reordered == 1);
00155     return(res);
00156 
00157 } /* end of Cudd_addRoundOff */

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

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

Synopsis [Computes the scalar inverse of an ADD.]

Description [Computes an n ADD where the discriminants are the multiplicative inverses of the corresponding discriminants of the argument ADD. Returns a pointer to the resulting ADD in case of success. Returns NULL if any discriminants smaller than epsilon is encountered.]

SideEffects [None]

Definition at line 116 of file cuddAddInv.c.

00120 {
00121     DdNode *res;
00122 
00123     if (!cuddIsConstant(epsilon)) {
00124         (void) fprintf(dd->err,"Invalid epsilon\n");
00125         return(NULL);
00126     }
00127     do {
00128         dd->reordered = 0;
00129         res  = cuddAddScalarInverseRecur(dd,f,epsilon);
00130     } while (dd->reordered == 1);
00131     return(res);
00132 
00133 } /* end of Cudd_addScalarInverse */

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

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

Synopsis [This operator sets f to the value of g wherever g != 0.]

Description [This operator sets f to the value of g wherever g != 0. Returns NULL if not a terminal case; f op g otherwise.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 278 of file cuddAddApply.c.

00282 {
00283     DdNode *F, *G;
00284 
00285     F = *f; G = *g;
00286     if (F == G) return(F);
00287     if (F == DD_ZERO(dd)) return(G);
00288     if (G == DD_ZERO(dd)) return(F);
00289     if (cuddIsConstant(G)) return(G);
00290     return(NULL);
00291 
00292 } /* end of Cudd_addSetNZ */

DdNode* Cudd_addSwapVariables ( DdManager dd,
DdNode f,
DdNode **  x,
DdNode **  y,
int  n 
)

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

Synopsis [Swaps two sets of variables of the same size (x and y) in the ADD f.]

Description [Swaps two sets of variables of the same size (x and y) in the ADD f. The size is given by n. The two sets of variables are assumed to be disjoint. Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addPermute Cudd_bddSwapVariables]

Definition at line 279 of file cuddCompose.c.

00285 {
00286     DdNode *swapped;
00287     int  i, j, k;
00288     int  *permut;
00289 
00290     permut = ALLOC(int,dd->size);
00291     if (permut == NULL) {
00292         dd->errorCode = CUDD_MEMORY_OUT;
00293         return(NULL);
00294     }
00295     for (i = 0; i < dd->size; i++) permut[i] = i;
00296     for (i = 0; i < n; i++) {
00297         j = x[i]->index;
00298         k = y[i]->index;
00299         permut[j] = k;
00300         permut[k] = j;
00301     }
00302 
00303     swapped = Cudd_addPermute(dd,f,permut);
00304     FREE(permut);
00305 
00306     return(swapped);
00307 
00308 } /* end of Cudd_addSwapVariables */

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

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

Synopsis [f if f>=g; 0 if f<g.]

Description [Threshold operator for Apply (f if f >=g; 0 if f<g). Returns NULL if not a terminal case; f op g otherwise.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 244 of file cuddAddApply.c.

00248 {
00249     DdNode *F, *G;
00250 
00251     F = *f; G = *g;
00252     if (F == G || F == DD_PLUS_INFINITY(dd)) return(F);
00253     if (cuddIsConstant(F) && cuddIsConstant(G)) {
00254         if (cuddV(F) >= cuddV(G)) {
00255             return(F);
00256         } else {
00257             return(DD_ZERO(dd));
00258         }
00259     }
00260     return(NULL);
00261 
00262 } /* end of Cudd_addThreshold */

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

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

Synopsis [Integer and floating point multiplication.]

Description [Integer and floating point multiplication. Returns NULL if not a terminal case; f * g otherwise. This function can be used also to take the AND of two 0-1 ADDs.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 204 of file cuddAddApply.c.

00208 {
00209     DdNode *res;
00210     DdNode *F, *G;
00211     CUDD_VALUE_TYPE value;
00212 
00213     F = *f; G = *g;
00214     if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ZERO(dd));
00215     if (F == DD_ONE(dd)) return(G);
00216     if (G == DD_ONE(dd)) return(F);
00217     if (cuddIsConstant(F) && cuddIsConstant(G)) {
00218         value = cuddV(F)*cuddV(G);
00219         res = cuddUniqueConst(dd,value);
00220         return(res);
00221     }
00222     if (F > G) { /* swap f and g */
00223         *f = G;
00224         *g = F;
00225     }
00226     return(NULL);
00227 
00228 } /* end of Cudd_addTimes */

DdNode* Cudd_addTimesPlus ( DdManager dd,
DdNode A,
DdNode B,
DdNode **  z,
int  nz 
)

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

Synopsis [Calculates the product of two matrices represented as ADDs.]

Description [Calculates the product of two matrices, A and B, represented as ADDs, using the CMU matrix by matrix multiplication procedure by Clarke et al.. Matrix A has x's as row variables and z's as column variables, while matrix B has z's as row variables and y's as column variables. Returns the pointer to the result if successful; NULL otherwise. The resulting matrix has x's as row variables and y's as column variables.]

SideEffects [None]

SeeAlso [Cudd_addMatrixMultiply]

Definition at line 181 of file cuddMatMult.c.

00187 {
00188     DdNode *w, *cube, *tmp, *res; 
00189     int i;
00190     tmp = Cudd_addApply(dd,Cudd_addTimes,A,B);
00191     if (tmp == NULL) return(NULL);
00192     Cudd_Ref(tmp);
00193     Cudd_Ref(cube = DD_ONE(dd));
00194     for (i = nz-1; i >= 0; i--) {
00195          w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd));
00196          if (w == NULL) {
00197             Cudd_RecursiveDeref(dd,tmp);
00198             return(NULL);
00199          }
00200          Cudd_Ref(w);
00201          Cudd_RecursiveDeref(dd,cube);
00202          cube = w;
00203     }
00204     res = Cudd_addExistAbstract(dd,tmp,cube);
00205     if (res == NULL) {
00206         Cudd_RecursiveDeref(dd,tmp);
00207         Cudd_RecursiveDeref(dd,cube);
00208         return(NULL);
00209     }
00210     Cudd_Ref(res);
00211     Cudd_RecursiveDeref(dd,cube);
00212     Cudd_RecursiveDeref(dd,tmp);
00213     Cudd_Deref(res);
00214     return(res);
00215 
00216 } /* end of Cudd_addTimesPlus */

DdNode* Cudd_addTriangle ( DdManager dd,
DdNode f,
DdNode g,
DdNode **  z,
int  nz 
)

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

Synopsis [Performs the triangulation step for the shortest path computation.]

Description [Implements the semiring multiplication algorithm used in the triangulation step for the shortest path computation. f is assumed to depend on variables x (rows) and z (columns). g is assumed to depend on variables z (rows) and y (columns). The product of f and g then depends on x (rows) and y (columns). Only the z variables have to be explicitly identified; they are the "abstraction" variables. Returns a pointer to the result if successful; NULL otherwise. ]

SideEffects [None]

SeeAlso [Cudd_addMatrixMultiply Cudd_bddAndAbstract]

Definition at line 239 of file cuddMatMult.c.

00245 {
00246     int    i, nvars, *vars;
00247     DdNode *res, *cube;
00248 
00249     nvars = dd->size;
00250     vars = ALLOC(int, nvars);
00251     if (vars == NULL) {
00252         dd->errorCode = CUDD_MEMORY_OUT;
00253         return(NULL);
00254     }
00255     for (i = 0; i < nvars; i++) vars[i] = -1;
00256     for (i = 0; i < nz; i++) vars[z[i]->index] = i;
00257     cube = Cudd_addComputeCube(dd, z, NULL, nz);
00258     if (cube == NULL) {
00259         FREE(vars);
00260         return(NULL);
00261     }
00262     cuddRef(cube);
00263 
00264     do {
00265         dd->reordered = 0;
00266         res = addTriangleRecur(dd, f, g, vars, cube);
00267     } while (dd->reordered == 1);
00268     if (res != NULL) cuddRef(res);
00269     Cudd_RecursiveDeref(dd,cube);
00270     if (res != NULL) cuddDeref(res);
00271     FREE(vars);
00272     return(res);
00273 
00274 } /* end of Cudd_addTriangle */

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

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

Synopsis [Universally Abstracts all the variables in cube from f.]

Description [Abstracts all the variables in cube from f by taking the product over all possible values taken by the variable. Returns the abstracted ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addExistAbstract Cudd_bddUnivAbstract Cudd_addOrAbstract]

Definition at line 174 of file cuddAddAbs.c.

00178 {
00179     DdNode              *res;
00180 
00181     if (addCheckPositiveCube(manager, cube) == 0) {
00182         (void) fprintf(manager->err,"Error:  Can only abstract cubes");
00183         return(NULL);
00184     }
00185 
00186     do {
00187         manager->reordered = 0;
00188         res = cuddAddUnivAbstractRecur(manager, f, cube);
00189     } while (manager->reordered == 1);
00190 
00191     return(res);
00192 
00193 } /* end of Cudd_addUnivAbstract */

DdNode* Cudd_addVectorCompose ( DdManager dd,
DdNode f,
DdNode **  vector 
)

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

Synopsis [Composes an ADD with a vector of 0-1 ADDs.]

Description [Given a vector of 0-1 ADDs, creates a new ADD by substituting the 0-1 ADDs for the variables of the ADD f. There should be an entry in vector for each variable in the manager. If no substitution is sought for a given variable, the corresponding projection function should be specified in the vector. This function implements simultaneous composition. Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addNonSimCompose Cudd_addPermute Cudd_addCompose Cudd_bddVectorCompose]

Definition at line 559 of file cuddCompose.c.

00563 {
00564     DdHashTable         *table;
00565     DdNode              *res;
00566     int                 deepest;
00567     int                 i;
00568 
00569     do {
00570         dd->reordered = 0;
00571         /* Initialize local cache. */
00572         table = cuddHashTableInit(dd,1,2);
00573         if (table == NULL) return(NULL);
00574 
00575         /* Find deepest real substitution. */
00576         for (deepest = dd->size - 1; deepest >= 0; deepest--) {
00577             i = dd->invperm[deepest];
00578             if (!ddIsIthAddVar(dd,vector[i],i)) {
00579                 break;
00580             }
00581         }
00582 
00583         /* Recursively solve the problem. */
00584         res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest);
00585         if (res != NULL) cuddRef(res);
00586 
00587         /* Dispose of local cache. */
00588         cuddHashTableQuit(table);
00589     } while (dd->reordered == 1);
00590 
00591     if (res != NULL) cuddDeref(res);
00592     return(res);
00593 
00594 } /* end of Cudd_addVectorCompose */

DdNode* Cudd_addWalsh ( DdManager dd,
DdNode **  x,
DdNode **  y,
int  n 
)

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

Synopsis [Generates a Walsh matrix in ADD form.]

Description [Generates a Walsh matrix in ADD form. Returns a pointer to the matrixi if successful; NULL otherwise.]

SideEffects [None]

Definition at line 116 of file cuddAddWalsh.c.

00121 {
00122     DdNode *res;
00123 
00124     do {
00125         dd->reordered = 0;
00126         res = addWalshInt(dd, x, y, n);
00127     } while (dd->reordered == 1);
00128     return(res);
00129 
00130 } /* end of Cudd_addWalsh */

DdNode* Cudd_addXeqy ( DdManager dd,
int  N,
DdNode **  x,
DdNode **  y 
)

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

Synopsis [Generates an ADD for the function x==y.]

Description [This function generates an ADD for the function x==y. Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. The ADD is built bottom-up. It has 3*N-1 internal nodes, if the variables are ordered as follows: x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ]

SideEffects [None]

SeeAlso [Cudd_Xeqy]

Definition at line 404 of file cuddPriority.c.

00409 {
00410     DdNode *one, *zero;
00411     DdNode *u, *v, *w;
00412     int     i;
00413 
00414     one = DD_ONE(dd);
00415     zero = DD_ZERO(dd);
00416 
00417     /* Build bottom part of ADD outside loop. */
00418     v = Cudd_addIte(dd, y[N-1], one, zero);
00419     if (v == NULL) return(NULL);
00420     cuddRef(v);
00421     w = Cudd_addIte(dd, y[N-1], zero, one);
00422     if (w == NULL) {
00423         Cudd_RecursiveDeref(dd, v);
00424         return(NULL);
00425     }
00426     cuddRef(w);
00427     u = Cudd_addIte(dd, x[N-1], v, w);
00428     if (u == NULL) {
00429         Cudd_RecursiveDeref(dd, v);
00430         Cudd_RecursiveDeref(dd, w);
00431         return(NULL);
00432     }
00433     cuddRef(u);
00434     Cudd_RecursiveDeref(dd, v);
00435     Cudd_RecursiveDeref(dd, w);
00436 
00437     /* Loop to build the rest of the ADD. */
00438     for (i = N-2; i >= 0; i--) {
00439         v = Cudd_addIte(dd, y[i], u, zero);
00440         if (v == NULL) {
00441             Cudd_RecursiveDeref(dd, u);
00442             return(NULL);
00443         }
00444         cuddRef(v);
00445         w = Cudd_addIte(dd, y[i], zero, u);
00446         if (w == NULL) {
00447             Cudd_RecursiveDeref(dd, u);
00448             Cudd_RecursiveDeref(dd, v);
00449             return(NULL);
00450         }
00451         cuddRef(w);
00452         Cudd_RecursiveDeref(dd, u);
00453         u = Cudd_addIte(dd, x[i], v, w);
00454         if (w == NULL) {
00455             Cudd_RecursiveDeref(dd, v);
00456             Cudd_RecursiveDeref(dd, w);
00457             return(NULL);
00458         }
00459         cuddRef(u);
00460         Cudd_RecursiveDeref(dd, v);
00461         Cudd_RecursiveDeref(dd, w);
00462     }
00463     cuddDeref(u);
00464     return(u);
00465 
00466 } /* end of Cudd_addXeqy */

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

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

Synopsis [XNOR of two 0-1 ADDs.]

Description [XNOR of two 0-1 ADDs. Returns NULL if not a terminal case; f XNOR g otherwise.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 709 of file cuddAddApply.c.

00713 {
00714     DdNode *F, *G;
00715 
00716     F = *f; G = *g;
00717     if (F == G) return(DD_ONE(dd));
00718     if (F == DD_ONE(dd) && G == DD_ONE(dd)) return(DD_ONE(dd));
00719     if (G == DD_ZERO(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd));
00720     if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd));
00721     if (F > G) { /* swap f and g */
00722         *f = G;
00723         *g = F;
00724     }
00725     return(NULL);
00726 
00727 } /* end of Cudd_addXnor */

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

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

Synopsis [XOR of two 0-1 ADDs.]

Description [XOR of two 0-1 ADDs. Returns NULL if not a terminal case; f XOR g otherwise.]

SideEffects [None]

SeeAlso [Cudd_addApply]

Definition at line 675 of file cuddAddApply.c.

00679 {
00680     DdNode *F, *G;
00681 
00682     F = *f; G = *g;
00683     if (F == G) return(DD_ZERO(dd));
00684     if (F == DD_ONE(dd) && G == DD_ZERO(dd)) return(DD_ONE(dd));
00685     if (G == DD_ONE(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd));
00686     if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd));
00687     if (F > G) { /* swap f and g */
00688         *f = G;
00689         *g = F;
00690     }
00691     return(NULL);
00692 
00693 } /* end of Cudd_addXor */

DdApaDigit Cudd_ApaAdd ( int  digits,
DdApaNumber  a,
DdApaNumber  b,
DdApaNumber  sum 
)

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

Synopsis [Adds two arbitrary precision integers.]

Description [Adds two arbitrary precision integers. Returns the carry out of the most significant digit.]

SideEffects [The result of the sum is stored in parameter sum.]

SeeAlso []

Definition at line 217 of file cuddApa.c.

00222 {
00223     int i;
00224     DdApaDoubleDigit partial = 0;
00225 
00226     for (i = digits - 1; i >= 0; i--) {
00227         partial = a[i] + b[i] + DD_MSDIGIT(partial);
00228         sum[i] = (DdApaDigit) DD_LSDIGIT(partial);
00229     }
00230     return((DdApaDigit) DD_MSDIGIT(partial));
00231 
00232 } /* end of Cudd_ApaAdd */

int Cudd_ApaCompare ( int  digitsFirst,
DdApaNumber  first,
int  digitsSecond,
DdApaNumber  second 
)

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

Synopsis [Compares two arbitrary precision integers.]

Description [Compares two arbitrary precision integers. Returns 1 if the first number is larger; 0 if they are equal; -1 if the second number is larger.]

SideEffects [None]

SeeAlso []

Definition at line 445 of file cuddApa.c.

00450 {
00451     int i;
00452     int firstNZ, secondNZ;
00453 
00454     /* Find first non-zero in both numbers. */
00455     for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++)
00456         if (first[firstNZ] != 0) break;
00457     for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++)
00458         if (second[secondNZ] != 0) break;
00459     if (digitsFirst - firstNZ > digitsSecond - secondNZ) return(1);
00460     else if (digitsFirst - firstNZ < digitsSecond - secondNZ) return(-1);
00461     for (i = 0; i < digitsFirst - firstNZ; i++) {
00462         if (first[firstNZ + i] > second[secondNZ + i]) return(1);
00463         else if (first[firstNZ + i] < second[secondNZ + i]) return(-1);
00464     }
00465     return(0);
00466 
00467 } /* end of Cudd_ApaCompare */

int Cudd_ApaCompareRatios ( int  digitsFirst,
DdApaNumber  firstNum,
unsigned int  firstDen,
int  digitsSecond,
DdApaNumber  secondNum,
unsigned int  secondDen 
)

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

Synopsis [Compares the ratios of two arbitrary precision integers to two unsigned ints.]

Description [Compares the ratios of two arbitrary precision integers to two unsigned ints. Returns 1 if the first number is larger; 0 if they are equal; -1 if the second number is larger.]

SideEffects [None]

SeeAlso []

Definition at line 485 of file cuddApa.c.

00492 {
00493     int result;
00494     DdApaNumber first, second;
00495     unsigned int firstRem, secondRem;
00496 
00497     first = Cudd_NewApaNumber(digitsFirst);
00498     firstRem = Cudd_ApaIntDivision(digitsFirst,firstNum,firstDen,first);
00499     second = Cudd_NewApaNumber(digitsSecond);
00500     secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second);
00501     result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second);
00502     FREE(first);
00503     FREE(second);
00504     if (result == 0) {
00505         if ((double)firstRem/firstDen > (double)secondRem/secondDen)
00506             return(1);
00507         else if ((double)firstRem/firstDen < (double)secondRem/secondDen)
00508             return(-1);
00509     }
00510     return(result);
00511 
00512 } /* end of Cudd_ApaCompareRatios */

void Cudd_ApaCopy ( int  digits,
DdApaNumber  source,
DdApaNumber  dest 
)

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

Synopsis [Makes a copy of an arbitrary precision integer.]

Description [Makes a copy of an arbitrary precision integer.]

SideEffects [Changes parameter dest.]

SeeAlso []

Definition at line 190 of file cuddApa.c.

00194 {
00195     int i;
00196 
00197     for (i = 0; i < digits; i++) {
00198         dest[i] = source[i];
00199     }
00200 
00201 } /* end of Cudd_ApaCopy */

DdApaNumber Cudd_ApaCountMinterm ( DdManager manager,
DdNode node,
int  nvars,
int *  digits 
)

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

Synopsis [Counts the number of minterms of a DD.]

Description [Counts the number of minterms of a DD. The function is assumed to depend on nvars variables. The minterm count is represented as an arbitrary precision unsigned integer, to allow for any number of variables CUDD supports. Returns a pointer to the array representing the number of minterms of the function rooted at node if successful; NULL otherwise.]

SideEffects [The number of digits of the result is returned in parameter digits.]

SeeAlso [Cudd_CountMinterm]

Definition at line 680 of file cuddApa.c.

00685 {
00686     DdApaNumber max, min;
00687     st_table    *table;
00688     DdApaNumber i,count;
00689 
00690     background = manager->background;
00691     zero = Cudd_Not(manager->one);
00692 
00693     *digits = Cudd_ApaNumberOfDigits(nvars+1);
00694     max = Cudd_NewApaNumber(*digits);
00695     if (max == NULL) {
00696         return(NULL);
00697     }
00698     Cudd_ApaPowerOfTwo(*digits,max,nvars);
00699     min = Cudd_NewApaNumber(*digits);
00700     if (min == NULL) {
00701         FREE(max);
00702         return(NULL);
00703     }
00704     Cudd_ApaSetToLiteral(*digits,min,0);
00705     table = st_init_table(st_ptrcmp,st_ptrhash);
00706     if (table == NULL) {
00707         FREE(max);
00708         FREE(min);
00709         return(NULL);
00710     }
00711     i = cuddApaCountMintermAux(Cudd_Regular(node),*digits,max,min,table);
00712     if (i == NULL) {
00713         FREE(max);
00714         FREE(min);
00715         st_foreach(table, cuddApaStCountfree, NULL);
00716         st_free_table(table);
00717         return(NULL);
00718     }
00719     count = Cudd_NewApaNumber(*digits);
00720     if (count == NULL) {
00721         FREE(max);
00722         FREE(min);
00723         st_foreach(table, cuddApaStCountfree, NULL);
00724         st_free_table(table);
00725         if (Cudd_Regular(node)->ref == 1) FREE(i);
00726         return(NULL);
00727     }
00728     if (Cudd_IsComplement(node)) {
00729         (void) Cudd_ApaSubtract(*digits,max,i,count);
00730     } else {
00731         Cudd_ApaCopy(*digits,i,count);
00732     }
00733     FREE(max);
00734     FREE(min);
00735     st_foreach(table, cuddApaStCountfree, NULL);
00736     st_free_table(table);
00737     if (Cudd_Regular(node)->ref == 1) FREE(i);
00738     return(count);
00739 
00740 } /* end of Cudd_ApaCountMinterm */

unsigned int Cudd_ApaIntDivision ( int  digits,
DdApaNumber  dividend,
unsigned int  divisor,
DdApaNumber  quotient 
)

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

Synopsis [Divides an arbitrary precision integer by an integer.]

Description [Divides an arbitrary precision integer by a 32-bit unsigned integer. Returns the remainder of the division. This procedure relies on the assumption that the number of bits of a DdApaDigit plus the number of bits of an unsigned int is less the number of bits of the mantissa of a double. This guarantees that the product of a DdApaDigit and an unsigned int can be represented without loss of precision by a double. On machines where this assumption is not satisfied, this procedure will malfunction.]

SideEffects [The quotient is returned in parameter quotient.]

SeeAlso [Cudd_ApaShortDivision]

Definition at line 320 of file cuddApa.c.

00325 {
00326     int i;
00327     double partial;
00328     unsigned int remainder = 0;
00329     double ddiv = (double) divisor;
00330 
00331     for (i = 0; i < digits; i++) {
00332         partial = (double) remainder * DD_APA_BASE + dividend[i];
00333         quotient[i] = (DdApaDigit) (partial / ddiv);
00334         remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv));
00335     }
00336 
00337     return(remainder);
00338 
00339 } /* end of Cudd_ApaIntDivision */

int Cudd_ApaNumberOfDigits ( int  binaryDigits  ) 

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

Synopsis [Finds the number of digits for an arbitrary precision integer.]

Description [Finds the number of digits for an arbitrary precision integer given the maximum number of binary digits. The number of binary digits should be positive. Returns the number of digits if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 143 of file cuddApa.c.

00145 {
00146     int digits;
00147 
00148     digits = binaryDigits / DD_APA_BITS;
00149     if ((digits * DD_APA_BITS) != binaryDigits)
00150         digits++;
00151     return(digits);
00152 
00153 } /* end of Cudd_ApaNumberOfDigits */

void Cudd_ApaPowerOfTwo ( int  digits,
DdApaNumber  number,
int  power 
)

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

Synopsis [Sets an arbitrary precision integer to a power of two.]

Description [Sets an arbitrary precision integer to a power of two. If the power of two is too large to be represented, the number is set to 0.]

SideEffects [The result is returned in parameter number.]

SeeAlso []

Definition at line 413 of file cuddApa.c.

00417 {
00418     int i;
00419     int index;
00420 
00421     for (i = 0; i < digits; i++)
00422         number[i] = 0;
00423     i = digits - 1 - power / DD_APA_BITS;
00424     if (i < 0) return;
00425     index = power & (DD_APA_BITS - 1);
00426     number[i] = 1 << index;
00427 
00428 } /* end of Cudd_ApaPowerOfTwo */

int Cudd_ApaPrintDecimal ( FILE *  fp,
int  digits,
DdApaNumber  number 
)

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

Synopsis [Prints an arbitrary precision integer in decimal format.]

Description [Prints an arbitrary precision integer in decimal format. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintExponential]

Definition at line 558 of file cuddApa.c.

00562 {
00563     int i, result;
00564     DdApaDigit remainder;
00565     DdApaNumber work;
00566     unsigned char *decimal;
00567     int leadingzero;
00568     int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1;
00569 
00570     work = Cudd_NewApaNumber(digits);
00571     if (work == NULL)
00572         return(0);
00573     decimal = ALLOC(unsigned char, decimalDigits);
00574     if (decimal == NULL) {
00575         FREE(work);
00576         return(0);
00577     }
00578     Cudd_ApaCopy(digits,number,work);
00579     for (i = decimalDigits - 1; i >= 0; i--) {
00580         remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work);
00581         decimal[i] = (unsigned char) remainder;
00582     }
00583     FREE(work);
00584 
00585     leadingzero = 1;
00586     for (i = 0; i < decimalDigits; i++) {
00587         leadingzero = leadingzero && (decimal[i] == 0);
00588         if ((!leadingzero) || (i == (decimalDigits - 1))) {
00589             result = fprintf(fp,"%1d",decimal[i]);
00590             if (result == EOF) {
00591                 FREE(decimal);
00592                 return(0);
00593             }
00594         }
00595     }
00596     FREE(decimal);
00597     return(1);
00598 
00599 } /* end of Cudd_ApaPrintDecimal */

int Cudd_ApaPrintDensity ( FILE *  fp,
DdManager dd,
DdNode node,
int  nvars 
)

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

Synopsis [Prints the density of a BDD or ADD using arbitrary precision arithmetic.]

Description [Prints the density of a BDD or ADD using arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 834 of file cuddApa.c.

00839 {
00840     int digits;
00841     int result;
00842     DdApaNumber count,density;
00843     unsigned int size, remainder, fractional;
00844 
00845     count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
00846     if (count == NULL)
00847         return(0);
00848     size = Cudd_DagSize(node);
00849     density = Cudd_NewApaNumber(digits);
00850     remainder = Cudd_ApaIntDivision(digits,count,size,density);
00851     result = Cudd_ApaPrintDecimal(fp,digits,density);
00852     FREE(count);
00853     FREE(density);
00854     fractional = (unsigned int)((double)remainder / size * 1000000);
00855     if (fprintf(fp,".%u\n", fractional) == EOF) {
00856         return(0);
00857     }
00858     return(result);
00859 
00860 } /* end of Cudd_ApaPrintDensity */

int Cudd_ApaPrintExponential ( FILE *  fp,
int  digits,
DdApaNumber  number,
int  precision 
)

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

Synopsis [Prints an arbitrary precision integer in exponential format.]

Description [Prints an arbitrary precision integer in exponential format. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_ApaPrintHex Cudd_ApaPrintDecimal]

Definition at line 615 of file cuddApa.c.

00620 {
00621     int i, first, last, result;
00622     DdApaDigit remainder;
00623     DdApaNumber work;
00624     unsigned char *decimal;
00625     int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1;
00626 
00627     work = Cudd_NewApaNumber(digits);
00628     if (work == NULL)
00629         return(0);
00630     decimal = ALLOC(unsigned char, decimalDigits);
00631     if (decimal == NULL) {
00632         FREE(work);
00633         return(0);
00634     }
00635     Cudd_ApaCopy(digits,number,work);
00636     first = decimalDigits - 1;
00637     for (i = decimalDigits - 1; i >= 0; i--) {
00638         remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work);
00639         decimal[i] = (unsigned char) remainder;
00640         if (remainder != 0) first = i; /* keep track of MS non-zero */
00641     }
00642     FREE(work);
00643     last = ddMin(first + precision, decimalDigits);
00644 
00645     for (i = first; i < last; i++) {
00646         result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]);
00647         if (result == EOF) {
00648             FREE(decimal);
00649             return(0);
00650         }
00651     }
00652     FREE(decimal);
00653     result = fprintf(fp,"e+%d",decimalDigits - first - 1);
00654     if (result == EOF) {
00655         return(0);
00656     }
00657     return(1);
00658 
00659 } /* end of Cudd_ApaPrintExponential */

int Cudd_ApaPrintHex ( FILE *  fp,
int  digits,
DdApaNumber  number 
)

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

Synopsis [Prints an arbitrary precision integer in hexadecimal format.]

Description [Prints an arbitrary precision integer in hexadecimal format. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_ApaPrintDecimal Cudd_ApaPrintExponential]

Definition at line 528 of file cuddApa.c.

00532 {
00533     int i, result;
00534 
00535     for (i = 0; i < digits; i++) {
00536         result = fprintf(fp,DD_APA_HEXPRINT,number[i]);
00537         if (result == EOF)
00538             return(0);
00539     }
00540     return(1);
00541 
00542 } /* end of Cudd_ApaPrintHex */

int Cudd_ApaPrintMinterm ( FILE *  fp,
DdManager dd,
DdNode node,
int  nvars 
)

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

Synopsis [Prints the number of minterms of a BDD or ADD using arbitrary precision arithmetic.]

Description [Prints the number of minterms of a BDD or ADD using arbitrary precision arithmetic. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_ApaPrintMintermExp]

Definition at line 757 of file cuddApa.c.

00762 {
00763     int digits;
00764     int result;
00765     DdApaNumber count;
00766 
00767     count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
00768     if (count == NULL)
00769         return(0);
00770     result = Cudd_ApaPrintDecimal(fp,digits,count);
00771     FREE(count);
00772     if (fprintf(fp,"\n") == EOF) {
00773         return(0);
00774     }
00775     return(result);
00776 
00777 } /* end of Cudd_ApaPrintMinterm */

int Cudd_ApaPrintMintermExp ( FILE *  fp,
DdManager dd,
DdNode node,
int  nvars,
int  precision 
)

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

Synopsis [Prints the number of minterms of a BDD or ADD in exponential format using arbitrary precision arithmetic.]

Description [Prints the number of minterms of a BDD or ADD in exponential format using arbitrary precision arithmetic. Parameter precision controls the number of signficant digits printed. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_ApaPrintMinterm]

Definition at line 796 of file cuddApa.c.

00802 {
00803     int digits;
00804     int result;
00805     DdApaNumber count;
00806 
00807     count = Cudd_ApaCountMinterm(dd,node,nvars,&digits);
00808     if (count == NULL)
00809         return(0);
00810     result = Cudd_ApaPrintExponential(fp,digits,count,precision);
00811     FREE(count);
00812     if (fprintf(fp,"\n") == EOF) {
00813         return(0);
00814     }
00815     return(result);
00816 
00817 } /* end of Cudd_ApaPrintMintermExp */

void Cudd_ApaSetToLiteral ( int  digits,
DdApaNumber  number,
DdApaDigit  literal 
)

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

Synopsis [Sets an arbitrary precision integer to a one-digit literal.]

Description [Sets an arbitrary precision integer to a one-digit literal.]

SideEffects [The result is returned in parameter number.]

SeeAlso []

Definition at line 385 of file cuddApa.c.

00389 {
00390     int i;
00391 
00392     for (i = 0; i < digits - 1; i++)
00393         number[i] = 0;
00394     number[digits - 1] = literal;
00395 
00396 } /* end of Cudd_ApaSetToLiteral */

void Cudd_ApaShiftRight ( int  digits,
DdApaDigit  in,
DdApaNumber  a,
DdApaNumber  b 
)

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

Synopsis [Shifts right an arbitrary precision integer by one binary place.]

Description [Shifts right an arbitrary precision integer by one binary place. The most significant binary digit of the result is taken from parameter in.]

SideEffects [The result is returned in parameter b.]

SeeAlso []

Definition at line 357 of file cuddApa.c.

00362 {
00363     int i;
00364 
00365     for (i = digits - 1; i > 0; i--) {
00366         b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1));
00367     }
00368     b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1));
00369 
00370 } /* end of Cudd_ApaShiftRight */

DdApaDigit Cudd_ApaShortDivision ( int  digits,
DdApaNumber  dividend,
DdApaDigit  divisor,
DdApaNumber  quotient 
)

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

Synopsis [Divides an arbitrary precision integer by a digit.]

Description [Divides an arbitrary precision integer by a digit.]

SideEffects [The quotient is returned in parameter quotient.]

SeeAlso []

Definition at line 279 of file cuddApa.c.

00284 {
00285     int i;
00286     DdApaDigit remainder;
00287     DdApaDoubleDigit partial;
00288 
00289     remainder = 0;
00290     for (i = 0; i < digits; i++) {
00291         partial = remainder * DD_APA_BASE + dividend[i];
00292         quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor);
00293         remainder = (DdApaDigit) (partial % divisor);
00294     }
00295 
00296     return(remainder);
00297 
00298 } /* end of Cudd_ApaShortDivision */

DdApaDigit Cudd_ApaSubtract ( int  digits,
DdApaNumber  a,
DdApaNumber  b,
DdApaNumber  diff 
)

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

Synopsis [Subtracts two arbitrary precision integers.]

Description [Subtracts two arbitrary precision integers. Returns the borrow out of the most significant digit.]

SideEffects [The result of the subtraction is stored in parameter diff.]

SeeAlso []

Definition at line 249 of file cuddApa.c.

00254 {
00255     int i;
00256     DdApaDoubleDigit partial = DD_APA_BASE;
00257 
00258     for (i = digits - 1; i >= 0; i--) {
00259         partial = DD_MSDIGIT(partial) + DD_APA_MASK + a[i] - b[i];
00260         diff[i] = (DdApaDigit) DD_LSDIGIT(partial);
00261     }
00262     return((DdApaDigit) DD_MSDIGIT(partial) - 1);
00263 
00264 } /* end of Cudd_ApaSubtract */

void Cudd_AutodynDisable ( DdManager unique  ) 

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

Synopsis [Disables automatic dynamic reordering.]

Description []

SideEffects [None]

SeeAlso [Cudd_AutodynEnable Cudd_ReorderingStatus Cudd_AutodynDisableZdd]

Definition at line 704 of file cuddAPI.c.

00706 {
00707     unique->autoDyn = 0;
00708     return;
00709 
00710 } /* end of Cudd_AutodynDisable */

void Cudd_AutodynDisableZdd ( DdManager unique  ) 

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

Synopsis [Disables automatic dynamic reordering of ZDDs.]

Description []

SideEffects [None]

SeeAlso [Cudd_AutodynEnableZdd Cudd_ReorderingStatusZdd Cudd_AutodynDisable]

Definition at line 782 of file cuddAPI.c.

00784 {
00785     unique->autoDynZ = 0;
00786     return;
00787 
00788 } /* end of Cudd_AutodynDisableZdd */

void Cudd_AutodynEnable ( DdManager unique,
Cudd_ReorderingType  method 
)

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

Synopsis [Enables automatic dynamic reordering of BDDs and ADDs.]

Description [Enables automatic dynamic reordering of BDDs and ADDs. Parameter method is used to determine the method used for reordering. If CUDD_REORDER_SAME is passed, the method is unchanged.]

SideEffects [None]

SeeAlso [Cudd_AutodynDisable Cudd_ReorderingStatus Cudd_AutodynEnableZdd]

Definition at line 665 of file cuddAPI.c.

00668 {
00669     unique->autoDyn = 1;
00670     if (method != CUDD_REORDER_SAME) {
00671         unique->autoMethod = method;
00672     }
00673 #ifndef DD_NO_DEATH_ROW
00674     /* If reordering is enabled, using the death row causes too many
00675     ** invocations. Hence, we shrink the death row to just one entry.
00676     */
00677     cuddClearDeathRow(unique);
00678     unique->deathRowDepth = 1;
00679     unique->deadMask = unique->deathRowDepth - 1;
00680     if ((unsigned) unique->nextDead > unique->deadMask) {
00681         unique->nextDead = 0;
00682     }
00683     unique->deathRow = REALLOC(DdNodePtr, unique->deathRow,
00684         unique->deathRowDepth);
00685 #endif
00686     return;
00687 
00688 } /* end of Cudd_AutodynEnable */

void Cudd_AutodynEnableZdd ( DdManager unique,
Cudd_ReorderingType  method 
)

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

Synopsis [Enables automatic dynamic reordering of ZDDs.]

Description [Enables automatic dynamic reordering of ZDDs. Parameter method is used to determine the method used for reordering ZDDs. If CUDD_REORDER_SAME is passed, the method is unchanged.]

SideEffects [None]

SeeAlso [Cudd_AutodynDisableZdd Cudd_ReorderingStatusZdd Cudd_AutodynEnable]

Definition at line 756 of file cuddAPI.c.

00759 {
00760     unique->autoDynZ = 1;
00761     if (method != CUDD_REORDER_SAME) {
00762         unique->autoMethodZ = method;
00763     }
00764     return;
00765 
00766 } /* end of Cudd_AutodynEnableZdd */

double Cudd_AverageDistance ( DdManager dd  ) 

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

Synopsis [Computes the average distance between adjacent nodes.]

Description [Computes the average distance between adjacent nodes in the manager. Adjacent nodes are node pairs such that the second node is the then child, else child, or next node in the collision list.]

SideEffects [None]

SeeAlso []

Definition at line 2610 of file cuddUtil.c.

02612 {
02613     double tetotal, nexttotal;
02614     double tesubtotal, nextsubtotal;
02615     double temeasured, nextmeasured;
02616     int i, j;
02617     int slots, nvars;
02618     long diff;
02619     DdNode *scan;
02620     DdNodePtr *nodelist;
02621     DdNode *sentinel = &(dd->sentinel);
02622 
02623     nvars = dd->size;
02624     if (nvars == 0) return(0.0);
02625 
02626     /* Initialize totals. */
02627     tetotal = 0.0;
02628     nexttotal = 0.0;
02629     temeasured = 0.0;
02630     nextmeasured = 0.0;
02631 
02632     /* Scan the variable subtables. */
02633     for (i = 0; i < nvars; i++) {
02634         nodelist = dd->subtables[i].nodelist;
02635         tesubtotal = 0.0;
02636         nextsubtotal = 0.0;
02637         slots = dd->subtables[i].slots;
02638         for (j = 0; j < slots; j++) {
02639             scan = nodelist[j];
02640             while (scan != sentinel) {
02641                 diff = (long) scan - (long) cuddT(scan);
02642                 tesubtotal += (double) ddAbs(diff);
02643                 diff = (long) scan - (long) Cudd_Regular(cuddE(scan));
02644                 tesubtotal += (double) ddAbs(diff);
02645                 temeasured += 2.0;
02646                 if (scan->next != sentinel) {
02647                     diff = (long) scan - (long) scan->next;
02648                     nextsubtotal += (double) ddAbs(diff);
02649                     nextmeasured += 1.0;
02650                 }
02651                 scan = scan->next;
02652             }
02653         }
02654         tetotal += tesubtotal;
02655         nexttotal += nextsubtotal;
02656     }
02657 
02658     /* Scan the constant table. */
02659     nodelist = dd->constants.nodelist;
02660     nextsubtotal = 0.0;
02661     slots = dd->constants.slots;
02662     for (j = 0; j < slots; j++) {
02663         scan = nodelist[j];
02664         while (scan != NULL) {
02665             if (scan->next != NULL) {
02666                 diff = (long) scan - (long) scan->next;
02667                 nextsubtotal += (double) ddAbs(diff);
02668                 nextmeasured += 1.0;
02669             }
02670             scan = scan->next;
02671         }
02672     }
02673     nexttotal += nextsubtotal;
02674 
02675     return((tetotal + nexttotal) / (temeasured + nextmeasured));
02676 
02677 } /* end of Cudd_AverageDistance */

DdNode* Cudd_bddAdjPermuteX ( DdManager dd,
DdNode B,
DdNode **  x,
int  n 
)

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

Synopsis [Rearranges a set of variables in the BDD B.]

Description [Rearranges a set of variables in the BDD B. The size of the set is given by n. This procedure is intended for the `randomization' of the priority functions. Returns a pointer to the BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables Cudd_Dxygtdxz Cudd_Dxygtdyz Cudd_PrioritySelect]

Definition at line 508 of file cuddCompose.c.

00513 {
00514     DdNode *swapped;
00515     int  i, j, k;
00516     int  *permut;
00517 
00518     permut = ALLOC(int,dd->size);
00519     if (permut == NULL) {
00520         dd->errorCode = CUDD_MEMORY_OUT;
00521         return(NULL);
00522     }
00523     for (i = 0; i < dd->size; i++) permut[i] = i;
00524     for (i = 0; i < n-2; i += 3) {
00525         j = x[i]->index;
00526         k = x[i+1]->index;
00527         permut[j] = k;
00528         permut[k] = j;
00529     }
00530 
00531     swapped = Cudd_bddPermute(dd,B,permut);
00532     FREE(permut);
00533 
00534     return(swapped);
00535 
00536 } /* end of Cudd_bddAdjPermuteX */

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

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

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

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

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAndAbstract Cudd_bddIntersect Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]

Definition at line 310 of file cuddBddIte.c.

00314 {
00315     DdNode *res;
00316 
00317     do {
00318         dd->reordered = 0;
00319         res = cuddBddAndRecur(dd,f,g);
00320     } while (dd->reordered == 1);
00321     return(res);
00322 
00323 } /* end of Cudd_bddAnd */

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

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

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

Description [Takes the AND of two BDDs and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the result is successful; NULL otherwise. Cudd_bddAndAbstract implements the semiring matrix multiplication algorithm for the boolean semiring.]

SideEffects [None]

SeeAlso [Cudd_addMatrixMultiply Cudd_addTriangle Cudd_bddAnd]

Definition at line 120 of file cuddAndAbs.c.

00125 {
00126     DdNode *res;
00127 
00128     do {
00129         manager->reordered = 0;
00130         res = cuddBddAndAbstractRecur(manager, f, g, cube);
00131     } while (manager->reordered == 1);
00132     return(res);
00133 
00134 } /* end of Cudd_bddAndAbstract */

DdNode* Cudd_bddAndAbstractLimit ( DdManager manager,
DdNode f,
DdNode g,
DdNode cube,
unsigned int  limit 
)

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

Synopsis [Takes the AND of two BDDs and simultaneously abstracts the variables in cube. Returns NULL if too many nodes are required.]

Description [Takes the AND of two BDDs and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the result is successful; NULL otherwise. In particular, if the number of new nodes created exceeds limit, this function returns NULL.]

SideEffects [None]

SeeAlso [Cudd_bddAndAbstract]

Definition at line 154 of file cuddAndAbs.c.

00160 {
00161     DdNode *res;
00162     unsigned int saveLimit = manager->maxLive;
00163 
00164     manager->maxLive = (manager->keys - manager->dead) +
00165       (manager->keysZ - manager->deadZ) + limit;
00166     do {
00167         manager->reordered = 0;
00168         res = cuddBddAndAbstractRecur(manager, f, g, cube);
00169     } while (manager->reordered == 1);
00170     manager->maxLive = saveLimit;
00171     return(res);
00172 
00173 } /* end of Cudd_bddAndAbstractLimit */

DdNode* Cudd_bddAndLimit ( DdManager dd,
DdNode f,
DdNode g,
unsigned int  limit 
)

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

Synopsis [Computes the conjunction of two BDDs f and g. Returns NULL if too many nodes are required.]

Description [Computes the conjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up or more new nodes than limit are required.]

SideEffects [None]

SeeAlso [Cudd_bddAnd]

Definition at line 342 of file cuddBddIte.c.

00347 {
00348     DdNode *res;
00349     unsigned int saveLimit = dd->maxLive;
00350 
00351     dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit;
00352     do {
00353         dd->reordered = 0;
00354         res = cuddBddAndRecur(dd,f,g);
00355     } while (dd->reordered == 1);
00356     dd->maxLive = saveLimit;
00357     return(res);
00358 
00359 } /* end of Cudd_bddAndLimit */

int Cudd_bddApproxConjDecomp ( DdManager dd,
DdNode f,
DdNode ***  conjuncts 
)

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

Synopsis [Performs two-way conjunctive decomposition of a BDD.]

Description [Performs two-way conjunctive decomposition of a BDD. This procedure owes its name to the use of supersetting to obtain an initial factor of the given function. Returns the number of conjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise. The conjuncts produced by this procedure tend to be imbalanced.]

SideEffects [The factors are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the conjuncts are already referenced. If the function returns 0, the array for the conjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]

SeeAlso [Cudd_bddApproxDisjDecomp Cudd_bddIterConjDecomp Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox Cudd_bddSqueeze Cudd_bddLICompaction]

Definition at line 171 of file cuddDecomp.c.

00175 {
00176     DdNode *superset1, *superset2, *glocal, *hlocal;
00177     int nvars = Cudd_SupportSize(dd,f);
00178 
00179     /* Find a tentative first factor by overapproximation and minimization. */
00180     superset1 = Cudd_RemapOverApprox(dd,f,nvars,0,1.0);
00181     if (superset1 == NULL) return(0);
00182     cuddRef(superset1);
00183     superset2 = Cudd_bddSqueeze(dd,f,superset1);
00184     if (superset2 == NULL) {
00185         Cudd_RecursiveDeref(dd,superset1);
00186         return(0);
00187     }
00188     cuddRef(superset2);
00189     Cudd_RecursiveDeref(dd,superset1);
00190 
00191     /* Compute the second factor by minimization. */
00192     hlocal = Cudd_bddLICompaction(dd,f,superset2);
00193     if (hlocal == NULL) {
00194         Cudd_RecursiveDeref(dd,superset2);
00195         return(0);
00196     }
00197     cuddRef(hlocal);
00198 
00199     /* Refine the first factor by minimization. If h turns out to be f, this
00200     ** step guarantees that g will be 1. */
00201     glocal = Cudd_bddLICompaction(dd,superset2,hlocal);
00202     if (glocal == NULL) {
00203         Cudd_RecursiveDeref(dd,superset2);
00204         Cudd_RecursiveDeref(dd,hlocal);
00205         return(0);
00206     }
00207     cuddRef(glocal);
00208     Cudd_RecursiveDeref(dd,superset2);
00209 
00210     if (glocal != DD_ONE(dd)) {
00211         if (hlocal != DD_ONE(dd)) {
00212             *conjuncts = ALLOC(DdNode *,2);
00213             if (*conjuncts == NULL) {
00214                 Cudd_RecursiveDeref(dd,glocal);
00215                 Cudd_RecursiveDeref(dd,hlocal);
00216                 dd->errorCode = CUDD_MEMORY_OUT;
00217                 return(0);
00218             }
00219             (*conjuncts)[0] = glocal;
00220             (*conjuncts)[1] = hlocal;
00221             return(2);
00222         } else {
00223             Cudd_RecursiveDeref(dd,hlocal);
00224             *conjuncts = ALLOC(DdNode *,1);
00225             if (*conjuncts == NULL) {
00226                 Cudd_RecursiveDeref(dd,glocal);
00227                 dd->errorCode = CUDD_MEMORY_OUT;
00228                 return(0);
00229             }
00230             (*conjuncts)[0] = glocal;
00231             return(1);
00232         }
00233     } else {
00234         Cudd_RecursiveDeref(dd,glocal);
00235         *conjuncts = ALLOC(DdNode *,1);
00236         if (*conjuncts == NULL) {
00237             Cudd_RecursiveDeref(dd,hlocal);
00238             dd->errorCode = CUDD_MEMORY_OUT;
00239             return(0);
00240         }
00241         (*conjuncts)[0] = hlocal;
00242         return(1);
00243     }
00244 
00245 } /* end of Cudd_bddApproxConjDecomp */

int Cudd_bddApproxDisjDecomp ( DdManager dd,
DdNode f,
DdNode ***  disjuncts 
)

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

Synopsis [Performs two-way disjunctive decomposition of a BDD.]

Description [Performs two-way disjunctive decomposition of a BDD. Returns the number of disjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise. The disjuncts produced by this procedure tend to be imbalanced.]

SideEffects [The two disjuncts are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the disjuncts are already referenced. If the function returns 0, the array for the disjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]

SeeAlso [Cudd_bddApproxConjDecomp Cudd_bddIterDisjDecomp Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp]

Definition at line 269 of file cuddDecomp.c.

00273 {
00274     int result, i;
00275 
00276     result = Cudd_bddApproxConjDecomp(dd,Cudd_Not(f),disjuncts);
00277     for (i = 0; i < result; i++) {
00278         (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]);
00279     }
00280     return(result);
00281 
00282 } /* end of Cudd_bddApproxDisjDecomp */

int Cudd_bddBindVar ( DdManager dd,
int  index 
)

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

Synopsis [Prevents sifting of a variable.]

Description [This function sets a flag to prevent sifting of a variable. Returns 1 if successful; 0 otherwise (i.e., invalid variable index).]

SideEffects [Changes the "bindVar" flag in DdSubtable.]

SeeAlso [Cudd_bddUnbindVar]

Definition at line 3896 of file cuddAPI.c.

03899 {
03900     if (index >= dd->size || index < 0) return(0);
03901     dd->subtables[dd->perm[index]].bindVar = 1;
03902     return(1);
03903 
03904 } /* end of Cudd_bddBindVar */

DdNode* Cudd_bddBooleanDiff ( DdManager manager,
DdNode f,
int  x 
)

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

Synopsis [Computes the boolean difference of f with respect to x.]

Description [Computes the boolean difference of f with respect to the variable with index x. Returns the BDD of the boolean difference if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 242 of file cuddBddAbs.c.

00246 {
00247     DdNode *res, *var;
00248 
00249     /* If the variable is not currently in the manager, f cannot
00250     ** depend on it.
00251     */
00252     if (x >= manager->size) return(Cudd_Not(DD_ONE(manager)));
00253     var = manager->vars[x];
00254 
00255     do {
00256         manager->reordered = 0;
00257         res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var);
00258     } while (manager->reordered == 1);
00259 
00260     return(res);
00261 
00262 } /* end of Cudd_bddBooleanDiff */

DdNode** Cudd_bddCharToVect ( DdManager dd,
DdNode f 
)

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

Synopsis [Computes a vector whose image equals a non-zero function.]

Description [Computes a vector of BDDs whose image equals a non-zero function. The result depends on the variable order. The i-th component of the vector depends only on the first i variables in the order. Each BDD in the vector is not larger than the BDD of the given characteristic function. This function is based on the description of char-to-vect in "Verification of Sequential Machines Using Boolean Functional Vectors" by O. Coudert, C. Berthet and J. C. Madre. Returns a pointer to an array containing the result if successful; NULL otherwise. The size of the array equals the number of variables in the manager. The components of the solution have their reference counts already incremented (unlike the results of most other functions in the package).]

SideEffects [None]

SeeAlso [Cudd_bddConstrain]

Definition at line 506 of file cuddGenCof.c.

00509 {
00510     int i, j;
00511     DdNode **vect;
00512     DdNode *res = NULL;
00513 
00514     if (f == Cudd_Not(DD_ONE(dd))) return(NULL);
00515 
00516     vect = ALLOC(DdNode *, dd->size);
00517     if (vect == NULL) {
00518         dd->errorCode = CUDD_MEMORY_OUT;
00519         return(NULL);
00520     }
00521 
00522     do {
00523         dd->reordered = 0;
00524         for (i = 0; i < dd->size; i++) {
00525             res = cuddBddCharToVect(dd,f,dd->vars[dd->invperm[i]]);
00526             if (res == NULL) {
00527                 /* Clean up the vector array in case reordering took place. */
00528                 for (j = 0; j < i; j++) {
00529                     Cudd_IterDerefBdd(dd, vect[dd->invperm[j]]);
00530                 }
00531                 break;
00532             }
00533             cuddRef(res);
00534             vect[dd->invperm[i]] = res;
00535         }
00536     } while (dd->reordered == 1);
00537     if (res == NULL) {
00538         FREE(vect);
00539         return(NULL);
00540     }
00541     return(vect);
00542 
00543 } /* end of Cudd_bddCharToVect */

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

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

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

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

SideEffects [None]

SeeAlso [Cudd_bddAnd]

Definition at line 125 of file cuddClip.c.

00131 {
00132     DdNode *res;
00133 
00134     do {
00135         dd->reordered = 0;
00136         res = cuddBddClippingAnd(dd,f,g,maxDepth,direction);
00137     } while (dd->reordered == 1);
00138     return(res);
00139 
00140 } /* end of Cudd_bddClippingAnd */

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

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

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

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

SideEffects [None]

SeeAlso [Cudd_bddAndAbstract Cudd_bddClippingAnd]

Definition at line 159 of file cuddClip.c.

00166 {
00167     DdNode *res;
00168 
00169     do {
00170         dd->reordered = 0;
00171         res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction);
00172     } while (dd->reordered == 1);
00173     return(res);
00174 
00175 } /* end of Cudd_bddClippingAndAbstract */

DdNode* Cudd_bddClosestCube ( DdManager dd,
DdNode f,
DdNode g,
int *  distance 
)

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

Synopsis [Finds a cube of f at minimum Hamming distance from g.]

Description [Finds a cube of f at minimum Hamming distance from the minterms of g. All the minterms of the cube are at the minimum distance. If the distance is 0, the cube belongs to the intersection of f and g. Returns the cube if successful; NULL otherwise.]

SideEffects [The distance is returned as a side effect.]

SeeAlso [Cudd_MinHammingDist]

Definition at line 1355 of file cuddPriority.c.

01360 {
01361     DdNode *res, *acube;
01362     CUDD_VALUE_TYPE rdist;
01363 
01364     /* Compute the cube and distance as a single ADD. */
01365     do {
01366         dd->reordered = 0;
01367         res = cuddBddClosestCube(dd,f,g,CUDD_CONST_INDEX + 1.0);
01368     } while (dd->reordered == 1);
01369     if (res == NULL) return(NULL);
01370     cuddRef(res);
01371 
01372     /* Unpack distance and cube. */
01373     do {
01374         dd->reordered = 0;
01375         acube = separateCube(dd, res, &rdist);
01376     } while (dd->reordered == 1);
01377     if (acube == NULL) {
01378         Cudd_RecursiveDeref(dd, res);
01379         return(NULL);
01380     }
01381     cuddRef(acube);
01382     Cudd_RecursiveDeref(dd, res);
01383 
01384     /* Convert cube from ADD to BDD. */
01385     do {
01386         dd->reordered = 0;
01387         res = cuddAddBddDoPattern(dd, acube);
01388     } while (dd->reordered == 1);
01389     if (res == NULL) {
01390         Cudd_RecursiveDeref(dd, acube);
01391         return(NULL);
01392     }
01393     cuddRef(res);
01394     Cudd_RecursiveDeref(dd, acube);
01395 
01396     *distance = (int) rdist;
01397     cuddDeref(res);
01398     return(res);
01399 
01400 } /* end of Cudd_bddClosestCube */

DdNode* Cudd_bddCompose ( DdManager dd,
DdNode f,
DdNode g,
int  v 
)

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

Synopsis [Substitutes g for x_v in the BDD for f.]

Description [Substitutes g for x_v in the BDD for f. v is the index of the variable to be substituted. Cudd_bddCompose passes the corresponding projection function to the recursive procedure, so that the cache may be used. Returns the composed BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addCompose]

Definition at line 163 of file cuddCompose.c.

00168 {
00169     DdNode *proj, *res;
00170 
00171     /* Sanity check. */
00172     if (v < 0 || v >= dd->size) return(NULL);
00173 
00174     proj =  dd->vars[v];
00175     do {
00176         dd->reordered = 0;
00177         res = cuddBddComposeRecur(dd,f,g,proj);
00178     } while (dd->reordered == 1);
00179     return(res);
00180 
00181 } /* end of Cudd_bddCompose */

DdNode* Cudd_bddComputeCube ( DdManager dd,
DdNode **  vars,
int *  phase,
int  n 
)

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

Synopsis [Computes the cube of an array of BDD variables.]

Description [Computes the cube of an array of BDD variables. If non-null, the phase argument indicates which literal of each variable should appear in the cube. If phase\[i\] is nonzero, then the positive literal is used. If phase is NULL, the cube is positive unate. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addComputeCube Cudd_IndicesToCube Cudd_CubeArrayToBdd]

Definition at line 2192 of file cuddUtil.c.

02197 {
02198     DdNode      *cube;
02199     DdNode      *fn;
02200     int         i;
02201 
02202     cube = DD_ONE(dd);
02203     cuddRef(cube);
02204 
02205     for (i = n - 1; i >= 0; i--) {
02206         if (phase == NULL || phase[i] != 0) {
02207             fn = Cudd_bddAnd(dd,vars[i],cube);
02208         } else {
02209             fn = Cudd_bddAnd(dd,Cudd_Not(vars[i]),cube);
02210         }
02211         if (fn == NULL) {
02212             Cudd_RecursiveDeref(dd,cube);
02213             return(NULL);
02214         }
02215         cuddRef(fn);
02216         Cudd_RecursiveDeref(dd,cube);
02217         cube = fn;
02218     }
02219     cuddDeref(cube);
02220 
02221     return(cube);
02222 
02223 }  /* end of Cudd_bddComputeCube */

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

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

Synopsis [Computes f constrain c.]

Description [Computes f constrain c (f @ c). Uses a canonical form: (f' @ c) = ( f @ c)'. (Note: this is not true for c.) List of special cases:

  • f @ 0 = 0
  • f @ 1 = f
  • 0 @ c = 0
  • 1 @ c = 1
  • f @ f = 1
  • f @ f'= 0

Returns a pointer to the result if successful; NULL otherwise. Note that if F=(f1,...,fn) and reordering takes place while computing F @ c, then the image restriction property (Img(F,c) = Img(F @ c)) is lost.]

SideEffects [None]

SeeAlso [Cudd_bddRestrict Cudd_addConstrain]

Definition at line 176 of file cuddGenCof.c.

00180 {
00181     DdNode *res;
00182 
00183     do {
00184         dd->reordered = 0;
00185         res = cuddBddConstrainRecur(dd,f,c);
00186     } while (dd->reordered == 1);
00187     return(res);
00188 
00189 } /* end of Cudd_bddConstrain */

DdNode** Cudd_bddConstrainDecomp ( DdManager dd,
DdNode f 
)

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

Synopsis [BDD conjunctive decomposition as in McMillan's CAV96 paper.]

Description [BDD conjunctive decomposition as in McMillan's CAV96 paper. The decomposition is canonical only for a given variable order. If canonicity is required, variable ordering must be disabled after the decomposition has been computed. Returns an array with one entry for each BDD variable in the manager if successful; otherwise NULL. The components of the solution have their reference counts already incremented (unlike the results of most other functions in the package.]

SideEffects [None]

SeeAlso [Cudd_bddConstrain Cudd_bddExistAbstract]

Definition at line 367 of file cuddGenCof.c.

00370 {
00371     DdNode **decomp;
00372     int res;
00373     int i;
00374 
00375     /* Create an initialize decomposition array. */
00376     decomp = ALLOC(DdNode *,dd->size);
00377     if (decomp == NULL) {
00378         dd->errorCode = CUDD_MEMORY_OUT;
00379         return(NULL);
00380     }
00381     for (i = 0; i < dd->size; i++) {
00382         decomp[i] = NULL;
00383     }
00384     do {
00385         dd->reordered = 0;
00386         /* Clean up the decomposition array in case reordering took place. */
00387         for (i = 0; i < dd->size; i++) {
00388             if (decomp[i] != NULL) {
00389                 Cudd_IterDerefBdd(dd, decomp[i]);
00390                 decomp[i] = NULL;
00391             }
00392         }
00393         res = cuddBddConstrainDecomp(dd,f,decomp);
00394     } while (dd->reordered == 1);
00395     if (res == 0) {
00396         FREE(decomp);
00397         return(NULL);
00398     }
00399     /* Missing components are constant ones. */
00400     for (i = 0; i < dd->size; i++) {
00401         if (decomp[i] == NULL) {
00402             decomp[i] = DD_ONE(dd);
00403             cuddRef(decomp[i]);
00404         }
00405     }
00406     return(decomp);
00407 
00408 } /* end of Cudd_bddConstrainDecomp */

double Cudd_bddCorrelation ( DdManager manager,
DdNode f,
DdNode g 
)

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

Synopsis [Computes the correlation of f and g.]

Description [Computes the correlation of f and g. If f == g, their correlation is 1. If f == g', their correlation is 0. Returns the fraction of minterms in the ON-set of the EXNOR of f and g. If it runs out of memory, returns (double)CUDD_OUT_OF_MEM.]

SideEffects [None]

SeeAlso [Cudd_bddCorrelationWeights]

Definition at line 143 of file cuddBddCorr.c.

00147 {
00148 
00149     st_table    *table;
00150     double      correlation;
00151 
00152 #ifdef CORREL_STATS
00153     num_calls = 0;
00154 #endif
00155 
00156     table = st_init_table(CorrelCompare,CorrelHash);
00157     if (table == NULL) return((double)CUDD_OUT_OF_MEM);
00158     correlation = bddCorrelationAux(manager,f,g,table);
00159     st_foreach(table, CorrelCleanUp, NIL(char));
00160     st_free_table(table);
00161     return(correlation);
00162 
00163 } /* end of Cudd_bddCorrelation */

double Cudd_bddCorrelationWeights ( DdManager manager,
DdNode f,
DdNode g,
double *  prob 
)

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

Synopsis [Computes the correlation of f and g for given input probabilities.]

Description [Computes the correlation of f and g for given input probabilities. On input, prob\[i\] is supposed to contain the probability of the i-th input variable to be 1. If f == g, their correlation is 1. If f == g', their correlation is 0. Returns the probability that f and g have the same value. If it runs out of memory, returns (double)CUDD_OUT_OF_MEM. The correlation of f and the constant one gives the probability of f.]

SideEffects [None]

SeeAlso [Cudd_bddCorrelation]

Definition at line 185 of file cuddBddCorr.c.

00190 {
00191 
00192     st_table    *table;
00193     double      correlation;
00194 
00195 #ifdef CORREL_STATS
00196     num_calls = 0;
00197 #endif
00198 
00199     table = st_init_table(CorrelCompare,CorrelHash);
00200     if (table == NULL) return((double)CUDD_OUT_OF_MEM);
00201     correlation = bddCorrelationWeightsAux(manager,f,g,prob,table);
00202     st_foreach(table, CorrelCleanUp, NIL(char));
00203     st_free_table(table);
00204     return(correlation);
00205 
00206 } /* end of Cudd_bddCorrelationWeights */

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

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

Synopsis [Existentially abstracts all the variables in cube from f.]

Description [Existentially abstracts all the variables in cube from f. Returns the abstracted BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddUnivAbstract Cudd_addExistAbstract]

Definition at line 126 of file cuddBddAbs.c.

00130 {
00131     DdNode *res;
00132 
00133     if (bddCheckPositiveCube(manager, cube) == 0) {
00134         (void) fprintf(manager->err,
00135                        "Error: Can only abstract positive cubes\n");
00136         manager->errorCode = CUDD_INVALID_ARG;
00137         return(NULL);
00138     }
00139 
00140     do {
00141         manager->reordered = 0;
00142         res = cuddBddExistAbstractRecur(manager, f, cube);
00143     } while (manager->reordered == 1);
00144 
00145     return(res);
00146 
00147 } /* end of Cudd_bddExistAbstract */

int Cudd_bddGenConjDecomp ( DdManager dd,
DdNode f,
DdNode ***  conjuncts 
)

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

Synopsis [Performs two-way conjunctive decomposition of a BDD.]

Description [Performs two-way conjunctive decomposition of a BDD. This procedure owes its name to the fact tht it generalizes the decomposition based on the cofactors with respect to one variable. Returns the number of conjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise. The conjuncts produced by this procedure tend to be balanced.]

SideEffects [The two factors are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the conjuncts are already referenced. If the function returns 0, the array for the conjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]

SeeAlso [Cudd_bddGenDisjDecomp Cudd_bddApproxConjDecomp Cudd_bddIterConjDecomp Cudd_bddVarConjDecomp]

Definition at line 492 of file cuddDecomp.c.

00496 {
00497     int result;
00498     DdNode *glocal, *hlocal;
00499 
00500     one = DD_ONE(dd);
00501     zero = Cudd_Not(one);
00502     
00503     do {
00504         dd->reordered = 0;
00505         result = cuddConjunctsAux(dd, f, &glocal, &hlocal);
00506     } while (dd->reordered == 1);
00507 
00508     if (result == 0) {
00509         return(0);
00510     }
00511 
00512     if (glocal != one) {
00513         if (hlocal != one) {
00514             *conjuncts = ALLOC(DdNode *,2);
00515             if (*conjuncts == NULL) {
00516                 Cudd_RecursiveDeref(dd,glocal);
00517                 Cudd_RecursiveDeref(dd,hlocal);
00518                 dd->errorCode = CUDD_MEMORY_OUT;
00519                 return(0);
00520             }
00521             (*conjuncts)[0] = glocal;
00522             (*conjuncts)[1] = hlocal;
00523             return(2);
00524         } else {
00525             Cudd_RecursiveDeref(dd,hlocal);
00526             *conjuncts = ALLOC(DdNode *,1);
00527             if (*conjuncts == NULL) {
00528                 Cudd_RecursiveDeref(dd,glocal);
00529                 dd->errorCode = CUDD_MEMORY_OUT;
00530                 return(0);
00531             }
00532             (*conjuncts)[0] = glocal;
00533             return(1);
00534         }
00535     } else {
00536         Cudd_RecursiveDeref(dd,glocal);
00537         *conjuncts = ALLOC(DdNode *,1);
00538         if (*conjuncts == NULL) {
00539             Cudd_RecursiveDeref(dd,hlocal);
00540             dd->errorCode = CUDD_MEMORY_OUT;
00541             return(0);
00542         }
00543         (*conjuncts)[0] = hlocal;
00544         return(1);
00545     }
00546 
00547 } /* end of Cudd_bddGenConjDecomp */

int Cudd_bddGenDisjDecomp ( DdManager dd,
DdNode f,
DdNode ***  disjuncts 
)

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

Synopsis [Performs two-way disjunctive decomposition of a BDD.]

Description [Performs two-way disjunctive decomposition of a BDD. Returns the number of disjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise. The disjuncts produced by this procedure tend to be balanced.]

SideEffects [The two disjuncts are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the disjuncts are already referenced. If the function returns 0, the array for the disjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]

SeeAlso [Cudd_bddGenConjDecomp Cudd_bddApproxDisjDecomp Cudd_bddIterDisjDecomp Cudd_bddVarDisjDecomp]

Definition at line 571 of file cuddDecomp.c.

00575 {
00576     int result, i;
00577 
00578     result = Cudd_bddGenConjDecomp(dd,Cudd_Not(f),disjuncts);
00579     for (i = 0; i < result; i++) {
00580         (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]);
00581     }
00582     return(result);
00583 
00584 } /* end of Cudd_bddGenDisjDecomp */

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

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

Synopsis [Returns a function included in the intersection of f and g.]

Description [Computes a function included in the intersection of f and g. (That is, a witness that the intersection is not empty.) Cudd_bddIntersect tries to build as few new nodes as possible. If the only result of interest is whether f and g intersect, Cudd_bddLeq should be used instead.]

SideEffects [None]

SeeAlso [Cudd_bddLeq Cudd_bddIteConstant]

Definition at line 278 of file cuddBddIte.c.

00282 {
00283     DdNode *res;
00284 
00285     do {
00286         dd->reordered = 0;
00287         res = cuddBddIntersectRecur(dd,f,g);
00288     } while (dd->reordered == 1);
00289 
00290     return(res);
00291 
00292 } /* end of Cudd_bddIntersect */

DdNode* Cudd_bddInterval ( DdManager dd,
int  N,
DdNode **  x,
unsigned int  lowerB,
unsigned int  upperB 
)

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

Synopsis [Generates a BDD for the function lowerB x upperB.]

Description [This function generates a BDD for the function lowerB x upperB, where x is an N-bit number, x\[0\] x\[1\] ... x\[N-1\], with 0 the most significant bit (important!). The number of variables N should be sufficient to represent the bounds; otherwise, the bounds are truncated to their N least significant bits. Two BDDs are built bottom-up for lowerB x and x upperB, and they are finally conjoined.]

SideEffects [None]

SeeAlso [Cudd_Xgty]

Definition at line 1117 of file cuddPriority.c.

01123 {
01124     DdNode *one, *zero;
01125     DdNode *r, *rl, *ru;
01126     int     i;
01127 
01128     one = DD_ONE(dd);
01129     zero = Cudd_Not(one);
01130 
01131     rl = one;
01132     cuddRef(rl);
01133     ru = one;
01134     cuddRef(ru);
01135 
01136     /* Loop to build the rest of the BDDs. */
01137     for (i = N-1; i >= 0; i--) {
01138         DdNode *vl, *vu;
01139         vl = Cudd_bddIte(dd, x[i],
01140                          lowerB&1 ? rl : one,
01141                          lowerB&1 ? zero : rl);
01142         if (vl == NULL) {
01143             Cudd_IterDerefBdd(dd, rl);
01144             Cudd_IterDerefBdd(dd, ru);
01145             return(NULL);
01146         }
01147         cuddRef(vl);
01148         Cudd_IterDerefBdd(dd, rl);
01149         rl = vl;
01150         lowerB >>= 1;
01151         vu = Cudd_bddIte(dd, x[i],
01152                          upperB&1 ? ru : zero,
01153                          upperB&1 ? one : ru);
01154         if (vu == NULL) {
01155             Cudd_IterDerefBdd(dd, rl);
01156             Cudd_IterDerefBdd(dd, ru);
01157             return(NULL);
01158         }
01159         cuddRef(vu);
01160         Cudd_IterDerefBdd(dd, ru);
01161         ru = vu;
01162         upperB >>= 1;
01163     }
01164 
01165     /* Conjoin the two bounds. */
01166     r = Cudd_bddAnd(dd, rl, ru);
01167     if (r == NULL) {
01168         Cudd_IterDerefBdd(dd, rl);
01169         Cudd_IterDerefBdd(dd, ru);
01170         return(NULL);
01171     }
01172     cuddRef(r);
01173     Cudd_IterDerefBdd(dd, rl);
01174     Cudd_IterDerefBdd(dd, ru);
01175     cuddDeref(r);
01176     return(r);
01177 
01178 } /* end of Cudd_bddInterval */

int Cudd_bddIsNsVar ( DdManager dd,
int  index 
)

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

Synopsis [Checks whether a variable is next state.]

Description [Checks whether a variable is next state. Returns 1 if the variable's type is present state; 0 if the variable exists but is not a present state; -1 if the variable does not exist.]

SideEffects [none]

SeeAlso [Cudd_bddSetNsVar Cudd_bddIsPiVar Cudd_bddIsPsVar]

Definition at line 4095 of file cuddAPI.c.

04098 {
04099     if (index >= dd->size || index < 0) return -1;
04100     return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_NEXT_STATE);
04101 
04102 } /* end of Cudd_bddIsNsVar */

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

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

Synopsis [Computes a BDD in the interval between L and U with a simple sum-of-produuct cover.]

Description [Computes a BDD in the interval between L and U with a simple sum-of-produuct cover. This procedure is similar to Cudd_zddIsop, but it does not return the ZDD for the cover. Returns a pointer to the BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_zddIsop]

Definition at line 170 of file cuddZddIsop.c.

00174 {
00175     DdNode      *res;
00176 
00177     do {
00178         dd->reordered = 0;
00179         res = cuddBddIsop(dd, L, U);
00180     } while (dd->reordered == 1);
00181     return(res);
00182 
00183 } /* end of Cudd_bddIsop */

int Cudd_bddIsPiVar ( DdManager dd,
int  index 
)

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

Synopsis [Checks whether a variable is primary input.]

Description [Checks whether a variable is primary input. Returns 1 if the variable's type is primary input; 0 if the variable exists but is not a primary input; -1 if the variable does not exist.]

SideEffects [none]

SeeAlso [Cudd_bddSetPiVar Cudd_bddIsPsVar Cudd_bddIsNsVar]

Definition at line 4047 of file cuddAPI.c.

04050 {
04051     if (index >= dd->size || index < 0) return -1;
04052     return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRIMARY_INPUT);
04053 
04054 } /* end of Cudd_bddIsPiVar */

int Cudd_bddIsPsVar ( DdManager dd,
int  index 
)

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

Synopsis [Checks whether a variable is present state.]

Description [Checks whether a variable is present state. Returns 1 if the variable's type is present state; 0 if the variable exists but is not a present state; -1 if the variable does not exist.]

SideEffects [none]

SeeAlso [Cudd_bddSetPsVar Cudd_bddIsPiVar Cudd_bddIsNsVar]

Definition at line 4071 of file cuddAPI.c.

04074 {
04075     if (index >= dd->size || index < 0) return -1;
04076     return (dd->subtables[dd->perm[index]].varType == CUDD_VAR_PRESENT_STATE);
04077 
04078 } /* end of Cudd_bddIsPsVar */

int Cudd_bddIsVarEssential ( DdManager manager,
DdNode f,
int  id,
int  phase 
)

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

Synopsis [Determines whether a given variable is essential with a given phase in a BDD.]

Description [Determines whether a given variable is essential with a given phase in a BDD. Uses Cudd_bddIteConstant. Returns 1 if phase == 1 and f-->x_id, or if phase == 0 and f-->x_id'.]

SideEffects [None]

SeeAlso [Cudd_FindEssential]

Definition at line 235 of file cuddEssent.c.

00240 {
00241     DdNode      *var;
00242     int         res;
00243 
00244     var = Cudd_bddIthVar(manager, id);
00245 
00246     var = Cudd_NotCond(var,phase == 0);
00247 
00248     res = Cudd_bddLeq(manager, f, var);
00249 
00250     return(res);
00251 
00252 } /* end of Cudd_bddIsVarEssential */

int Cudd_bddIsVarHardGroup ( DdManager dd,
int  index 
)

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

Synopsis [Checks whether a variable is set to be in a hard group.]

Description [Checks whether a variable is set to be in a hard group. This function is used for lazy sifting. Returns 1 if the variable is marked to be in a hard group; 0 if the variable exists, but it is not marked to be in a hard group; -1 if the variable does not exist.]

SideEffects [none]

SeeAlso [Cudd_bddSetVarHardGroup]

Definition at line 4323 of file cuddAPI.c.

04326 {
04327     if (index >= dd->size || index < 0) return(-1);
04328     if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_HARD_GROUP)
04329         return(1);
04330     return(0);
04331 
04332 } /* end of Cudd_bddIsVarToBeGrouped */

int Cudd_bddIsVarToBeGrouped ( DdManager dd,
int  index 
)

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

Synopsis [Checks whether a variable is set to be grouped.]

Description [Checks whether a variable is set to be grouped. This function is used for lazy sifting.]

SideEffects [none]

SeeAlso []

Definition at line 4246 of file cuddAPI.c.

04249 {
04250     if (index >= dd->size || index < 0) return(-1);
04251     if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP)
04252         return(0);
04253     else
04254         return(dd->subtables[dd->perm[index]].varToBeGrouped);
04255 
04256 } /* end of Cudd_bddIsVarToBeGrouped */

int Cudd_bddIsVarToBeUngrouped ( DdManager dd,
int  index 
)

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

Synopsis [Checks whether a variable is set to be ungrouped.]

Description [Checks whether a variable is set to be ungrouped. This function is used for lazy sifting. Returns 1 if the variable is marked to be ungrouped; 0 if the variable exists, but it is not marked to be ungrouped; -1 if the variable does not exist.]

SideEffects [none]

SeeAlso [Cudd_bddSetVarToBeUngrouped]

Definition at line 4298 of file cuddAPI.c.

04301 {
04302     if (index >= dd->size || index < 0) return(-1);
04303     return dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP;
04304 
04305 } /* end of Cudd_bddIsVarToBeGrouped */

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

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

Synopsis [Implements ITE(f,g,h).]

Description [Implements ITE(f,g,h). Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_addIte Cudd_bddIteConstant Cudd_bddIntersect]

Definition at line 139 of file cuddBddIte.c.

00144 {
00145     DdNode *res;
00146 
00147     do {
00148         dd->reordered = 0;
00149         res = cuddBddIteRecur(dd,f,g,h);
00150     } while (dd->reordered == 1);
00151     return(res);
00152 
00153 } /* end of Cudd_bddIte */

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

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

Synopsis [Implements ITEconstant(f,g,h).]

Description [Implements ITEconstant(f,g,h). Returns a pointer to the resulting BDD (which may or may not be constant) or DD_NON_CONSTANT. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_bddIntersect Cudd_bddLeq Cudd_addIteConstant]

Definition at line 170 of file cuddBddIte.c.

00175 {
00176     DdNode       *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
00177     DdNode       *one = DD_ONE(dd);
00178     DdNode       *zero = Cudd_Not(one);
00179     int          comple;
00180     unsigned int topf, topg, toph, v;
00181 
00182     statLine(dd);
00183     /* Trivial cases. */
00184     if (f == one)                       /* ITE(1,G,H) => G */
00185         return(g);
00186     
00187     if (f == zero)                      /* ITE(0,G,H) => H */
00188         return(h);
00189     
00190     /* f now not a constant. */
00191     bddVarToConst(f, &g, &h, one);      /* possibly convert g or h */
00192                                         /* to constants */
00193 
00194     if (g == h)                         /* ITE(F,G,G) => G */
00195         return(g);
00196 
00197     if (Cudd_IsConstant(g) && Cudd_IsConstant(h)) 
00198         return(DD_NON_CONSTANT);        /* ITE(F,1,0) or ITE(F,0,1) */
00199                                         /* => DD_NON_CONSTANT */
00200     
00201     if (g == Cudd_Not(h))
00202         return(DD_NON_CONSTANT);        /* ITE(F,G,G') => DD_NON_CONSTANT */
00203                                         /* if F != G and F != G' */
00204     
00205     comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph);
00206 
00207     /* Cache lookup. */
00208     r = cuddConstantLookup(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h);
00209     if (r != NULL) {
00210         return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT));
00211     }
00212 
00213     v = ddMin(topg, toph);
00214 
00215     /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */
00216     if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
00217         return(DD_NON_CONSTANT);
00218     }
00219 
00220     /* Compute cofactors. */
00221     if (topf <= v) {
00222         v = ddMin(topf, v);             /* v = top_var(F,G,H) */
00223         Fv = cuddT(f); Fnv = cuddE(f);
00224     } else {
00225         Fv = Fnv = f;
00226     }
00227 
00228     if (topg == v) {
00229         Gv = cuddT(g); Gnv = cuddE(g);
00230     } else {
00231         Gv = Gnv = g;
00232     }
00233 
00234     if (toph == v) {
00235         H = Cudd_Regular(h);
00236         Hv = cuddT(H); Hnv = cuddE(H);
00237         if (Cudd_IsComplement(h)) {
00238             Hv = Cudd_Not(Hv);
00239             Hnv = Cudd_Not(Hnv);
00240         }
00241     } else {
00242         Hv = Hnv = h;
00243     }
00244 
00245     /* Recursion. */
00246     t = Cudd_bddIteConstant(dd, Fv, Gv, Hv);
00247     if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) {
00248         cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT);
00249         return(DD_NON_CONSTANT);
00250     }
00251     e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv);
00252     if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) {
00253         cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT);
00254         return(DD_NON_CONSTANT);
00255     }
00256     cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t);
00257     return(Cudd_NotCond(t,comple));
00258 
00259 } /* end of Cudd_bddIteConstant */

int Cudd_bddIterConjDecomp ( DdManager dd,
DdNode f,
DdNode ***  conjuncts 
)

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

Synopsis [Performs two-way conjunctive decomposition of a BDD.]

Description [Performs two-way conjunctive decomposition of a BDD. This procedure owes its name to the iterated use of supersetting to obtain a factor of the given function. Returns the number of conjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise. The conjuncts produced by this procedure tend to be imbalanced.]

SideEffects [The factors are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the conjuncts are already referenced. If the function returns 0, the array for the conjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]

SeeAlso [Cudd_bddIterDisjDecomp Cudd_bddApproxConjDecomp Cudd_bddGenConjDecomp Cudd_bddVarConjDecomp Cudd_RemapOverApprox Cudd_bddSqueeze Cudd_bddLICompaction]

Definition at line 309 of file cuddDecomp.c.

00313 {
00314     DdNode *superset1, *superset2, *old[2], *res[2];
00315     int sizeOld, sizeNew;
00316     int nvars = Cudd_SupportSize(dd,f);
00317 
00318     old[0] = DD_ONE(dd);
00319     cuddRef(old[0]);
00320     old[1] = f;
00321     cuddRef(old[1]);
00322     sizeOld = Cudd_SharingSize(old,2);
00323 
00324     do {
00325         /* Find a tentative first factor by overapproximation and
00326         ** minimization. */
00327         superset1 = Cudd_RemapOverApprox(dd,old[1],nvars,0,1.0);
00328         if (superset1 == NULL) {
00329             Cudd_RecursiveDeref(dd,old[0]);
00330             Cudd_RecursiveDeref(dd,old[1]);
00331             return(0);
00332         }
00333         cuddRef(superset1);
00334         superset2 = Cudd_bddSqueeze(dd,old[1],superset1);
00335         if (superset2 == NULL) {
00336             Cudd_RecursiveDeref(dd,old[0]);
00337             Cudd_RecursiveDeref(dd,old[1]);
00338             Cudd_RecursiveDeref(dd,superset1);
00339             return(0);
00340         }
00341         cuddRef(superset2);
00342         Cudd_RecursiveDeref(dd,superset1);
00343         res[0] = Cudd_bddAnd(dd,old[0],superset2);
00344         if (res[0] == NULL) {
00345             Cudd_RecursiveDeref(dd,superset2);
00346             Cudd_RecursiveDeref(dd,old[0]);
00347             Cudd_RecursiveDeref(dd,old[1]);
00348             return(0);
00349         }
00350         cuddRef(res[0]);
00351         Cudd_RecursiveDeref(dd,superset2);
00352         if (res[0] == old[0]) {
00353             Cudd_RecursiveDeref(dd,res[0]);
00354             break;      /* avoid infinite loop */
00355         }
00356 
00357         /* Compute the second factor by minimization. */
00358         res[1] = Cudd_bddLICompaction(dd,old[1],res[0]);
00359         if (res[1] == NULL) {
00360             Cudd_RecursiveDeref(dd,old[0]);
00361             Cudd_RecursiveDeref(dd,old[1]);
00362             return(0);
00363         }
00364         cuddRef(res[1]);
00365 
00366         sizeNew = Cudd_SharingSize(res,2);
00367         if (sizeNew <= sizeOld) {
00368             Cudd_RecursiveDeref(dd,old[0]);
00369             old[0] = res[0];
00370             Cudd_RecursiveDeref(dd,old[1]);
00371             old[1] = res[1];
00372             sizeOld = sizeNew;
00373         } else {
00374             Cudd_RecursiveDeref(dd,res[0]);
00375             Cudd_RecursiveDeref(dd,res[1]);
00376             break;
00377         }
00378 
00379     } while (1);
00380 
00381     /* Refine the first factor by minimization. If h turns out to
00382     ** be f, this step guarantees that g will be 1. */
00383     superset1 = Cudd_bddLICompaction(dd,old[0],old[1]);
00384     if (superset1 == NULL) {
00385         Cudd_RecursiveDeref(dd,old[0]);
00386         Cudd_RecursiveDeref(dd,old[1]);
00387         return(0);
00388     }
00389     cuddRef(superset1);
00390     Cudd_RecursiveDeref(dd,old[0]);
00391     old[0] = superset1;
00392 
00393     if (old[0] != DD_ONE(dd)) {
00394         if (old[1] != DD_ONE(dd)) {
00395             *conjuncts = ALLOC(DdNode *,2);
00396             if (*conjuncts == NULL) {
00397                 Cudd_RecursiveDeref(dd,old[0]);
00398                 Cudd_RecursiveDeref(dd,old[1]);
00399                 dd->errorCode = CUDD_MEMORY_OUT;
00400                 return(0);
00401             }
00402             (*conjuncts)[0] = old[0];
00403             (*conjuncts)[1] = old[1];
00404             return(2);
00405         } else {
00406             Cudd_RecursiveDeref(dd,old[1]);
00407             *conjuncts = ALLOC(DdNode *,1);
00408             if (*conjuncts == NULL) {
00409                 Cudd_RecursiveDeref(dd,old[0]);
00410                 dd->errorCode = CUDD_MEMORY_OUT;
00411                 return(0);
00412             }
00413             (*conjuncts)[0] = old[0];
00414             return(1);
00415         }
00416     } else {
00417         Cudd_RecursiveDeref(dd,old[0]);
00418         *conjuncts = ALLOC(DdNode *,1);
00419         if (*conjuncts == NULL) {
00420             Cudd_RecursiveDeref(dd,old[1]);
00421             dd->errorCode = CUDD_MEMORY_OUT;
00422             return(0);
00423         }
00424         (*conjuncts)[0] = old[1];
00425         return(1);
00426     }
00427 
00428 } /* end of Cudd_bddIterConjDecomp */

int Cudd_bddIterDisjDecomp ( DdManager dd,
DdNode f,
DdNode ***  disjuncts 
)

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

Synopsis [Performs two-way disjunctive decomposition of a BDD.]

Description [Performs two-way disjunctive decomposition of a BDD. Returns the number of disjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise. The disjuncts produced by this procedure tend to be imbalanced.]

SideEffects [The two disjuncts are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the disjuncts are already referenced. If the function returns 0, the array for the disjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]

SeeAlso [Cudd_bddIterConjDecomp Cudd_bddApproxDisjDecomp Cudd_bddGenDisjDecomp Cudd_bddVarDisjDecomp]

Definition at line 452 of file cuddDecomp.c.

00456 {
00457     int result, i;
00458 
00459     result = Cudd_bddIterConjDecomp(dd,Cudd_Not(f),disjuncts);
00460     for (i = 0; i < result; i++) {
00461         (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]);
00462     }
00463     return(result);
00464 
00465 } /* end of Cudd_bddIterDisjDecomp */

DdNode* Cudd_bddIthVar ( DdManager dd,
int  i 
)

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

Synopsis [Returns the BDD variable with index i.]

Description [Retrieves the BDD variable with index i if it already exists, or creates a new BDD variable. Returns a pointer to the variable if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel Cudd_ReadVars]

Definition at line 412 of file cuddAPI.c.

00415 {
00416     DdNode *res;
00417 
00418     if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL);
00419     if (i < dd->size) {
00420         res = dd->vars[i];
00421     } else {
00422         res = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one));
00423     }
00424 
00425     return(res);
00426 
00427 } /* end of Cudd_bddIthVar */

int Cudd_bddLeq ( DdManager dd,
DdNode f,
DdNode g 
)

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

Synopsis [Determines whether f is less than or equal to g.]

Description [Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_bddIteConstant Cudd_addEvalConst]

Definition at line 532 of file cuddBddIte.c.

00536 {
00537     DdNode *one, *zero, *tmp, *F, *fv, *fvn, *gv, *gvn;
00538     unsigned int topf, topg, res;
00539 
00540     statLine(dd);
00541     /* Terminal cases and normalization. */
00542     if (f == g) return(1);
00543 
00544     if (Cudd_IsComplement(g)) {
00545         /* Special case: if f is regular and g is complemented,
00546         ** f(1,...,1) = 1 > 0 = g(1,...,1).
00547         */
00548         if (!Cudd_IsComplement(f)) return(0);
00549         /* Both are complemented: Swap and complement because
00550         ** f <= g <=> g' <= f' and we want the second argument to be regular.
00551         */
00552         tmp = g;
00553         g = Cudd_Not(f);
00554         f = Cudd_Not(tmp);
00555     } else if (Cudd_IsComplement(f) && g < f) {
00556         tmp = g;
00557         g = Cudd_Not(f);
00558         f = Cudd_Not(tmp);
00559     }
00560 
00561     /* Now g is regular and, if f is not regular, f < g. */
00562     one = DD_ONE(dd);
00563     if (g == one) return(1);    /* no need to test against zero */
00564     if (f == one) return(0);    /* since at this point g != one */
00565     if (Cudd_Not(f) == g) return(0); /* because neither is constant */
00566     zero = Cudd_Not(one);
00567     if (f == zero) return(1);
00568 
00569     /* Here neither f nor g is constant. */
00570 
00571     /* Check cache. */
00572     tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g);
00573     if (tmp != NULL) {
00574         return(tmp == one);
00575     }
00576 
00577     /* Compute cofactors. */
00578     F = Cudd_Regular(f);
00579     topf = dd->perm[F->index];
00580     topg = dd->perm[g->index];
00581     if (topf <= topg) {
00582         fv = cuddT(F); fvn = cuddE(F);
00583         if (f != F) {
00584             fv = Cudd_Not(fv);
00585             fvn = Cudd_Not(fvn);
00586         }
00587     } else {
00588         fv = fvn = f;
00589     }
00590     if (topg <= topf) {
00591         gv = cuddT(g); gvn = cuddE(g);
00592     } else {
00593         gv = gvn = g;
00594     }
00595 
00596     /* Recursive calls. Since we want to maximize the probability of
00597     ** the special case f(1,...,1) > g(1,...,1), we consider the negative
00598     ** cofactors first. Indeed, the complementation parity of the positive
00599     ** cofactors is the same as the one of the parent functions.
00600     */
00601     res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv);
00602 
00603     /* Store result in cache and return. */
00604     cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero));
00605     return(res);
00606 
00607 } /* end of Cudd_bddLeq */

int Cudd_bddLeqUnless ( DdManager dd,
DdNode f,
DdNode g,
DdNode D 
)

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

Synopsis [Tells whether f is less than of equal to G unless D is 1.]

Description [Tells whether f is less than of equal to G unless D is 1. f, g, and D are BDDs. The function returns 1 if f is less than of equal to G, and 0 otherwise. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_EquivDC Cudd_bddLeq Cudd_bddIteConstant]

Definition at line 618 of file cuddSat.c.

00623 {
00624     DdNode *tmp, *One, *F, *G;
00625     DdNode *Ft, *Fe, *Gt, *Ge, *Dt, *De;
00626     int res;
00627     unsigned int flevel, glevel, dlevel, top;
00628 
00629     statLine(dd);
00630 
00631     One = DD_ONE(dd);
00632 
00633     /* Check terminal cases. */
00634     if (f == g || g == One || f == Cudd_Not(One) || D == One ||
00635         D == f || D == Cudd_Not(g)) return(1);
00636     /* Check for two-operand cases. */
00637     if (D == Cudd_Not(One) || D == g || D == Cudd_Not(f))
00638         return(Cudd_bddLeq(dd,f,g));
00639     if (g == Cudd_Not(One) || g == Cudd_Not(f)) return(Cudd_bddLeq(dd,f,D));
00640     if (f == One) return(Cudd_bddLeq(dd,Cudd_Not(g),D));
00641 
00642     /* From now on, f, g, and D are non-constant, distinct, and
00643     ** non-complementary. */
00644 
00645     /* Normalize call to increase cache efficiency.  We rely on the
00646     ** fact that f <= g unless D is equivalent to not(g) <= not(f)
00647     ** unless D and to f <= D unless g.  We make sure that D is
00648     ** regular, and that at most one of f and g is complemented.  We also
00649     ** ensure that when two operands can be swapped, the one with the
00650     ** lowest address comes first. */
00651 
00652     if (Cudd_IsComplement(D)) {
00653         if (Cudd_IsComplement(g)) {
00654             /* Special case: if f is regular and g is complemented,
00655             ** f(1,...,1) = 1 > 0 = g(1,...,1).  If D(1,...,1) = 0, return 0.
00656             */
00657             if (!Cudd_IsComplement(f)) return(0);
00658             /* !g <= D unless !f  or  !D <= g unless !f */
00659             tmp = D;
00660             D = Cudd_Not(f);
00661             if (g < tmp) {
00662                 f = Cudd_Not(g);
00663                 g = tmp;
00664             } else {
00665                 f = Cudd_Not(tmp);
00666             }
00667         } else {
00668             if (Cudd_IsComplement(f)) {
00669                 /* !D <= !f unless g  or  !D <= g unless !f */
00670                 tmp = f;
00671                 f = Cudd_Not(D);
00672                 if (tmp < g) {
00673                     D = g;
00674                     g = Cudd_Not(tmp);
00675                 } else {
00676                     D = Cudd_Not(tmp);
00677                 }
00678             } else {
00679                 /* f <= D unless g  or  !D <= !f unless g */
00680                 tmp = D;
00681                 D = g;
00682                 if (tmp < f) {
00683                     g = Cudd_Not(f);
00684                     f = Cudd_Not(tmp);
00685                 } else {
00686                     g = tmp;
00687                 }
00688             }
00689         }
00690     } else {
00691         if (Cudd_IsComplement(g)) {
00692             if (Cudd_IsComplement(f)) {
00693                 /* !g <= !f unless D  or  !g <= D unless !f */
00694                 tmp = f;
00695                 f = Cudd_Not(g);
00696                 if (D < tmp) {
00697                     g = D;
00698                     D = Cudd_Not(tmp);
00699                 } else {
00700                     g = Cudd_Not(tmp);
00701                 }
00702             } else {
00703                 /* f <= g unless D  or  !g <= !f unless D */
00704                 if (g < f) {
00705                     tmp = g;
00706                     g = Cudd_Not(f);
00707                     f = Cudd_Not(tmp);
00708                 }
00709             }
00710         } else {
00711             /* f <= g unless D  or  f <= D unless g */
00712             if (D < g) {
00713                 tmp = D;
00714                 D = g;
00715                 g = tmp;
00716             }
00717         }
00718     }
00719 
00720     /* From now on, D is regular. */
00721 
00722     /* Check cache. */
00723     tmp = cuddCacheLookup(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D);
00724     if (tmp != NULL) return(tmp == One);
00725 
00726     /* Find splitting variable. */
00727     F = Cudd_Regular(f);
00728     flevel = dd->perm[F->index];
00729     G = Cudd_Regular(g);
00730     glevel = dd->perm[G->index];
00731     top = ddMin(flevel,glevel);
00732     dlevel = dd->perm[D->index];
00733     top = ddMin(top,dlevel);
00734 
00735     /* Compute cofactors. */
00736     if (top == flevel) {
00737         Ft = cuddT(F);
00738         Fe = cuddE(F);
00739         if (F != f) {
00740             Ft = Cudd_Not(Ft);
00741             Fe = Cudd_Not(Fe);
00742         }
00743     } else {
00744         Ft = Fe = f;
00745     }
00746     if (top == glevel) {
00747         Gt = cuddT(G);
00748         Ge = cuddE(G);
00749         if (G != g) {
00750             Gt = Cudd_Not(Gt);
00751             Ge = Cudd_Not(Ge);
00752         }
00753     } else {
00754         Gt = Ge = g;
00755     }
00756     if (top == dlevel) {
00757         Dt = cuddT(D);
00758         De = cuddE(D);
00759     } else {
00760         Dt = De = D;
00761     }
00762 
00763     /* Solve recursively. */
00764     res = Cudd_bddLeqUnless(dd,Ft,Gt,Dt);
00765     if (res != 0) {
00766         res = Cudd_bddLeqUnless(dd,Fe,Ge,De);
00767     }
00768     cuddCacheInsert(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D,Cudd_NotCond(One,!res));
00769 
00770     return(res);
00771 
00772 } /* end of Cudd_bddLeqUnless */

DdNode* Cudd_bddLICompaction ( 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_bddRestrict]

Definition at line 566 of file cuddGenCof.c.

00570 {
00571     DdNode *res;
00572 
00573     do {
00574         dd->reordered = 0;
00575         res = cuddBddLICompaction(dd,f,c);
00576     } while (dd->reordered == 1);
00577     return(res);
00578 
00579 } /* end of Cudd_bddLICompaction */

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

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

Synopsis [Computes the intesection of two sets of literals represented as BDDs.]

Description [Computes the intesection of two sets of literals represented as BDDs. Each set is represented as a cube of the literals in the set. The empty set is represented by the constant 1. No variable can be simultaneously present in both phases in a set. Returns a pointer to the BDD representing the intersected sets, if successful; NULL otherwise.]

SideEffects [None]

Definition at line 114 of file cuddLiteral.c.

00118 {
00119     DdNode *res;
00120 
00121     do {
00122         dd->reordered = 0;
00123         res = cuddBddLiteralSetIntersectionRecur(dd,f,g);
00124     } while (dd->reordered == 1);
00125     return(res);
00126 
00127 } /* end of Cudd_bddLiteralSetIntersection */

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

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

Synopsis [Expands cube to a prime implicant of f.]

Description [Expands cube to a prime implicant of f. Returns the prime if successful; NULL otherwise. In particular, NULL is returned if cube is not a real cube or is not an implicant of f.]

SideEffects [None]

SeeAlso []

Definition at line 860 of file cuddSat.c.

00864 {
00865     DdNode *res;
00866 
00867     if (!Cudd_bddLeq(dd,cube,f)) return(NULL);
00868 
00869     do {
00870         dd->reordered = 0;
00871         res = cuddBddMakePrime(dd,cube,f);
00872     } while (dd->reordered == 1);
00873     return(res);
00874 
00875 } /* end of Cudd_bddMakePrime */

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

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

Synopsis [Finds a small BDD that agrees with f over c.]

Description [Finds a small BDD that agrees with f over c. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction Cudd_bddSqueeze]

Definition at line 649 of file cuddGenCof.c.

00653 {
00654     DdNode *cplus, *res;
00655 
00656     if (c == Cudd_Not(DD_ONE(dd))) return(c);
00657     if (Cudd_IsConstant(f)) return(f);
00658     if (f == c) return(DD_ONE(dd));
00659     if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd)));
00660 
00661     cplus = Cudd_RemapOverApprox(dd,c,0,0,1.0);
00662     if (cplus == NULL) return(NULL);
00663     cuddRef(cplus);
00664     res = Cudd_bddLICompaction(dd,f,cplus);
00665     if (res == NULL) {
00666         Cudd_IterDerefBdd(dd,cplus);
00667         return(NULL);
00668     }
00669     cuddRef(res);
00670     Cudd_IterDerefBdd(dd,cplus);
00671     cuddDeref(res);
00672     return(res);
00673 
00674 } /* end of Cudd_bddMinimize */

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

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

Synopsis [Computes the NAND of two BDDs f and g.]

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

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNor Cudd_bddXor Cudd_bddXnor]

Definition at line 409 of file cuddBddIte.c.

00413 {
00414     DdNode *res;
00415 
00416     do {
00417         dd->reordered = 0;
00418         res = cuddBddAndRecur(dd,f,g);
00419     } while (dd->reordered == 1);
00420     res = Cudd_NotCond(res,res != NULL);
00421     return(res);
00422 
00423 } /* end of Cudd_bddNand */

DdNode* Cudd_bddNewVar ( DdManager dd  ) 

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

Synopsis [Returns a new BDD variable.]

Description [Creates a new BDD variable. The new variable has an index equal to the largest previous index plus 1. Returns a pointer to the new variable if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel]

Definition at line 319 of file cuddAPI.c.

00321 {
00322     DdNode *res;
00323 
00324     if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL);
00325     res = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one));
00326 
00327     return(res);
00328 
00329 } /* end of Cudd_bddNewVar */

DdNode* Cudd_bddNewVarAtLevel ( DdManager dd,
int  level 
)

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

Synopsis [Returns a new BDD variable at a specified level.]

Description [Creates a new BDD variable. The new variable has an index equal to the largest previous index plus 1 and is positioned at the specified level in the order. Returns a pointer to the new variable if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddNewVar Cudd_bddIthVar Cudd_addNewVarAtLevel]

Definition at line 347 of file cuddAPI.c.

00350 {
00351     DdNode *res;
00352 
00353     if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL);
00354     if (level >= dd->size) return(Cudd_bddIthVar(dd,level));
00355     if (!cuddInsertSubtables(dd,1,level)) return(NULL);
00356     res = dd->vars[dd->size - 1];
00357 
00358     return(res);
00359 
00360 } /* end of Cudd_bddNewVarAtLevel */

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

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

Synopsis [Computes the NOR of two BDDs f and g.]

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

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddXor Cudd_bddXnor]

Definition at line 441 of file cuddBddIte.c.

00445 {
00446     DdNode *res;
00447 
00448     do {
00449         dd->reordered = 0;
00450         res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
00451     } while (dd->reordered == 1);
00452     return(res);
00453 
00454 } /* end of Cudd_bddNor */

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

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

Synopsis [Computes f non-polluting-and g.]

Description [Computes f non-polluting-and g. The non-polluting AND of f and g is a hybrid of AND and Restrict. From Restrict, this operation takes the idea of existentially quantifying the top variable of the second operand if it does not appear in the first. Therefore, the variables that appear in the result also appear in f. For the rest, the function behaves like AND. Since the two operands play different roles, non-polluting AND is not commutative.

Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddConstrain Cudd_bddRestrict]

Definition at line 295 of file cuddGenCof.c.

00299 {
00300     DdNode *res;
00301 
00302     do {
00303         dd->reordered = 0;
00304         res = cuddBddNPAndRecur(dd,f,g);
00305     } while (dd->reordered == 1);
00306     return(res);
00307 
00308 } /* end of Cudd_bddNPAnd */

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

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

Synopsis [Computes the disjunction of two BDDs f and g.]

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

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]

Definition at line 377 of file cuddBddIte.c.

00381 {
00382     DdNode *res;
00383 
00384     do {
00385         dd->reordered = 0;
00386         res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
00387     } while (dd->reordered == 1);
00388     res = Cudd_NotCond(res,res != NULL);
00389     return(res);
00390 
00391 } /* end of Cudd_bddOr */

DdNode* Cudd_bddPermute ( DdManager manager,
DdNode node,
int *  permut 
)

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

Synopsis [Permutes the variables of a BDD.]

Description [Given a permutation in array permut, creates a new BDD with permuted variables. There should be an entry in array permut for each variable in the manager. The i-th entry of permut holds the index of the variable that is to substitute the i-th variable. Returns a pointer to the resulting BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addPermute Cudd_bddSwapVariables]

Definition at line 328 of file cuddCompose.c.

00332 {
00333     DdHashTable         *table;
00334     DdNode              *res;
00335 
00336     do {
00337         manager->reordered = 0;
00338         table = cuddHashTableInit(manager,1,2);
00339         if (table == NULL) return(NULL);
00340         res = cuddBddPermuteRecur(manager,table,node,permut);
00341         if (res != NULL) cuddRef(res);
00342         /* Dispose of local cache. */
00343         cuddHashTableQuit(table);
00344 
00345     } while (manager->reordered == 1);
00346 
00347     if (res != NULL) cuddDeref(res);
00348     return(res);
00349 
00350 } /* end of Cudd_bddPermute */

DdNode** Cudd_bddPickArbitraryMinterms ( DdManager dd,
DdNode f,
DdNode **  vars,
int  n,
int  k 
)

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

Synopsis [Picks k on-set minterms evenly distributed from given DD.]

Description [Picks k on-set minterms evenly distributed from given DD. The minterms are in terms of vars. The array vars should contain at least all variables in the support of f; if this condition is not met the minterms built by this procedure may not be contained in f. Builds an array of BDDs for the minterms and returns a pointer to it if successful; NULL otherwise. There are three reasons why the procedure may fail:

  • It may run out of memory;
  • the function f may be the constant 0;
  • the minterms may not be contained in f.

]

SideEffects [None]

SeeAlso [Cudd_bddPickOneMinterm Cudd_bddPickOneCube]

Definition at line 1389 of file cuddUtil.c.

01395 {
01396     char **string;
01397     int i, j, l, size;
01398     int *indices;
01399     int result;
01400     DdNode **old, *neW;
01401     double minterms;
01402     char *saveString;
01403     int saveFlag, savePoint, isSame;
01404 
01405     minterms = Cudd_CountMinterm(dd,f,n);
01406     if ((double)k > minterms) {
01407         return(NULL);
01408     }
01409 
01410     size = dd->size;
01411     string = ALLOC(char *, k);
01412     if (string == NULL) {
01413         dd->errorCode = CUDD_MEMORY_OUT;
01414         return(NULL);
01415     }
01416     for (i = 0; i < k; i++) {
01417         string[i] = ALLOC(char, size + 1);
01418         if (string[i] == NULL) {
01419             for (j = 0; j < i; j++)
01420                 FREE(string[i]);
01421             FREE(string);
01422             dd->errorCode = CUDD_MEMORY_OUT;
01423             return(NULL);
01424         }
01425         for (j = 0; j < size; j++) string[i][j] = '2';
01426         string[i][size] = '\0';
01427     }
01428     indices = ALLOC(int,n);
01429     if (indices == NULL) {
01430         dd->errorCode = CUDD_MEMORY_OUT;
01431         for (i = 0; i < k; i++)
01432             FREE(string[i]);
01433         FREE(string);
01434         return(NULL);
01435     }
01436 
01437     for (i = 0; i < n; i++) {
01438         indices[i] = vars[i]->index;
01439     }
01440 
01441     result = ddPickArbitraryMinterms(dd,f,n,k,string);
01442     if (result == 0) {
01443         for (i = 0; i < k; i++)
01444             FREE(string[i]);
01445         FREE(string);
01446         FREE(indices);
01447         return(NULL);
01448     }
01449 
01450     old = ALLOC(DdNode *, k);
01451     if (old == NULL) {
01452         dd->errorCode = CUDD_MEMORY_OUT;
01453         for (i = 0; i < k; i++)
01454             FREE(string[i]);
01455         FREE(string);
01456         FREE(indices);
01457         return(NULL);
01458     }
01459     saveString = ALLOC(char, size + 1);
01460     if (saveString == NULL) {
01461         dd->errorCode = CUDD_MEMORY_OUT;
01462         for (i = 0; i < k; i++)
01463             FREE(string[i]);
01464         FREE(string);
01465         FREE(indices);
01466         FREE(old);
01467         return(NULL);
01468     }
01469     saveFlag = 0;
01470 
01471     /* Build result BDD array. */
01472     for (i = 0; i < k; i++) {
01473         isSame = 0;
01474         if (!saveFlag) {
01475             for (j = i + 1; j < k; j++) {
01476                 if (strcmp(string[i], string[j]) == 0) {
01477                     savePoint = i;
01478                     strcpy(saveString, string[i]);
01479                     saveFlag = 1;
01480                     break;
01481                 }
01482             }
01483         } else {
01484             if (strcmp(string[i], saveString) == 0) {
01485                 isSame = 1;
01486             } else {
01487                 saveFlag = 0;
01488                 for (j = i + 1; j < k; j++) {
01489                     if (strcmp(string[i], string[j]) == 0) {
01490                         savePoint = i;
01491                         strcpy(saveString, string[i]);
01492                         saveFlag = 1;
01493                         break;
01494                     }
01495                 }
01496             }
01497         }
01498         /* Randomize choice for don't cares. */
01499         for (j = 0; j < n; j++) {
01500             if (string[i][indices[j]] == '2')
01501                 string[i][indices[j]] =
01502                   (char) ((Cudd_Random() & 0x20) ? '1' : '0');
01503         }
01504 
01505         while (isSame) {
01506             isSame = 0;
01507             for (j = savePoint; j < i; j++) {
01508                 if (strcmp(string[i], string[j]) == 0) {
01509                     isSame = 1;
01510                     break;
01511                 }
01512             }
01513             if (isSame) {
01514                 strcpy(string[i], saveString);
01515                 /* Randomize choice for don't cares. */
01516                 for (j = 0; j < n; j++) {
01517                     if (string[i][indices[j]] == '2')
01518                         string[i][indices[j]] =
01519                           (char) ((Cudd_Random() & 0x20) ? '1' : '0');
01520                 }
01521             }
01522         }
01523 
01524         old[i] = Cudd_ReadOne(dd);
01525         cuddRef(old[i]);
01526 
01527         for (j = 0; j < n; j++) {
01528             if (string[i][indices[j]] == '0') {
01529                 neW = Cudd_bddAnd(dd,old[i],Cudd_Not(vars[j]));
01530             } else {
01531                 neW = Cudd_bddAnd(dd,old[i],vars[j]);
01532             }
01533             if (neW == NULL) {
01534                 FREE(saveString);
01535                 for (l = 0; l < k; l++)
01536                     FREE(string[l]);
01537                 FREE(string);
01538                 FREE(indices);
01539                 for (l = 0; l <= i; l++)
01540                     Cudd_RecursiveDeref(dd,old[l]);
01541                 FREE(old);
01542                 return(NULL);
01543             }
01544             cuddRef(neW);
01545             Cudd_RecursiveDeref(dd,old[i]);
01546             old[i] = neW;
01547         }
01548 
01549         /* Test. */
01550         if (!Cudd_bddLeq(dd,old[i],f)) {
01551             FREE(saveString);
01552             for (l = 0; l < k; l++)
01553                 FREE(string[l]);
01554             FREE(string);
01555             FREE(indices);
01556             for (l = 0; l <= i; l++)
01557                 Cudd_RecursiveDeref(dd,old[l]);
01558             FREE(old);
01559             return(NULL);
01560         }
01561     }
01562 
01563     FREE(saveString);
01564     for (i = 0; i < k; i++) {
01565         cuddDeref(old[i]);
01566         FREE(string[i]);
01567     }
01568     FREE(string);
01569     FREE(indices);
01570     return(old);
01571 
01572 }  /* end of Cudd_bddPickArbitraryMinterms */

int Cudd_bddPickOneCube ( DdManager ddm,
DdNode node,
char *  string 
)

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

Synopsis [Picks one on-set cube randomly from the given DD.]

Description [Picks one on-set cube randomly from the given DD. The cube is written into an array of characters. The array must have at least as many entries as there are variables. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddPickOneMinterm]

Definition at line 1217 of file cuddUtil.c.

01221 {
01222     DdNode *N, *T, *E;
01223     DdNode *one, *bzero;
01224     char   dir;
01225     int    i;
01226 
01227     if (string == NULL || node == NULL) return(0);
01228 
01229     /* The constant 0 function has no on-set cubes. */
01230     one = DD_ONE(ddm);
01231     bzero = Cudd_Not(one);
01232     if (node == bzero) return(0);
01233 
01234     for (i = 0; i < ddm->size; i++) string[i] = 2;
01235 
01236     for (;;) {
01237 
01238         if (node == one) break;
01239 
01240         N = Cudd_Regular(node);
01241 
01242         T = cuddT(N); E = cuddE(N);
01243         if (Cudd_IsComplement(node)) {
01244             T = Cudd_Not(T); E = Cudd_Not(E);
01245         }
01246         if (T == bzero) {
01247             string[N->index] = 0;
01248             node = E;
01249         } else if (E == bzero) {
01250             string[N->index] = 1;
01251             node = T;
01252         } else {
01253             dir = (char) ((Cudd_Random() & 0x2000) >> 13);
01254             string[N->index] = dir;
01255             node = dir ? T : E;
01256         }
01257     }
01258     return(1);
01259 
01260 } /* end of Cudd_bddPickOneCube */

DdNode* Cudd_bddPickOneMinterm ( DdManager dd,
DdNode f,
DdNode **  vars,
int  n 
)

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

Synopsis [Picks one on-set minterm randomly from the given DD.]

Description [Picks one on-set minterm randomly from the given DD. The minterm is in terms of vars. The array vars should contain at least all variables in the support of f; if this condition is not met the minterm built by this procedure may not be contained in f. Builds a BDD for the minterm and returns a pointer to it if successful; NULL otherwise. There are three reasons why the procedure may fail:

  • It may run out of memory;
  • the function f may be the constant 0;
  • the minterm may not be contained in f.

]

SideEffects [None]

SeeAlso [Cudd_bddPickOneCube]

Definition at line 1287 of file cuddUtil.c.

01292 {
01293     char *string;
01294     int i, size;
01295     int *indices;
01296     int result;
01297     DdNode *old, *neW;
01298 
01299     size = dd->size;
01300     string = ALLOC(char, size);
01301     if (string == NULL) {
01302         dd->errorCode = CUDD_MEMORY_OUT;
01303         return(NULL);
01304     }
01305     indices = ALLOC(int,n);
01306     if (indices == NULL) {
01307         dd->errorCode = CUDD_MEMORY_OUT;
01308         FREE(string);
01309         return(NULL);
01310     }
01311 
01312     for (i = 0; i < n; i++) {
01313         indices[i] = vars[i]->index;
01314     }
01315 
01316     result = Cudd_bddPickOneCube(dd,f,string);
01317     if (result == 0) {
01318         FREE(string);
01319         FREE(indices);
01320         return(NULL);
01321     }
01322 
01323     /* Randomize choice for don't cares. */
01324     for (i = 0; i < n; i++) {
01325         if (string[indices[i]] == 2)
01326             string[indices[i]] = (char) ((Cudd_Random() & 0x20) >> 5);
01327     }
01328 
01329     /* Build result BDD. */
01330     old = Cudd_ReadOne(dd);
01331     cuddRef(old);
01332 
01333     for (i = n-1; i >= 0; i--) {
01334         neW = Cudd_bddAnd(dd,old,Cudd_NotCond(vars[i],string[indices[i]]==0));
01335         if (neW == NULL) {
01336             FREE(string);
01337             FREE(indices);
01338             Cudd_RecursiveDeref(dd,old);
01339             return(NULL);
01340         }
01341         cuddRef(neW);
01342         Cudd_RecursiveDeref(dd,old);
01343         old = neW;
01344     }
01345 
01346 #ifdef DD_DEBUG
01347     /* Test. */
01348     if (Cudd_bddLeq(dd,old,f)) {
01349         cuddDeref(old);
01350     } else {
01351         Cudd_RecursiveDeref(dd,old);
01352         old = NULL;
01353     }
01354 #else
01355     cuddDeref(old);
01356 #endif
01357 
01358     FREE(string);
01359     FREE(indices);
01360     return(old);
01361 
01362 }  /* end of Cudd_bddPickOneMinterm */

int Cudd_bddPrintCover ( DdManager dd,
DdNode l,
DdNode u 
)

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

Synopsis [Prints a sum of prime implicants of a BDD.]

Description [Prints a sum of product cover for an incompletely specified function given by a lower bound and an upper bound. Each product is a prime implicant obtained by expanding the product corresponding to a path from node to the constant one. Uses the package default output file. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_PrintMinterm]

Definition at line 249 of file cuddUtil.c.

00253 {
00254     int *array;
00255     int q, result;
00256     DdNode *lb;
00257 #ifdef DD_DEBUG
00258     DdNode *cover;
00259 #endif
00260 
00261     array = ALLOC(int, Cudd_ReadSize(dd));
00262     if (array == NULL) return(0);
00263     lb = l;
00264     cuddRef(lb);
00265 #ifdef DD_DEBUG
00266     cover = Cudd_ReadLogicZero(dd);
00267     cuddRef(cover);
00268 #endif
00269     while (lb != Cudd_ReadLogicZero(dd)) {
00270         DdNode *implicant, *prime, *tmp;
00271         int length;
00272         implicant = Cudd_LargestCube(dd,lb,&length);
00273         if (implicant == NULL) {
00274             Cudd_RecursiveDeref(dd,lb);
00275             FREE(array);
00276             return(0);
00277         }
00278         cuddRef(implicant);
00279         prime = Cudd_bddMakePrime(dd,implicant,u);
00280         if (prime == NULL) {
00281             Cudd_RecursiveDeref(dd,lb);
00282             Cudd_RecursiveDeref(dd,implicant);
00283             FREE(array);
00284             return(0);
00285         }
00286         cuddRef(prime);
00287         Cudd_RecursiveDeref(dd,implicant);
00288         tmp = Cudd_bddAnd(dd,lb,Cudd_Not(prime));
00289         if (tmp == NULL) {
00290             Cudd_RecursiveDeref(dd,lb);
00291             Cudd_RecursiveDeref(dd,prime);
00292             FREE(array);
00293             return(0);
00294         }
00295         cuddRef(tmp);
00296         Cudd_RecursiveDeref(dd,lb);
00297         lb = tmp;
00298         result = Cudd_BddToCubeArray(dd,prime,array);
00299         if (result == 0) {
00300             Cudd_RecursiveDeref(dd,lb);
00301             Cudd_RecursiveDeref(dd,prime);
00302             FREE(array);
00303             return(0);
00304         }
00305         for (q = 0; q < dd->size; q++) {
00306             switch (array[q]) {
00307             case 0:
00308                 (void) fprintf(dd->out, "0");
00309                 break;
00310             case 1:
00311                 (void) fprintf(dd->out, "1");
00312                 break;
00313             case 2:
00314                 (void) fprintf(dd->out, "-");
00315                 break;
00316             default:
00317                 (void) fprintf(dd->out, "?");
00318             }
00319         }
00320         (void) fprintf(dd->out, " 1\n");
00321 #ifdef DD_DEBUG
00322         tmp = Cudd_bddOr(dd,prime,cover);
00323         if (tmp == NULL) {
00324             Cudd_RecursiveDeref(dd,cover);
00325             Cudd_RecursiveDeref(dd,lb);
00326             Cudd_RecursiveDeref(dd,prime);
00327             FREE(array);
00328             return(0);
00329         }
00330         cuddRef(tmp);
00331         Cudd_RecursiveDeref(dd,cover);
00332         cover = tmp;
00333 #endif
00334         Cudd_RecursiveDeref(dd,prime);
00335     }
00336     (void) fprintf(dd->out, "\n");
00337     Cudd_RecursiveDeref(dd,lb);
00338     FREE(array);
00339 #ifdef DD_DEBUG
00340     if (!Cudd_bddLeq(dd,cover,u) || !Cudd_bddLeq(dd,l,cover)) {
00341         Cudd_RecursiveDeref(dd,cover);
00342         return(0);
00343     }
00344     Cudd_RecursiveDeref(dd,cover);
00345 #endif
00346     return(1);
00347 
00348 } /* end of Cudd_bddPrintCover */

int Cudd_bddRead ( FILE *  fp,
DdManager dd,
DdNode **  E,
DdNode ***  x,
DdNode ***  y,
int *  nx,
int *  ny,
int *  m,
int *  n,
int  bx,
int  sx,
int  by,
int  sy 
)

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

Synopsis [Reads in a graph (without labels) given as a list of arcs.]

Description [Reads in a graph (without labels) given as an adjacency matrix. The first line of the input contains the numbers of rows and columns of the adjacency matrix. The remaining lines contain the arcs of the graph, one per line. Each arc is described by two integers, i.e., the row and column number, or the indices of the two endpoints. Cudd_bddRead produces a BDD that depends on two sets of variables: x and y. The x variables (x\[0\] ... x\[nx-1\]) encode the row index and the y variables (y\[0\] ... y\[ny-1\]) encode the column index. x\[0\] and y\[0\] are the most significant bits in the indices. The variables may already exist or may be created by the function. The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.

On input, nx and ny hold the numbers of row and column variables already in existence. On output, they hold the numbers of row and column variables actually used by the matrix. When Cudd_bddRead creates the variable arrays, the index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy. When some variables already exist, Cudd_bddRead expects the indices of the existing x variables to be bx+i*sx, and the indices of the existing y variables to be by+i*sy.

m and n are set to the numbers of rows and columns of the matrix. Their values on input are immaterial. The BDD for the graph is returned in E, and its reference count is > 0. Cudd_bddRead returns 1 in case of success; 0 otherwise.]

SideEffects [nx and ny are set to the numbers of row and column variables. m and n are set to the numbers of rows and columns. x and y are possibly extended to represent the array of row and column variables.]

SeeAlso [Cudd_addHarwell Cudd_addRead]

Definition at line 365 of file cuddRead.c.

00379 {
00380     DdNode *one, *zero;
00381     DdNode *w;
00382     DdNode *minterm1;
00383     int u, v, err, i, nv;
00384     int lnx, lny;
00385     DdNode **lx, **ly;
00386 
00387     one = DD_ONE(dd);
00388     zero = Cudd_Not(one);
00389 
00390     err = fscanf(fp, "%d %d", &u, &v);
00391     if (err == EOF) {
00392         return(0);
00393     } else if (err != 2) {
00394         return(0);
00395     }
00396 
00397     *m = u;
00398     /* Compute the number of x variables. */
00399     lx = *x;
00400     u--;        /* row and column numbers start from 0 */
00401     for (lnx=0; u > 0; lnx++) {
00402         u >>= 1;
00403     }
00404     if (lnx > *nx) {
00405         *x = lx = REALLOC(DdNode *, *x, lnx);
00406         if (lx == NULL) {
00407             dd->errorCode = CUDD_MEMORY_OUT;
00408             return(0);
00409         }
00410     }
00411 
00412     *n = v;
00413     /* Compute the number of y variables. */
00414     ly = *y;
00415     v--;        /* row and column numbers start from 0 */
00416     for (lny=0; v > 0; lny++) {
00417         v >>= 1;
00418     }
00419     if (lny > *ny) {
00420         *y = ly = REALLOC(DdNode *, *y, lny);
00421         if (ly == NULL) {
00422             dd->errorCode = CUDD_MEMORY_OUT;
00423             return(0);
00424         }
00425     }
00426 
00427     /* Create all new variables. */
00428     for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) {
00429         do {
00430             dd->reordered = 0;
00431             lx[i] = cuddUniqueInter(dd, nv, one, zero);
00432         } while (dd->reordered == 1);
00433         if (lx[i] == NULL) return(0);
00434         cuddRef(lx[i]);
00435     }
00436     for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) {
00437         do {
00438             dd->reordered = 0;
00439             ly[i] = cuddUniqueInter(dd, nv, one, zero);
00440         } while (dd->reordered == 1);
00441         if (ly[i] == NULL) return(0);
00442         cuddRef(ly[i]);
00443     }
00444     *nx = lnx;
00445     *ny = lny;
00446 
00447     *E = zero; /* this call will never cause reordering */
00448     cuddRef(*E);
00449 
00450     while (! feof(fp)) {
00451         err = fscanf(fp, "%d %d", &u, &v);
00452         if (err == EOF) {
00453             break;
00454         } else if (err != 2) {
00455             return(0);
00456         } else if (u >= *m || v >= *n || u < 0 || v < 0) {
00457             return(0);
00458         }
00459  
00460         minterm1 = one; cuddRef(minterm1);
00461 
00462         /* Build minterm1 corresponding to this arc. */
00463         for (i = lnx - 1; i>=0; i--) {
00464             if (u & 1) {
00465                 w = Cudd_bddAnd(dd, minterm1, lx[i]);
00466             } else {
00467                 w = Cudd_bddAnd(dd, minterm1, Cudd_Not(lx[i]));
00468             }
00469             if (w == NULL) {
00470                 Cudd_RecursiveDeref(dd, minterm1);
00471                 return(0);
00472             }
00473             cuddRef(w);
00474             Cudd_RecursiveDeref(dd,minterm1);
00475             minterm1 = w;
00476             u >>= 1;
00477         }
00478         for (i = lny - 1; i>=0; i--) {
00479             if (v & 1) {
00480                 w = Cudd_bddAnd(dd, minterm1, ly[i]);
00481             } else {
00482                 w = Cudd_bddAnd(dd, minterm1, Cudd_Not(ly[i]));
00483             }
00484             if (w == NULL) {
00485                 Cudd_RecursiveDeref(dd, minterm1);
00486                 return(0);
00487             }
00488             cuddRef(w);
00489             Cudd_RecursiveDeref(dd, minterm1);
00490             minterm1 = w;
00491             v >>= 1;
00492         }
00493 
00494         w = Cudd_bddAnd(dd, Cudd_Not(minterm1), Cudd_Not(*E));
00495         if (w == NULL) {
00496             Cudd_RecursiveDeref(dd, minterm1);
00497             return(0);
00498         }
00499         w = Cudd_Not(w);
00500         cuddRef(w);
00501         Cudd_RecursiveDeref(dd, minterm1);
00502         Cudd_RecursiveDeref(dd, *E);
00503         *E = w;
00504     }
00505     return(1);
00506 
00507 } /* end of Cudd_bddRead */

int Cudd_bddReadPairIndex ( DdManager dd,
int  index 
)

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

Synopsis [Reads a corresponding pair index for a given index.]

Description [Reads a corresponding pair index for a given index. These pair indices are present and next state variable. Returns the corresponding variable index if the variable exists; -1 otherwise.]

SideEffects [modifies the manager]

SeeAlso [Cudd_bddSetPairIndex]

Definition at line 4145 of file cuddAPI.c.

04148 {
04149     if (index >= dd->size || index < 0) return -1;
04150     return dd->subtables[dd->perm[index]].pairIndex;
04151 
04152 } /* end of Cudd_bddReadPairIndex */

void Cudd_bddRealignDisable ( DdManager unique  ) 

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

Synopsis [Disables realignment of ZDD order to BDD order.]

Description []

SideEffects [None]

SeeAlso [Cudd_bddRealignEnable Cudd_bddRealignmentEnabled Cudd_zddRealignEnable Cudd_zddRealignmentEnabled]

Definition at line 961 of file cuddAPI.c.

00963 {
00964     unique->realignZ = 0;
00965     return;
00966 
00967 } /* end of Cudd_bddRealignDisable */

void Cudd_bddRealignEnable ( DdManager unique  ) 

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

Synopsis [Enables realignment of BDD order to ZDD order.]

Description [Enables realignment of the BDD variable order to the ZDD variable order after the ZDDs have been reordered. The number of ZDD variables must be a multiple of the number of BDD variables for realignment to make sense. If this condition is not met, Cudd_zddReduceHeap will return 0. Let M be the ratio of the two numbers. For the purpose of realignment, the ZDD variables from M*i to (M+1)*i-1 are reagarded as corresponding to BDD variable i. Realignment is initially disabled.]

SideEffects [None]

SeeAlso [Cudd_zddReduceHeap Cudd_bddRealignDisable Cudd_bddRealignmentEnabled Cudd_zddRealignDisable Cudd_zddRealignmentEnabled]

Definition at line 939 of file cuddAPI.c.

00941 {
00942     unique->realignZ = 1;
00943     return;
00944 
00945 } /* end of Cudd_bddRealignEnable */

int Cudd_bddRealignmentEnabled ( DdManager unique  ) 

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

Synopsis [Tells whether the realignment of BDD order to ZDD order is enabled.]

Description [Returns 1 if the realignment of BDD order to ZDD order is enabled; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddRealignEnable Cudd_bddRealignDisable Cudd_zddRealignEnable Cudd_zddRealignDisable]

Definition at line 909 of file cuddAPI.c.

00911 {
00912     return(unique->realignZ);
00913 
00914 } /* end of Cudd_bddRealignmentEnabled */

int Cudd_bddResetVarToBeGrouped ( DdManager dd,
int  index 
)

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

Synopsis [Resets a variable not to be grouped.]

Description [Resets a variable not to be grouped. This function is used for lazy sifting. Returns 1 if successful; 0 otherwise.]

SideEffects [modifies the manager]

SeeAlso [Cudd_bddSetVarToBeGrouped Cudd_bddSetVarHardGroup]

Definition at line 4219 of file cuddAPI.c.

04222 {
04223     if (index >= dd->size || index < 0) return(0);
04224     if (dd->subtables[dd->perm[index]].varToBeGrouped <=
04225         CUDD_LAZY_SOFT_GROUP) {
04226         dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_NONE;
04227     }
04228     return(1);
04229 
04230 } /* end of Cudd_bddResetVarToBeGrouped */

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

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

Synopsis [BDD restrict according to Coudert and Madre's algorithm (ICCAD90).]

Description [BDD restrict according to Coudert and Madre's algorithm (ICCAD90). Returns the restricted BDD if successful; otherwise NULL. If application of restrict results in a BDD larger than the input BDD, the input BDD is returned.]

SideEffects [None]

SeeAlso [Cudd_bddConstrain Cudd_addRestrict]

Definition at line 208 of file cuddGenCof.c.

00212 {
00213     DdNode *suppF, *suppC, *commonSupport;
00214     DdNode *cplus, *res;
00215     int retval;
00216     int sizeF, sizeRes;
00217 
00218     /* Check terminal cases here to avoid computing supports in trivial cases.
00219     ** This also allows us notto check later for the case c == 0, in which
00220     ** there is no common support. */
00221     if (c == Cudd_Not(DD_ONE(dd))) return(Cudd_Not(DD_ONE(dd)));
00222     if (Cudd_IsConstant(f)) return(f);
00223     if (f == c) return(DD_ONE(dd));
00224     if (f == Cudd_Not(c)) return(Cudd_Not(DD_ONE(dd)));
00225 
00226     /* Check if supports intersect. */
00227     retval = Cudd_ClassifySupport(dd,f,c,&commonSupport,&suppF,&suppC);
00228     if (retval == 0) {
00229         return(NULL);
00230     }
00231     cuddRef(commonSupport); cuddRef(suppF); cuddRef(suppC);
00232     Cudd_IterDerefBdd(dd,suppF);
00233 
00234     if (commonSupport == DD_ONE(dd)) {
00235         Cudd_IterDerefBdd(dd,commonSupport);
00236         Cudd_IterDerefBdd(dd,suppC);
00237         return(f);
00238     }
00239     Cudd_IterDerefBdd(dd,commonSupport);
00240 
00241     /* Abstract from c the variables that do not appear in f. */
00242     cplus = Cudd_bddExistAbstract(dd, c, suppC);
00243     if (cplus == NULL) {
00244         Cudd_IterDerefBdd(dd,suppC);
00245         return(NULL);
00246     }
00247     cuddRef(cplus);
00248     Cudd_IterDerefBdd(dd,suppC);
00249 
00250     do {
00251         dd->reordered = 0;
00252         res = cuddBddRestrictRecur(dd, f, cplus);
00253     } while (dd->reordered == 1);
00254     if (res == NULL) {
00255         Cudd_IterDerefBdd(dd,cplus);
00256         return(NULL);
00257     }
00258     cuddRef(res);
00259     Cudd_IterDerefBdd(dd,cplus);
00260     /* Make restric safe by returning the smaller of the input and the
00261     ** result. */
00262     sizeF = Cudd_DagSize(f);
00263     sizeRes = Cudd_DagSize(res);
00264     if (sizeF <= sizeRes) {
00265         Cudd_IterDerefBdd(dd, res);
00266         return(f);
00267     } else {
00268         cuddDeref(res);
00269         return(res);
00270     }
00271 
00272 } /* end of Cudd_bddRestrict */

int Cudd_bddSetNsVar ( DdManager dd,
int  index 
)

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

Synopsis [Sets a variable type to next state.]

Description [Sets a variable type to next state. The variable type is used by lazy sifting. Returns 1 if successful; 0 otherwise.]

SideEffects [modifies the manager]

SeeAlso [Cudd_bddSetPiVar Cudd_bddSetPsVar Cudd_bddIsNsVar]

Definition at line 4022 of file cuddAPI.c.

04025 {
04026     if (index >= dd->size || index < 0) return (0);
04027     dd->subtables[dd->perm[index]].varType = CUDD_VAR_NEXT_STATE;
04028     return(1);
04029 
04030 } /* end of Cudd_bddSetNsVar */

int Cudd_bddSetPairIndex ( DdManager dd,
int  index,
int  pairIndex 
)

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

Synopsis [Sets a corresponding pair index for a given index.]

Description [Sets a corresponding pair index for a given index. These pair indices are present and next state variable. Returns 1 if successful; 0 otherwise.]

SideEffects [modifies the manager]

SeeAlso [Cudd_bddReadPairIndex]

Definition at line 4119 of file cuddAPI.c.

04123 {
04124     if (index >= dd->size || index < 0) return(0);
04125     dd->subtables[dd->perm[index]].pairIndex = pairIndex;
04126     return(1);
04127 
04128 } /* end of Cudd_bddSetPairIndex */

int Cudd_bddSetPiVar ( DdManager dd,
int  index 
)

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

Synopsis [Sets a variable type to primary input.]

Description [Sets a variable type to primary input. The variable type is used by lazy sifting. Returns 1 if successful; 0 otherwise.]

SideEffects [modifies the manager]

SeeAlso [Cudd_bddSetPsVar Cudd_bddSetNsVar Cudd_bddIsPiVar]

Definition at line 3974 of file cuddAPI.c.

03977 {
03978     if (index >= dd->size || index < 0) return (0);
03979     dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRIMARY_INPUT;
03980     return(1);
03981 
03982 } /* end of Cudd_bddSetPiVar */

int Cudd_bddSetPsVar ( DdManager dd,
int  index 
)

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

Synopsis [Sets a variable type to present state.]

Description [Sets a variable type to present state. The variable type is used by lazy sifting. Returns 1 if successful; 0 otherwise.]

SideEffects [modifies the manager]

SeeAlso [Cudd_bddSetPiVar Cudd_bddSetNsVar Cudd_bddIsPsVar]

Definition at line 3998 of file cuddAPI.c.

04001 {
04002     if (index >= dd->size || index < 0) return (0);
04003     dd->subtables[dd->perm[index]].varType = CUDD_VAR_PRESENT_STATE;
04004     return(1);
04005 
04006 } /* end of Cudd_bddSetPsVar */

int Cudd_bddSetVarHardGroup ( DdManager dd,
int  index 
)

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

Synopsis [Sets a variable to be a hard group.]

Description [Sets a variable to be a hard group. This function is used for lazy sifting. Returns 1 if successful; 0 otherwise.]

SideEffects [modifies the manager]

SeeAlso [Cudd_bddSetVarToBeGrouped Cudd_bddResetVarToBeGrouped Cudd_bddIsVarHardGroup]

Definition at line 4195 of file cuddAPI.c.

04198 {
04199     if (index >= dd->size || index < 0) return(0);
04200     dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_HARD_GROUP;
04201     return(1);
04202 
04203 } /* end of Cudd_bddSetVarHardGrouped */

int Cudd_bddSetVarToBeGrouped ( DdManager dd,
int  index 
)

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

Synopsis [Sets a variable to be grouped.]

Description [Sets a variable to be grouped. This function is used for lazy sifting. Returns 1 if successful; 0 otherwise.]

SideEffects [modifies the manager]

SeeAlso [Cudd_bddSetVarHardGroup Cudd_bddResetVarToBeGrouped]

Definition at line 4168 of file cuddAPI.c.

04171 {
04172     if (index >= dd->size || index < 0) return(0);
04173     if (dd->subtables[dd->perm[index]].varToBeGrouped <= CUDD_LAZY_SOFT_GROUP) {
04174         dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_SOFT_GROUP;
04175     }
04176     return(1);
04177 
04178 } /* end of Cudd_bddSetVarToBeGrouped */

int Cudd_bddSetVarToBeUngrouped ( DdManager dd,
int  index 
)

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

Synopsis [Sets a variable to be ungrouped.]

Description [Sets a variable to be ungrouped. This function is used for lazy sifting. Returns 1 if successful; 0 otherwise.]

SideEffects [modifies the manager]

SeeAlso [Cudd_bddIsVarToBeUngrouped]

Definition at line 4272 of file cuddAPI.c.

04275 {
04276     if (index >= dd->size || index < 0) return(0);
04277     dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_UNGROUP;
04278     return(1);
04279 
04280 } /* end of Cudd_bddSetVarToBeGrouped */

DdNode* Cudd_bddSqueeze ( DdManager dd,
DdNode l,
DdNode u 
)

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

Synopsis [Finds a small BDD in a function interval.]

Description [Finds a small BDD in a function interval. Given BDDs l and u, representing the lower bound and upper bound of a function interval, Cudd_bddSqueeze produces the BDD of a function within the interval with a small BDD. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddRestrict Cudd_bddLICompaction]

Definition at line 598 of file cuddGenCof.c.

00602 {
00603     DdNode *res;
00604     int sizeRes, sizeL, sizeU;
00605 
00606     do {
00607         dd->reordered = 0;
00608         res = cuddBddSqueeze(dd,l,u);
00609     } while (dd->reordered == 1);
00610     if (res == NULL) return(NULL);
00611     /* We now compare the result with the bounds and return the smallest.
00612     ** We first compare to u, so that in case l == 0 and u == 1, we return
00613     ** 0 as in other minimization algorithms. */
00614     sizeRes = Cudd_DagSize(res);
00615     sizeU = Cudd_DagSize(u);
00616     if (sizeU <= sizeRes) {
00617         cuddRef(res);
00618         Cudd_IterDerefBdd(dd,res);
00619         res = u;
00620         sizeRes = sizeU;
00621     }
00622     sizeL = Cudd_DagSize(l);
00623     if (sizeL <= sizeRes) {
00624         cuddRef(res);
00625         Cudd_IterDerefBdd(dd,res);
00626         res = l;
00627         sizeRes = sizeL;
00628     }
00629     return(res);
00630 
00631 } /* end of Cudd_bddSqueeze */

DdNode* Cudd_bddSwapVariables ( DdManager dd,
DdNode f,
DdNode **  x,
DdNode **  y,
int  n 
)

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

Synopsis [Swaps two sets of variables of the same size (x and y) in the BDD f.]

Description [Swaps two sets of variables of the same size (x and y) in the BDD f. The size is given by n. The two sets of variables are assumed to be disjoint. Returns a pointer to the resulting BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddPermute Cudd_addSwapVariables]

Definition at line 460 of file cuddCompose.c.

00466 {
00467     DdNode *swapped;
00468     int  i, j, k;
00469     int  *permut;
00470 
00471     permut = ALLOC(int,dd->size);
00472     if (permut == NULL) {
00473         dd->errorCode = CUDD_MEMORY_OUT;
00474         return(NULL);
00475     }
00476     for (i = 0; i < dd->size; i++) permut[i] = i;
00477     for (i = 0; i < n; i++) {
00478         j = x[i]->index;
00479         k = y[i]->index;
00480         permut[j] = k;
00481         permut[k] = j;
00482     }
00483 
00484     swapped = Cudd_bddPermute(dd,f,permut);
00485     FREE(permut);
00486 
00487     return(swapped);
00488 
00489 } /* end of Cudd_bddSwapVariables */

DdNode* Cudd_BddToAdd ( DdManager dd,
DdNode B 
)

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

Synopsis [Converts a BDD to a 0-1 ADD.]

Description [Converts a BDD to a 0-1 ADD. Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addBddPattern Cudd_addBddThreshold Cudd_addBddInterval Cudd_addBddStrictThreshold]

Definition at line 345 of file cuddBridge.c.

00348 {
00349     DdNode *res;
00350 
00351     do {
00352         dd->reordered = 0;
00353         res = ddBddToAddRecur(dd, B);
00354     } while (dd->reordered ==1);
00355     return(res);
00356 
00357 } /* end of Cudd_BddToAdd */

int Cudd_BddToCubeArray ( DdManager dd,
DdNode cube,
int *  array 
)

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

Synopsis [Builds a positional array from the BDD of a cube.]

Description [Builds a positional array from the BDD of a cube. Array must have one entry for each BDD variable. The positional array has 1 in i-th position if the variable of index i appears in true form in the cube; it has 0 in i-th position if the variable of index i appears in complemented form in the cube; finally, it has 2 in i-th position if the variable of index i does not appear in the cube. Returns 1 if successful (the BDD is indeed a cube); 0 otherwise.]

SideEffects [The result is in the array passed by reference.]

SeeAlso [Cudd_CubeArrayToBdd]

Definition at line 2342 of file cuddUtil.c.

02346 {
02347     DdNode *scan, *t, *e;
02348     int i;
02349     int size = Cudd_ReadSize(dd);
02350     DdNode *zero = Cudd_Not(DD_ONE(dd));
02351 
02352     for (i = size-1; i >= 0; i--) {
02353         array[i] = 2;
02354     }
02355     scan = cube;
02356     while (!Cudd_IsConstant(scan)) {
02357         int index = Cudd_Regular(scan)->index;
02358         cuddGetBranches(scan,&t,&e);
02359         if (t == zero) {
02360             array[index] = 0;
02361             scan = e;
02362         } else if (e == zero) {
02363             array[index] = 1;
02364             scan = t;
02365         } else {
02366             return(0);  /* cube is not a cube */
02367         }
02368     }
02369     if (scan == zero) {
02370         return(0);
02371     } else {
02372         return(1);
02373     }
02374 
02375 } /* end of Cudd_BddToCubeArray */

DdNode* Cudd_bddTransfer ( DdManager ddSource,
DdManager ddDestination,
DdNode f 
)

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

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

Description [Convert a BDD from a manager to another one. The orders of the variables in the two managers may be different. Returns a pointer to the BDD in the destination manager if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 405 of file cuddBridge.c.

00409 {
00410     DdNode *res;
00411     do {
00412         ddDestination->reordered = 0;
00413         res = cuddBddTransfer(ddSource, ddDestination, f);
00414     } while (ddDestination->reordered == 1);
00415     return(res);
00416 
00417 } /* end of Cudd_bddTransfer */

int Cudd_bddUnbindVar ( DdManager dd,
int  index 
)

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

Synopsis [Allows the sifting of a variable.]

Description [This function resets the flag that prevents the sifting of a variable. In successive variable reorderings, the variable will NOT be skipped, that is, sifted. Initially all variables can be sifted. It is necessary to call this function only to re-enable sifting after a call to Cudd_bddBindVar. Returns 1 if successful; 0 otherwise (i.e., invalid variable index).]

SideEffects [Changes the "bindVar" flag in DdSubtable.]

SeeAlso [Cudd_bddBindVar]

Definition at line 3924 of file cuddAPI.c.

03927 {
03928     if (index >= dd->size || index < 0) return(0);
03929     dd->subtables[dd->perm[index]].bindVar = 0;
03930     return(1);
03931 
03932 } /* end of Cudd_bddUnbindVar */

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

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

Synopsis [Universally abstracts all the variables in cube from f.]

Description [Universally abstracts all the variables in cube from f. Returns the abstracted BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddExistAbstract Cudd_addUnivAbstract]

Definition at line 203 of file cuddBddAbs.c.

00207 {
00208     DdNode      *res;
00209 
00210     if (bddCheckPositiveCube(manager, cube) == 0) {
00211         (void) fprintf(manager->err,
00212                        "Error: Can only abstract positive cubes\n");
00213         manager->errorCode = CUDD_INVALID_ARG;
00214         return(NULL);
00215     }
00216 
00217     do {
00218         manager->reordered = 0;
00219         res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube);
00220     } while (manager->reordered == 1);
00221     if (res != NULL) res = Cudd_Not(res);
00222 
00223     return(res);
00224 
00225 } /* end of Cudd_bddUnivAbstract */

int Cudd_bddVarConjDecomp ( DdManager dd,
DdNode f,
DdNode ***  conjuncts 
)

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

Synopsis [Performs two-way conjunctive decomposition of a BDD.]

Description [Conjunctively decomposes one BDD according to a variable. If f is the function of the BDD and x is the variable, the decomposition is (f+x)(f+x'). The variable is chosen so as to balance the sizes of the two conjuncts and to keep them small. Returns the number of conjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise.]

SideEffects [The two factors are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the conjuncts are already referenced. If the function returns 0, the array for the conjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]

SeeAlso [Cudd_bddVarDisjDecomp Cudd_bddGenConjDecomp Cudd_bddApproxConjDecomp Cudd_bddIterConjDecomp]

Definition at line 611 of file cuddDecomp.c.

00615 {
00616     int best;
00617     int min;
00618     DdNode *support, *scan, *var, *glocal, *hlocal;
00619 
00620     /* Find best cofactoring variable. */
00621     support = Cudd_Support(dd,f);
00622     if (support == NULL) return(0);
00623     if (Cudd_IsConstant(support)) {
00624         *conjuncts = ALLOC(DdNode *,1);
00625         if (*conjuncts == NULL) {
00626             dd->errorCode = CUDD_MEMORY_OUT;
00627             return(0);
00628         }
00629         (*conjuncts)[0] = f;
00630         cuddRef((*conjuncts)[0]);
00631         return(1);
00632     }
00633     cuddRef(support);
00634     min = 1000000000;
00635     best = -1;
00636     scan = support;
00637     while (!Cudd_IsConstant(scan)) {
00638         int i = scan->index;
00639         int est1 = Cudd_EstimateCofactor(dd,f,i,1);
00640         int est0 = Cudd_EstimateCofactor(dd,f,i,0);
00641         /* Minimize the size of the larger of the two cofactors. */
00642         int est = (est1 > est0) ? est1 : est0;
00643         if (est < min) {
00644             min = est;
00645             best = i;
00646         }
00647         scan = cuddT(scan);
00648     }
00649 #ifdef DD_DEBUG
00650     assert(best >= 0 && best < dd->size);
00651 #endif
00652     Cudd_RecursiveDeref(dd,support);
00653 
00654     var = Cudd_bddIthVar(dd,best);
00655     glocal = Cudd_bddOr(dd,f,var);
00656     if (glocal == NULL) {
00657         return(0);
00658     }
00659     cuddRef(glocal);
00660     hlocal = Cudd_bddOr(dd,f,Cudd_Not(var));
00661     if (hlocal == NULL) {
00662         Cudd_RecursiveDeref(dd,glocal);
00663         return(0);
00664     }
00665     cuddRef(hlocal);
00666 
00667     if (glocal != DD_ONE(dd)) {
00668         if (hlocal != DD_ONE(dd)) {
00669             *conjuncts = ALLOC(DdNode *,2);
00670             if (*conjuncts == NULL) {
00671                 Cudd_RecursiveDeref(dd,glocal);
00672                 Cudd_RecursiveDeref(dd,hlocal);
00673                 dd->errorCode = CUDD_MEMORY_OUT;
00674                 return(0);
00675             }
00676             (*conjuncts)[0] = glocal;
00677             (*conjuncts)[1] = hlocal;
00678             return(2);
00679         } else {
00680             Cudd_RecursiveDeref(dd,hlocal);
00681             *conjuncts = ALLOC(DdNode *,1);
00682             if (*conjuncts == NULL) {
00683                 Cudd_RecursiveDeref(dd,glocal);
00684                 dd->errorCode = CUDD_MEMORY_OUT;
00685                 return(0);
00686             }
00687             (*conjuncts)[0] = glocal;
00688             return(1);
00689         }
00690     } else {
00691         Cudd_RecursiveDeref(dd,glocal);
00692         *conjuncts = ALLOC(DdNode *,1);
00693         if (*conjuncts == NULL) {
00694             Cudd_RecursiveDeref(dd,hlocal);
00695             dd->errorCode = CUDD_MEMORY_OUT;
00696             return(0);
00697         }
00698         (*conjuncts)[0] = hlocal;
00699         return(1);
00700     }
00701 
00702 } /* end of Cudd_bddVarConjDecomp */

int Cudd_bddVarDisjDecomp ( DdManager dd,
DdNode f,
DdNode ***  disjuncts 
)

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

Synopsis [Performs two-way disjunctive decomposition of a BDD.]

Description [Performs two-way disjunctive decomposition of a BDD according to a variable. If f is the function of the BDD and x is the variable, the decomposition is f*x + f*x'. The variable is chosen so as to balance the sizes of the two disjuncts and to keep them small. Returns the number of disjuncts produced, that is, 2 if successful; 1 if no meaningful decomposition was found; 0 otherwise.]

SideEffects [The two disjuncts are returned in an array as side effects. The array is allocated by this function. It is the caller's responsibility to free it. On successful completion, the disjuncts are already referenced. If the function returns 0, the array for the disjuncts is not allocated. If the function returns 1, the only factor equals the function to be decomposed.]

SeeAlso [Cudd_bddVarConjDecomp Cudd_bddApproxDisjDecomp Cudd_bddIterDisjDecomp Cudd_bddGenDisjDecomp]

Definition at line 729 of file cuddDecomp.c.

00733 {
00734     int result, i;
00735 
00736     result = Cudd_bddVarConjDecomp(dd,Cudd_Not(f),disjuncts);
00737     for (i = 0; i < result; i++) {
00738         (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]);
00739     }
00740     return(result);
00741 
00742 } /* end of Cudd_bddVarDisjDecomp */

int Cudd_bddVarIsBound ( DdManager dd,
int  index 
)

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

Synopsis [Tells whether a variable can be sifted.]

Description [This function returns 1 if a variable is enabled for sifting. Initially all variables can be sifted. This function returns 0 only if there has been a previous call to Cudd_bddBindVar for that variable not followed by a call to Cudd_bddUnbindVar. The function returns 0 also in the case in which the index of the variable is out of bounds.]

SideEffects [none]

SeeAlso [Cudd_bddBindVar Cudd_bddUnbindVar]

Definition at line 3951 of file cuddAPI.c.

03954 {
03955     if (index >= dd->size || index < 0) return(0);
03956     return(dd->subtables[dd->perm[index]].bindVar);
03957 
03958 } /* end of Cudd_bddVarIsBound */

int Cudd_bddVarIsDependent ( DdManager dd,
DdNode f,
DdNode var 
)

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

Synopsis [Checks whether a variable is dependent on others in a function.]

Description [Checks whether a variable is dependent on others in a function. Returns 1 if the variable is dependent; 0 otherwise. No new nodes are created.]

SideEffects [None]

SeeAlso []

Definition at line 280 of file cuddBddAbs.c.

00284 {
00285     DdNode *F, *res, *zero, *ft, *fe;
00286     unsigned topf, level;
00287     DD_CTFP cacheOp;
00288     int retval;
00289 
00290     zero = Cudd_Not(DD_ONE(dd));
00291     if (Cudd_IsConstant(f)) return(f == zero);
00292 
00293     /* From now on f is not constant. */
00294     F = Cudd_Regular(f);
00295     topf = (unsigned) dd->perm[F->index];
00296     level = (unsigned) dd->perm[var->index];
00297 
00298     /* Check terminal case. If topf > index of var, f does not depend on var.
00299     ** Therefore, var is not dependent in f. */
00300     if (topf > level) {
00301         return(0);
00302     }
00303 
00304     cacheOp = (DD_CTFP) Cudd_bddVarIsDependent;
00305     res = cuddCacheLookup2(dd,cacheOp,f,var);
00306     if (res != NULL) {
00307         return(res != zero);
00308     }
00309 
00310     /* Compute cofactors. */
00311     ft = Cudd_NotCond(cuddT(F), f != F);
00312     fe = Cudd_NotCond(cuddE(F), f != F);
00313 
00314     if (topf == level) {
00315         retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe));
00316     } else {
00317         retval = Cudd_bddVarIsDependent(dd,ft,var) &&
00318             Cudd_bddVarIsDependent(dd,fe,var);
00319     }
00320 
00321     cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval));
00322 
00323     return(retval);
00324 
00325 } /* Cudd_bddVarIsDependent */

DdNode* Cudd_bddVarMap ( DdManager manager,
DdNode f 
)

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

Synopsis [Remaps the variables of a BDD using the default variable map.]

Description [Remaps the variables of a BDD using the default variable map. A typical use of this function is to swap two sets of variables. The variable map must be registered with Cudd_SetVarMap. Returns a pointer to the resulting BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddPermute Cudd_bddSwapVariables Cudd_SetVarMap]

Definition at line 369 of file cuddCompose.c.

00372 {
00373     DdNode *res;
00374 
00375     if (manager->map == NULL) return(NULL);
00376     do {
00377         manager->reordered = 0;
00378         res = cuddBddVarMapRecur(manager, f);
00379     } while (manager->reordered == 1);
00380 
00381     return(res);
00382 
00383 } /* end of Cudd_bddVarMap */

DdNode* Cudd_bddVectorCompose ( DdManager dd,
DdNode f,
DdNode **  vector 
)

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

Synopsis [Composes a BDD with a vector of BDDs.]

Description [Given a vector of BDDs, creates a new BDD by substituting the BDDs for the variables of the BDD f. There should be an entry in vector for each variable in the manager. If no substitution is sought for a given variable, the corresponding projection function should be specified in the vector. This function implements simultaneous composition. Returns a pointer to the resulting BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddPermute Cudd_bddCompose Cudd_addVectorCompose]

Definition at line 787 of file cuddCompose.c.

00791 {
00792     DdHashTable         *table;
00793     DdNode              *res;
00794     int                 deepest;
00795     int                 i;
00796 
00797     do {
00798         dd->reordered = 0;
00799         /* Initialize local cache. */
00800         table = cuddHashTableInit(dd,1,2);
00801         if (table == NULL) return(NULL);
00802 
00803         /* Find deepest real substitution. */
00804         for (deepest = dd->size - 1; deepest >= 0; deepest--) {
00805             i = dd->invperm[deepest];
00806             if (vector[i] != dd->vars[i]) {
00807                 break;
00808             }
00809         }
00810 
00811         /* Recursively solve the problem. */
00812         res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest);
00813         if (res != NULL) cuddRef(res);
00814 
00815         /* Dispose of local cache. */
00816         cuddHashTableQuit(table);
00817     } while (dd->reordered == 1);
00818 
00819     if (res != NULL) cuddDeref(res);
00820     return(res);
00821 
00822 } /* end of Cudd_bddVectorCompose */

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

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

Synopsis [Computes the exclusive NOR of two BDDs f and g.]

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

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor]

Definition at line 503 of file cuddBddIte.c.

00507 {
00508     DdNode *res;
00509 
00510     do {
00511         dd->reordered = 0;
00512         res = cuddBddXorRecur(dd,f,Cudd_Not(g));
00513     } while (dd->reordered == 1);
00514     return(res);
00515 
00516 } /* end of Cudd_bddXnor */

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

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

Synopsis [Computes the exclusive OR of two BDDs f and g.]

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

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXnor]

Definition at line 472 of file cuddBddIte.c.

00476 {
00477     DdNode *res;
00478 
00479     do {
00480         dd->reordered = 0;
00481         res = cuddBddXorRecur(dd,f,g);
00482     } while (dd->reordered == 1);
00483     return(res);
00484 
00485 } /* end of Cudd_bddXor */

DdNode* Cudd_bddXorExistAbstract ( 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_bddUnivAbstract Cudd_bddExistAbstract Cudd_bddAndAbstract]

Definition at line 165 of file cuddBddAbs.c.

00170 {
00171     DdNode *res;
00172 
00173     if (bddCheckPositiveCube(manager, cube) == 0) {
00174         (void) fprintf(manager->err,
00175                        "Error: Can only abstract positive cubes\n");
00176         manager->errorCode = CUDD_INVALID_ARG;
00177         return(NULL);
00178     }
00179 
00180     do {
00181         manager->reordered = 0;
00182         res = cuddBddXorExistAbstractRecur(manager, f, g, cube);
00183     } while (manager->reordered == 1);
00184 
00185     return(res);
00186 
00187 } /* end of Cudd_bddXorExistAbstract */

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

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

Synopsis [Extracts a dense superset from a BDD with the biased underapproximation method.]

Description [Extracts a dense superset from a BDD. The procedure is identical to the underapproximation procedure except for the fact that it works on the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. Returns a pointer to the BDD of the superset if successful. NULL if intermediate result causes the procedure to run out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_RemapOverApprox Cudd_BiasedUnderApprox Cudd_ReadSize]

Definition at line 459 of file cuddApprox.c.

00467 {
00468     DdNode *subset, *g;
00469 
00470     g = Cudd_Not(f);    
00471     do {
00472         dd->reordered = 0;
00473         subset = cuddBiasedUnderApprox(dd, g, b, numVars, threshold, quality1,
00474                                       quality0);
00475     } while (dd->reordered == 1);
00476     
00477     return(Cudd_NotCond(subset, (subset != NULL)));
00478     
00479 } /* end of Cudd_BiasedOverApprox */

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

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

Synopsis [Extracts a dense subset from a BDD with the biased underapproximation method.]

Description [Extracts a dense subset from a BDD. This procedure uses a biased remapping technique and density as the cost function. The bias is a function. This procedure tries to approximate where the bias is 0 and preserve the given function where the bias is 1. Returns a pointer to the BDD of the subset if successful. NULL if the procedure runs out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will cause overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox Cudd_RemapUnderApprox Cudd_ReadSize]

Definition at line 409 of file cuddApprox.c.

00417 {
00418     DdNode *subset;
00419 
00420     do {
00421         dd->reordered = 0;
00422         subset = cuddBiasedUnderApprox(dd, f, b, numVars, threshold, quality1,
00423                                        quality0);
00424     } while (dd->reordered == 1);
00425 
00426     return(subset);
00427 
00428 } /* end of Cudd_BiasedUnderApprox */

int Cudd_CheckKeys ( DdManager table  ) 

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

Synopsis [Checks for several conditions that should not occur.]

Description [Checks for the following conditions:

  • Wrong sizes of subtables.
  • Wrong number of keys found in unique subtable.
  • Wrong number of dead found in unique subtable.
  • Wrong number of keys found in the constant table
  • Wrong number of dead found in the constant table
  • Wrong number of total slots found
  • Wrong number of maximum keys found
  • Wrong number of total dead found

Reports the average length of non-empty lists. Returns the number of subtables for which the number of keys is wrong.]

SideEffects [None]

SeeAlso [Cudd_DebugCheck]

Definition at line 454 of file cuddCheck.c.

00456 {
00457     int size;
00458     int i,j;
00459     DdNodePtr *nodelist;
00460     DdNode *node;
00461     DdNode *sentinel = &(table->sentinel);
00462     DdSubtable *subtable;
00463     int keys;
00464     int dead;
00465     int count = 0;
00466     int totalKeys = 0;
00467     int totalSlots = 0;
00468     int totalDead = 0;
00469     int nonEmpty = 0;
00470     unsigned int slots;
00471     int logSlots;
00472     int shift;
00473 
00474     size = table->size;
00475 
00476     for (i = 0; i < size; i++) {
00477         subtable = &(table->subtables[i]);
00478         nodelist = subtable->nodelist;
00479         keys = subtable->keys;
00480         dead = subtable->dead;
00481         totalKeys += keys;
00482         slots = subtable->slots;
00483         shift = subtable->shift;
00484         logSlots = sizeof(int) * 8 - shift;
00485         if (((slots >> logSlots) << logSlots) != slots) {
00486             (void) fprintf(table->err,
00487                            "Unique table %d is not the right power of 2\n", i);
00488             (void) fprintf(table->err,
00489                            "    slots = %u shift = %d\n", slots, shift);
00490         }
00491         totalSlots += slots;
00492         totalDead += dead;
00493         for (j = 0; (unsigned) j < slots; j++) {
00494             node = nodelist[j];
00495             if (node != sentinel) {
00496                 nonEmpty++;
00497             }
00498             while (node != sentinel) {
00499                 keys--;
00500                 if (node->ref == 0) {
00501                     dead--;
00502                 }
00503                 node = node->next;
00504             }
00505         }
00506         if (keys != 0) {
00507             (void) fprintf(table->err, "Wrong number of keys found \
00508 in unique table %d (difference=%d)\n", i, keys);
00509             count++;
00510         }
00511         if (dead != 0) {
00512             (void) fprintf(table->err, "Wrong number of dead found \
00513 in unique table no. %d (difference=%d)\n", i, dead);
00514         }
00515     }   /* for each BDD/ADD subtable */
00516 
00517     /* Check the ZDD subtables. */
00518     size = table->sizeZ;
00519 
00520     for (i = 0; i < size; i++) {
00521         subtable = &(table->subtableZ[i]);
00522         nodelist = subtable->nodelist;
00523         keys = subtable->keys;
00524         dead = subtable->dead;
00525         totalKeys += keys;
00526         totalSlots += subtable->slots;
00527         totalDead += dead;
00528         for (j = 0; (unsigned) j < subtable->slots; j++) {
00529             node = nodelist[j];
00530             if (node != NULL) {
00531                 nonEmpty++;
00532             }
00533             while (node != NULL) {
00534                 keys--;
00535                 if (node->ref == 0) {
00536                     dead--;
00537                 }
00538                 node = node->next;
00539             }
00540         }
00541         if (keys != 0) {
00542             (void) fprintf(table->err, "Wrong number of keys found \
00543 in ZDD unique table no. %d (difference=%d)\n", i, keys);
00544             count++;
00545         }
00546         if (dead != 0) {
00547             (void) fprintf(table->err, "Wrong number of dead found \
00548 in ZDD unique table no. %d (difference=%d)\n", i, dead);
00549         }
00550     }   /* for each ZDD subtable */
00551 
00552     /* Check the constant table. */
00553     subtable = &(table->constants);
00554     nodelist = subtable->nodelist;
00555     keys = subtable->keys;
00556     dead = subtable->dead;
00557     totalKeys += keys;
00558     totalSlots += subtable->slots;
00559     totalDead += dead;
00560     for (j = 0; (unsigned) j < subtable->slots; j++) {
00561         node = nodelist[j];
00562         if (node != NULL) {
00563             nonEmpty++;
00564         }
00565         while (node != NULL) {
00566             keys--;
00567             if (node->ref == 0) {
00568                 dead--;
00569             }
00570             node = node->next;
00571         }
00572     }
00573     if (keys != 0) {
00574         (void) fprintf(table->err, "Wrong number of keys found \
00575 in the constant table (difference=%d)\n", keys);
00576         count++;
00577     }
00578     if (dead != 0) {
00579         (void) fprintf(table->err, "Wrong number of dead found \
00580 in the constant table (difference=%d)\n", dead);
00581     }
00582     if ((unsigned) totalKeys != table->keys + table->keysZ) {
00583         (void) fprintf(table->err, "Wrong number of total keys found \
00584 (difference=%d)\n", (int) (totalKeys-table->keys));
00585     }
00586     if ((unsigned) totalSlots != table->slots) {
00587         (void) fprintf(table->err, "Wrong number of total slots found \
00588 (difference=%d)\n", (int) (totalSlots-table->slots));
00589     }
00590     if (table->minDead != (unsigned) (table->gcFrac * table->slots)) {
00591         (void) fprintf(table->err, "Wrong number of minimum dead found \
00592 (%u vs. %u)\n", table->minDead,
00593         (unsigned) (table->gcFrac * (double) table->slots));
00594     }
00595     if ((unsigned) totalDead != table->dead + table->deadZ) {
00596         (void) fprintf(table->err, "Wrong number of total dead found \
00597 (difference=%d)\n", (int) (totalDead-table->dead));
00598     }
00599     (void)printf("Average length of non-empty lists = %g\n",
00600     (double) table->keys / (double) nonEmpty);
00601 
00602     return(count);
00603 
00604 } /* end of Cudd_CheckKeys */

int Cudd_CheckZeroRef ( DdManager manager  ) 

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

Synopsis [Checks the unique table for nodes with non-zero reference counts.]

Description [Checks the unique table for nodes with non-zero reference counts. It is normally called before Cudd_Quit to make sure that there are no memory leaks due to missing Cudd_RecursiveDeref's. Takes into account that reference counts may saturate and that the basic constants and the projection functions are referenced by the manager. Returns the number of nodes with non-zero reference count. (Except for the cases mentioned above.)]

SideEffects [None]

SeeAlso []

Definition at line 462 of file cuddRef.c.

00464 {
00465     int size;
00466     int i, j;
00467     int remain; /* the expected number of remaining references to one */
00468     DdNodePtr *nodelist;
00469     DdNode *node;
00470     DdNode *sentinel = &(manager->sentinel);
00471     DdSubtable *subtable;
00472     int count = 0;
00473     int index;
00474 
00475 #ifndef DD_NO_DEATH_ROW
00476     cuddClearDeathRow(manager);
00477 #endif
00478 
00479     /* First look at the BDD/ADD subtables. */
00480     remain = 1; /* reference from the manager */
00481     size = manager->size;
00482     remain += 2 * size; /* reference from the BDD projection functions */
00483 
00484     for (i = 0; i < size; i++) {
00485         subtable = &(manager->subtables[i]);
00486         nodelist = subtable->nodelist;
00487         for (j = 0; (unsigned) j < subtable->slots; j++) {
00488             node = nodelist[j];
00489             while (node != sentinel) {
00490                 if (node->ref != 0 && node->ref != DD_MAXREF) {
00491                     index = (int) node->index;
00492                     if (node != manager->vars[index]) {
00493                         count++;
00494                     } else {
00495                         if (node->ref != 1) {
00496                             count++;
00497                         }
00498                     }
00499                 }
00500                 node = node->next;
00501             }
00502         }
00503     }
00504 
00505     /* Then look at the ZDD subtables. */
00506     size = manager->sizeZ;
00507     if (size) /* references from ZDD universe */
00508         remain += 2;
00509 
00510     for (i = 0; i < size; i++) {
00511         subtable = &(manager->subtableZ[i]);
00512         nodelist = subtable->nodelist;
00513         for (j = 0; (unsigned) j < subtable->slots; j++) {
00514             node = nodelist[j];
00515             while (node != NULL) {
00516                 if (node->ref != 0 && node->ref != DD_MAXREF) {
00517                     index = (int) node->index;
00518                     if (node == manager->univ[manager->permZ[index]]) {
00519                         if (node->ref > 2) {
00520                             count++;
00521                         }
00522                     } else {
00523                         count++;
00524                     }
00525                 }
00526                 node = node->next;
00527             }
00528         }
00529     }
00530 
00531     /* Now examine the constant table. Plusinfinity, minusinfinity, and
00532     ** zero are referenced by the manager. One is referenced by the
00533     ** manager, by the ZDD universe, and by all projection functions.
00534     ** All other nodes should have no references.
00535     */
00536     nodelist = manager->constants.nodelist;
00537     for (j = 0; (unsigned) j < manager->constants.slots; j++) {
00538         node = nodelist[j];
00539         while (node != NULL) {
00540             if (node->ref != 0 && node->ref != DD_MAXREF) {
00541                 if (node == manager->one) {
00542                     if ((int) node->ref != remain) {
00543                         count++;
00544                     }
00545                 } else if (node == manager->zero ||
00546                 node == manager->plusinfinity ||
00547                 node == manager->minusinfinity) {
00548                     if (node->ref != 1) {
00549                         count++;
00550                     }
00551                 } else {
00552                     count++;
00553                 }
00554             }
00555             node = node->next;
00556         }
00557     }
00558     return(count);
00559 
00560 } /* end of Cudd_CheckZeroRef */

int Cudd_ClassifySupport ( DdManager dd,
DdNode f,
DdNode g,
DdNode **  common,
DdNode **  onlyF,
DdNode **  onlyG 
)

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

Synopsis [Classifies the variables in the support of two DDs.]

Description [Classifies the variables in the support of two DDs f and g, depending on whther they appear in both DDs, only in f, or only in g. Returns 1 if successful; 0 otherwise.]

SideEffects [The cubes of the three classes of variables are returned as side effects.]

SeeAlso [Cudd_Support Cudd_VectorSupport]

Definition at line 1081 of file cuddUtil.c.

01088 {
01089     int *supportF, *supportG;
01090     DdNode *tmp, *var;
01091     int i,j;
01092     int size;
01093 
01094     /* Allocate and initialize support arrays for ddSupportStep. */
01095     size = ddMax(dd->size, dd->sizeZ);
01096     supportF = ALLOC(int,size);
01097     if (supportF == NULL) {
01098         dd->errorCode = CUDD_MEMORY_OUT;
01099         return(0);
01100     }
01101     supportG = ALLOC(int,size);
01102     if (supportG == NULL) {
01103         dd->errorCode = CUDD_MEMORY_OUT;
01104         FREE(supportF);
01105         return(0);
01106     }
01107     for (i = 0; i < size; i++) {
01108         supportF[i] = 0;
01109         supportG[i] = 0;
01110     }
01111 
01112     /* Compute supports and clean up markers. */
01113     ddSupportStep(Cudd_Regular(f),supportF);
01114     ddClearFlag(Cudd_Regular(f));
01115     ddSupportStep(Cudd_Regular(g),supportG);
01116     ddClearFlag(Cudd_Regular(g));
01117 
01118     /* Classify variables and create cubes. */
01119     *common = *onlyF = *onlyG = DD_ONE(dd);
01120     cuddRef(*common); cuddRef(*onlyF); cuddRef(*onlyG);
01121     for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */
01122         i = (j >= dd->size) ? j : dd->invperm[j];
01123         if (supportF[i] == 0 && supportG[i] == 0) continue;
01124         var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one));
01125         cuddRef(var);
01126         if (supportG[i] == 0) {
01127             tmp = Cudd_bddAnd(dd,*onlyF,var);
01128             if (tmp == NULL) {
01129                 Cudd_RecursiveDeref(dd,*common);
01130                 Cudd_RecursiveDeref(dd,*onlyF);
01131                 Cudd_RecursiveDeref(dd,*onlyG);
01132                 Cudd_RecursiveDeref(dd,var);
01133                 FREE(supportF); FREE(supportG);
01134                 return(0);
01135             }
01136             cuddRef(tmp);
01137             Cudd_RecursiveDeref(dd,*onlyF);
01138             *onlyF = tmp;
01139         } else if (supportF[i] == 0) {
01140             tmp = Cudd_bddAnd(dd,*onlyG,var);
01141             if (tmp == NULL) {
01142                 Cudd_RecursiveDeref(dd,*common);
01143                 Cudd_RecursiveDeref(dd,*onlyF);
01144                 Cudd_RecursiveDeref(dd,*onlyG);
01145                 Cudd_RecursiveDeref(dd,var);
01146                 FREE(supportF); FREE(supportG);
01147                 return(0);
01148             }
01149             cuddRef(tmp);
01150             Cudd_RecursiveDeref(dd,*onlyG);
01151             *onlyG = tmp;
01152         } else {
01153             tmp = Cudd_bddAnd(dd,*common,var);
01154             if (tmp == NULL) {
01155                 Cudd_RecursiveDeref(dd,*common);
01156                 Cudd_RecursiveDeref(dd,*onlyF);
01157                 Cudd_RecursiveDeref(dd,*onlyG);
01158                 Cudd_RecursiveDeref(dd,var);
01159                 FREE(supportF); FREE(supportG);
01160                 return(0);
01161             }
01162             cuddRef(tmp);
01163             Cudd_RecursiveDeref(dd,*common);
01164             *common = tmp;
01165         }
01166         Cudd_RecursiveDeref(dd,var);
01167     }
01168 
01169     FREE(supportF); FREE(supportG);
01170     cuddDeref(*common); cuddDeref(*onlyF); cuddDeref(*onlyG);
01171     return(1);
01172 
01173 } /* end of Cudd_ClassifySupport */

void Cudd_ClearErrorCode ( DdManager dd  ) 

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

Synopsis [Clear the error code of a manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_ReadErrorCode]

Definition at line 3629 of file cuddAPI.c.

03631 {
03632     dd->errorCode = CUDD_NO_ERROR;
03633 
03634 } /* end of Cudd_ClearErrorCode */

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

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

Synopsis [Computes the cofactor of f with respect to g.]

Description [Computes the cofactor of f with respect to g; g must be the BDD or the ADD of a cube. Returns a pointer to the cofactor if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddConstrain Cudd_bddRestrict]

Definition at line 119 of file cuddCof.c.

00123 {
00124     DdNode *res,*zero;
00125 
00126     zero = Cudd_Not(DD_ONE(dd));
00127     if (g == zero || g == DD_ZERO(dd)) {
00128         (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n");
00129         dd->errorCode = CUDD_INVALID_ARG;
00130         return(NULL);
00131     }
00132     do {
00133         dd->reordered = 0;
00134         res = cuddCofactorRecur(dd,f,g);
00135     } while (dd->reordered == 1);
00136     return(res);
00137 
00138 } /* end of Cudd_Cofactor */

double* Cudd_CofMinterm ( DdManager dd,
DdNode node 
)

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

Synopsis [Computes the fraction of minterms in the on-set of all the positive cofactors of a BDD or ADD.]

Description [Computes the fraction of minterms in the on-set of all the positive cofactors of DD. Returns the pointer to an array of doubles if successful; NULL otherwise. The array has as many positions as there are BDD variables in the manager plus one. The last position of the array contains the fraction of the minterms in the ON-set of the function represented by the BDD or ADD. The other positions of the array hold the variable signatures.]

SideEffects [None]

Definition at line 127 of file cuddSign.c.

00130 {
00131     st_table    *table;
00132     double      *values;
00133     double      *result = NULL;
00134     int         i, firstLevel;
00135 
00136 #ifdef DD_STATS
00137     long startTime;
00138     startTime = util_cpu_time();
00139     num_calls = 0;
00140     table_mem = sizeof(st_table);
00141 #endif
00142 
00143     table = st_init_table(st_ptrcmp, st_ptrhash);
00144     if (table == NULL) {
00145         (void) fprintf(dd->err,
00146                        "out-of-memory, couldn't measure DD cofactors.\n");
00147         dd->errorCode = CUDD_MEMORY_OUT;
00148         return(NULL);
00149     }
00150     size = dd->size;
00151     values = ddCofMintermAux(dd, node, table);
00152     if (values != NULL) {
00153         result = ALLOC(double,size + 1);
00154         if (result != NULL) {
00155 #ifdef DD_STATS
00156             table_mem += (size + 1) * sizeof(double);
00157 #endif
00158             if (Cudd_IsConstant(node))
00159                 firstLevel = 1;
00160             else
00161                 firstLevel = cuddI(dd,Cudd_Regular(node)->index);
00162             for (i = 0; i < size; i++) {
00163                 if (i >= cuddI(dd,Cudd_Regular(node)->index)) {
00164                     result[dd->invperm[i]] = values[i - firstLevel];
00165                 } else {
00166                     result[dd->invperm[i]] = values[size - firstLevel];
00167                 }
00168             }
00169             result[size] = values[size - firstLevel];
00170         } else {
00171             dd->errorCode = CUDD_MEMORY_OUT;
00172         }
00173     }
00174 
00175 #ifdef DD_STATS
00176     table_mem += table->num_bins * sizeof(st_table_entry *);
00177 #endif
00178     if (Cudd_Regular(node)->ref == 1) FREE(values);
00179     st_foreach(table, cuddStCountfree, NULL);
00180     st_free_table(table);
00181 #ifdef DD_STATS
00182     (void) fprintf(dd->out,"Number of calls: %d\tTable memory: %d bytes\n",
00183                   num_calls, table_mem);
00184     (void) fprintf(dd->out,"Time to compute measures: %s\n",
00185                   util_print_time(util_cpu_time() - startTime));
00186 #endif
00187     if (result == NULL) {
00188         (void) fprintf(dd->out,
00189                        "out-of-memory, couldn't measure DD cofactors.\n");
00190         dd->errorCode = CUDD_MEMORY_OUT;
00191     }
00192     return(result);
00193 
00194 } /* end of Cudd_CofMinterm */

int Cudd_CountLeaves ( DdNode node  ) 

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

Synopsis [Counts the number of leaves in a DD.]

Description [Counts the number of leaves in a DD. Returns the number of leaves in the DD rooted at node if successful; CUDD_OUT_OF_MEM otherwise.]

SideEffects [None]

SeeAlso [Cudd_PrintDebug]

Definition at line 1190 of file cuddUtil.c.

01192 {
01193     int i;
01194 
01195     i = ddLeavesInt(Cudd_Regular(node));
01196     ddClearFlag(Cudd_Regular(node));
01197     return(i);
01198 
01199 } /* end of Cudd_CountLeaves */

double Cudd_CountMinterm ( DdManager manager,
DdNode node,
int  nvars 
)

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

Synopsis [Counts the number of minterms of a DD.]

Description [Counts the number of minterms of a DD. The function is assumed to depend on nvars variables. The minterm count is represented as a double, to allow for a larger number of variables. Returns the number of minterms of the function rooted at node if successful; (double) CUDD_OUT_OF_MEM otherwise.]

SideEffects [None]

SeeAlso [Cudd_PrintDebug Cudd_CountPath]

Definition at line 574 of file cuddUtil.c.

00578 {
00579     double      max;
00580     DdHashTable *table;
00581     double      res;
00582     CUDD_VALUE_TYPE epsilon;
00583 
00584     background = manager->background;
00585     zero = Cudd_Not(manager->one);
00586 
00587     max = pow(2.0,(double)nvars);
00588     table = cuddHashTableInit(manager,1,2);
00589     if (table == NULL) {
00590         return((double)CUDD_OUT_OF_MEM);
00591     }
00592     epsilon = Cudd_ReadEpsilon(manager);
00593     Cudd_SetEpsilon(manager,(CUDD_VALUE_TYPE)0.0);
00594     res = ddCountMintermAux(node,max,table);
00595     cuddHashTableQuit(table);
00596     Cudd_SetEpsilon(manager,epsilon);
00597 
00598     return(res);
00599 
00600 } /* end of Cudd_CountMinterm */

double Cudd_CountPath ( DdNode node  ) 

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

Synopsis [Counts the number of paths of a DD.]

Description [Counts the number of paths of a DD. Paths to all terminal nodes are counted. The path count is represented as a double, to allow for a larger number of variables. Returns the number of paths of the function rooted at node if successful; (double) CUDD_OUT_OF_MEM otherwise.]

SideEffects [None]

SeeAlso [Cudd_CountMinterm]

Definition at line 619 of file cuddUtil.c.

00621 {
00622 
00623     st_table    *table;
00624     double      i;
00625 
00626     table = st_init_table(st_ptrcmp,st_ptrhash);
00627     if (table == NULL) {
00628         return((double)CUDD_OUT_OF_MEM);
00629     }
00630     i = ddCountPathAux(Cudd_Regular(node),table);
00631     st_foreach(table, cuddStCountfree, NULL);
00632     st_free_table(table);
00633     return(i);
00634 
00635 } /* end of Cudd_CountPath */

double Cudd_CountPathsToNonZero ( DdNode node  ) 

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

Synopsis [Counts the number of paths to a non-zero terminal of a DD.]

Description [Counts the number of paths to a non-zero terminal of a DD. The path count is represented as a double, to allow for a larger number of variables. Returns the number of paths of the function rooted at node.]

SideEffects [None]

SeeAlso [Cudd_CountMinterm Cudd_CountPath]

Definition at line 703 of file cuddUtil.c.

00705 {
00706 
00707     st_table    *table;
00708     double      i;
00709 
00710     table = st_init_table(st_ptrcmp,st_ptrhash);
00711     if (table == NULL) {
00712         return((double)CUDD_OUT_OF_MEM);
00713     }
00714     i = ddCountPathsToNonZero(node,table);
00715     st_foreach(table, cuddStCountfree, NULL);
00716     st_free_table(table);
00717     return(i);
00718 
00719 } /* end of Cudd_CountPathsToNonZero */

DdNode* Cudd_CProjection ( DdManager dd,
DdNode R,
DdNode Y 
)

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

Synopsis [Computes the compatible projection of R w.r.t. cube Y.]

Description [Computes the compatible projection of relation R with respect to cube Y. Returns a pointer to the c-projection if successful; NULL otherwise. For a comparison between Cudd_CProjection and Cudd_PrioritySelect, see the documentation of the latter.]

SideEffects [None]

SeeAlso [Cudd_PrioritySelect]

Definition at line 1196 of file cuddPriority.c.

01200 {
01201     DdNode *res;
01202     DdNode *support;
01203 
01204     if (cuddCheckCube(dd,Y) == 0) {
01205         (void) fprintf(dd->err,
01206         "Error: The third argument of Cudd_CProjection should be a cube\n");
01207         dd->errorCode = CUDD_INVALID_ARG;
01208         return(NULL);
01209     }
01210 
01211     /* Compute the support of Y, which is used by the abstraction step
01212     ** in cuddCProjectionRecur.
01213     */
01214     support = Cudd_Support(dd,Y);
01215     if (support == NULL) return(NULL);
01216     cuddRef(support);
01217 
01218     do {
01219         dd->reordered = 0;
01220         res = cuddCProjectionRecur(dd,R,Y,support);
01221     } while (dd->reordered == 1);
01222 
01223     if (res == NULL) {
01224         Cudd_RecursiveDeref(dd,support);
01225         return(NULL);
01226     }
01227     cuddRef(res);
01228     Cudd_RecursiveDeref(dd,support);
01229     cuddDeref(res);
01230 
01231     return(res);
01232 
01233 } /* end of Cudd_CProjection */

DdNode* Cudd_CubeArrayToBdd ( DdManager dd,
int *  array 
)

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

Synopsis [Builds the BDD of a cube from a positional array.]

Description [Builds a cube from a positional array. The array must have one integer entry for each BDD variable. If the i-th entry is 1, the variable of index i appears in true form in the cube; If the i-th entry is 0, the variable of index i appears complemented in the cube; otherwise the variable does not appear in the cube. Returns a pointer to the BDD for the cube if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddComputeCube Cudd_IndicesToCube Cudd_BddToCubeArray]

Definition at line 2294 of file cuddUtil.c.

02297 {
02298     DdNode *cube, *var, *tmp;
02299     int i;
02300     int size = Cudd_ReadSize(dd);
02301 
02302     cube = DD_ONE(dd);
02303     cuddRef(cube);
02304     for (i = size - 1; i >= 0; i--) {
02305         if ((array[i] & ~1) == 0) {
02306             var = Cudd_bddIthVar(dd,i);
02307             tmp = Cudd_bddAnd(dd,cube,Cudd_NotCond(var,array[i]==0));
02308             if (tmp == NULL) {
02309                 Cudd_RecursiveDeref(dd,cube);
02310                 return(NULL);
02311             }
02312             cuddRef(tmp);
02313             Cudd_RecursiveDeref(dd,cube);
02314             cube = tmp;
02315         }
02316     }
02317     cuddDeref(cube);
02318     return(cube);
02319 
02320 } /* end of Cudd_CubeArrayToBdd */

int Cudd_DagSize ( DdNode node  ) 

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

Synopsis [Counts the number of nodes in a DD.]

Description [Counts the number of nodes in a DD. Returns the number of nodes in the graph rooted at node.]

SideEffects [None]

SeeAlso [Cudd_SharingSize Cudd_PrintDebug]

Definition at line 438 of file cuddUtil.c.

00440 {
00441     int i;
00442 
00443     i = ddDagInt(Cudd_Regular(node));
00444     ddClearFlag(Cudd_Regular(node));
00445 
00446     return(i);
00447 
00448 } /* end of Cudd_DagSize */

int Cudd_DeadAreCounted ( DdManager dd  ) 

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

Synopsis [Tells whether dead nodes are counted towards triggering reordering.]

Description [Tells whether dead nodes are counted towards triggering reordering. Returns 1 if dead nodes are counted; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_TurnOnCountDead Cudd_TurnOffCountDead]

Definition at line 2581 of file cuddAPI.c.

02583 {
02584     return(dd->countDead == 0 ? 1 : 0);
02585 
02586 } /* end of Cudd_DeadAreCounted */

int Cudd_DebugCheck ( DdManager table  ) 

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

Synopsis [Checks for inconsistencies in the DD heap.]

Description [Checks for inconsistencies in the DD heap:

  • node has illegal index
  • live node has dead children
  • node has illegal Then or Else pointers
  • BDD/ADD node has identical children
  • ZDD node has zero then child
  • wrong number of total nodes
  • wrong number of dead nodes
  • ref count error at node

Returns 0 if no inconsistencies are found; DD_OUT_OF_MEM if there is not enough memory; 1 otherwise.]

SideEffects [None]

SeeAlso [Cudd_CheckKeys]

Definition at line 138 of file cuddCheck.c.

00140 {
00141     unsigned int i;
00142     int         j,count;
00143     int         slots;
00144     DdNodePtr   *nodelist;
00145     DdNode      *f;
00146     DdNode      *sentinel = &(table->sentinel);
00147     st_table    *edgeTable;     /* stores internal ref count for each node */
00148     st_generator        *gen;
00149     int         flag = 0;
00150     int         totalNode;
00151     int         deadNode;
00152     int         index;
00153 
00154 
00155     edgeTable = st_init_table(st_ptrcmp,st_ptrhash);
00156     if (edgeTable == NULL) return(CUDD_OUT_OF_MEM);
00157 
00158     /* Check the BDD/ADD subtables. */
00159     for (i = 0; i < (unsigned) table->size; i++) {
00160         index = table->invperm[i];
00161         if (i != (unsigned) table->perm[index]) {
00162             (void) fprintf(table->err,
00163                            "Permutation corrupted: invperm[%u] = %d\t perm[%d] = %d\n",
00164                            i, index, index, table->perm[index]);
00165         }
00166         nodelist = table->subtables[i].nodelist;
00167         slots = table->subtables[i].slots;
00168 
00169         totalNode = 0;
00170         deadNode = 0;
00171         for (j = 0; j < slots; j++) {   /* for each subtable slot */
00172             f = nodelist[j];
00173             while (f != sentinel) {
00174                 totalNode++;
00175                 if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) {
00176                     if ((int) f->index != index) {
00177                         (void) fprintf(table->err,
00178                                        "Error: node has illegal index\n");
00179                         cuddPrintNode(f,table->err);
00180                         flag = 1;
00181                     }
00182                     if ((unsigned) cuddI(table,cuddT(f)->index) <= i ||
00183                         (unsigned) cuddI(table,Cudd_Regular(cuddE(f))->index)
00184                         <= i) {
00185                         (void) fprintf(table->err,
00186                                        "Error: node has illegal children\n");
00187                         cuddPrintNode(f,table->err);
00188                         flag = 1;
00189                     }
00190                     if (Cudd_Regular(cuddT(f)) != cuddT(f)) {
00191                         (void) fprintf(table->err,
00192                                        "Error: node has illegal form\n");
00193                         cuddPrintNode(f,table->err);
00194                         flag = 1;
00195                     }
00196                     if (cuddT(f) == cuddE(f)) {
00197                         (void) fprintf(table->err,
00198                                        "Error: node has identical children\n");
00199                         cuddPrintNode(f,table->err);
00200                         flag = 1;
00201                     }
00202                     if (cuddT(f)->ref == 0 || Cudd_Regular(cuddE(f))->ref == 0) {
00203                         (void) fprintf(table->err,
00204                                        "Error: live node has dead children\n");
00205                         cuddPrintNode(f,table->err);
00206                         flag =1;
00207                     }
00208                     /* Increment the internal reference count for the
00209                     ** then child of the current node.
00210                     */
00211                     if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) {
00212                         count++;
00213                     } else {
00214                         count = 1;
00215                     }
00216                     if (st_insert(edgeTable,(char *)cuddT(f),
00217                     (char *)(long)count) == ST_OUT_OF_MEM) {
00218                         st_free_table(edgeTable);
00219                         return(CUDD_OUT_OF_MEM);
00220                     }
00221 
00222                     /* Increment the internal reference count for the
00223                     ** else child of the current node.
00224                     */
00225                     if (st_lookup_int(edgeTable,(char *)Cudd_Regular(cuddE(f)),
00226                                       &count)) {
00227                         count++;
00228                     } else {
00229                         count = 1;
00230                     }
00231                     if (st_insert(edgeTable,(char *)Cudd_Regular(cuddE(f)),
00232                     (char *)(long)count) == ST_OUT_OF_MEM) {
00233                         st_free_table(edgeTable);
00234                         return(CUDD_OUT_OF_MEM);
00235                     }
00236                 } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) {
00237                     deadNode++;
00238 #if 0
00239                     debugCheckParent(table,f);
00240 #endif
00241                 } else {
00242                     fprintf(table->err,
00243                             "Error: node has illegal Then or Else pointers\n");
00244                     cuddPrintNode(f,table->err);
00245                     flag = 1;
00246                 }
00247 
00248                 f = f->next;
00249             }   /* for each element of the collision list */
00250         }       /* for each subtable slot */
00251 
00252         if ((unsigned) totalNode != table->subtables[i].keys) {
00253             fprintf(table->err,"Error: wrong number of total nodes\n");
00254             flag = 1;
00255         }
00256         if ((unsigned) deadNode != table->subtables[i].dead) {
00257             fprintf(table->err,"Error: wrong number of dead nodes\n");
00258             flag = 1;
00259         }
00260     }   /* for each BDD/ADD subtable */
00261 
00262     /* Check the ZDD subtables. */
00263     for (i = 0; i < (unsigned) table->sizeZ; i++) {
00264         index = table->invpermZ[i];
00265         if (i != (unsigned) table->permZ[index]) {
00266             (void) fprintf(table->err,
00267                            "Permutation corrupted: invpermZ[%u] = %d\t permZ[%d] = %d in ZDD\n",
00268                            i, index, index, table->permZ[index]);
00269         }
00270         nodelist = table->subtableZ[i].nodelist;
00271         slots = table->subtableZ[i].slots;
00272 
00273         totalNode = 0;
00274         deadNode = 0;
00275         for (j = 0; j < slots; j++) {   /* for each subtable slot */
00276             f = nodelist[j];
00277             while (f != NULL) {
00278                 totalNode++;
00279                 if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) {
00280                     if ((int) f->index != index) {
00281                         (void) fprintf(table->err,
00282                                        "Error: ZDD node has illegal index\n");
00283                         cuddPrintNode(f,table->err);
00284                         flag = 1;
00285                     }
00286                     if (Cudd_IsComplement(cuddT(f)) ||
00287                         Cudd_IsComplement(cuddE(f))) {
00288                         (void) fprintf(table->err,
00289                                        "Error: ZDD node has complemented children\n");
00290                         cuddPrintNode(f,table->err);
00291                         flag = 1;
00292                     }
00293                     if ((unsigned) cuddIZ(table,cuddT(f)->index) <= i ||
00294                     (unsigned) cuddIZ(table,cuddE(f)->index) <= i) {
00295                         (void) fprintf(table->err,
00296                                        "Error: ZDD node has illegal children\n");
00297                         cuddPrintNode(f,table->err);
00298                         cuddPrintNode(cuddT(f),table->err);
00299                         cuddPrintNode(cuddE(f),table->err);
00300                         flag = 1;
00301                     }
00302                     if (cuddT(f) == DD_ZERO(table)) {
00303                         (void) fprintf(table->err,
00304                                        "Error: ZDD node has zero then child\n");
00305                         cuddPrintNode(f,table->err);
00306                         flag = 1;
00307                     }
00308                     if (cuddT(f)->ref == 0 || cuddE(f)->ref == 0) {
00309                         (void) fprintf(table->err,
00310                                        "Error: ZDD live node has dead children\n");
00311                         cuddPrintNode(f,table->err);
00312                         flag =1;
00313                     }
00314                     /* Increment the internal reference count for the
00315                     ** then child of the current node.
00316                     */
00317                     if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) {
00318                         count++;
00319                     } else {
00320                         count = 1;
00321                     }
00322                     if (st_insert(edgeTable,(char *)cuddT(f),
00323                     (char *)(long)count) == ST_OUT_OF_MEM) {
00324                         st_free_table(edgeTable);
00325                         return(CUDD_OUT_OF_MEM);
00326                     }
00327 
00328                     /* Increment the internal reference count for the
00329                     ** else child of the current node.
00330                     */
00331                     if (st_lookup_int(edgeTable,(char *)cuddE(f),&count)) {
00332                         count++;
00333                     } else {
00334                         count = 1;
00335                     }
00336                     if (st_insert(edgeTable,(char *)cuddE(f),
00337                     (char *)(long)count) == ST_OUT_OF_MEM) {
00338                         st_free_table(edgeTable);
00339                         table->errorCode = CUDD_MEMORY_OUT;
00340                         return(CUDD_OUT_OF_MEM);
00341                     }
00342                 } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) {
00343                     deadNode++;
00344 #if 0
00345                     debugCheckParent(table,f);
00346 #endif
00347                 } else {
00348                     fprintf(table->err,
00349                             "Error: ZDD node has illegal Then or Else pointers\n");
00350                     cuddPrintNode(f,table->err);
00351                     flag = 1;
00352                 }
00353 
00354                 f = f->next;
00355             }   /* for each element of the collision list */
00356         }       /* for each subtable slot */
00357 
00358         if ((unsigned) totalNode != table->subtableZ[i].keys) {
00359             fprintf(table->err,
00360                     "Error: wrong number of total nodes in ZDD\n");
00361             flag = 1;
00362         }
00363         if ((unsigned) deadNode != table->subtableZ[i].dead) {
00364             fprintf(table->err,
00365                     "Error: wrong number of dead nodes in ZDD\n");
00366             flag = 1;
00367         }
00368     }   /* for each ZDD subtable */
00369 
00370     /* Check the constant table. */
00371     nodelist = table->constants.nodelist;
00372     slots = table->constants.slots;
00373 
00374     totalNode = 0;
00375     deadNode = 0;
00376     for (j = 0; j < slots; j++) {
00377         f = nodelist[j];
00378         while (f != NULL) {
00379             totalNode++;
00380             if (f->ref != 0) {
00381                 if (f->index != CUDD_CONST_INDEX) {
00382                     fprintf(table->err,"Error: node has illegal index\n");
00383 #if SIZEOF_VOID_P == 8
00384                     fprintf(table->err,
00385                             "       node 0x%lx, id = %u, ref = %u, value = %g\n",
00386                             (ptruint)f,f->index,f->ref,cuddV(f));
00387 #else
00388                     fprintf(table->err,
00389                             "       node 0x%x, id = %hu, ref = %hu, value = %g\n",
00390                             (ptruint)f,f->index,f->ref,cuddV(f));
00391 #endif
00392                     flag = 1;
00393                 }
00394             } else {
00395                 deadNode++;
00396             }
00397             f = f->next;
00398         }
00399     }
00400     if ((unsigned) totalNode != table->constants.keys) {
00401         (void) fprintf(table->err,
00402                        "Error: wrong number of total nodes in constants\n");
00403         flag = 1;
00404     }
00405     if ((unsigned) deadNode != table->constants.dead) {
00406         (void) fprintf(table->err,
00407                        "Error: wrong number of dead nodes in constants\n");
00408         flag = 1;
00409     }
00410     gen = st_init_gen(edgeTable);
00411     while (st_gen(gen, &f, &count)) {
00412         if (count > (int)(f->ref) && f->ref != DD_MAXREF) {
00413 #if SIZEOF_VOID_P == 8
00414             fprintf(table->err,"ref count error at node 0x%lx, count = %d, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f));
00415 #else
00416             fprintf(table->err,"ref count error at node 0x%x, count = %d, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f));
00417 #endif
00418             debugFindParent(table,f);
00419             flag = 1;
00420         }
00421     }
00422     st_free_gen(gen);
00423     st_free_table(edgeTable);
00424 
00425     return (flag);
00426 
00427 } /* end of Cudd_DebugCheck */

DdNode* Cudd_Decreasing ( DdManager dd,
DdNode f,
int  i 
)

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

Synopsis [Determines whether a BDD is negative unate in a variable.]

Description [Determines whether the function represented by BDD f is negative unate (monotonic decreasing) in variable i. Returns the constant one is f is unate and the (logical) constant zero if it is not. This function does not generate any new nodes.]

SideEffects [None]

SeeAlso [Cudd_Increasing]

Definition at line 413 of file cuddSat.c.

00417 {
00418     unsigned int topf, level;
00419     DdNode *F, *fv, *fvn, *res;
00420     DD_CTFP cacheOp;
00421 
00422     statLine(dd);
00423 #ifdef DD_DEBUG
00424     assert(0 <= i && i < dd->size);
00425 #endif
00426 
00427     F = Cudd_Regular(f);
00428     topf = cuddI(dd,F->index);
00429 
00430     /* Check terminal case. If topf > i, f does not depend on var.
00431     ** Therefore, f is unate in i.
00432     */
00433     level = (unsigned) dd->perm[i];
00434     if (topf > level) {
00435         return(DD_ONE(dd));
00436     }
00437 
00438     /* From now on, f is not constant. */
00439 
00440     /* Check cache. */
00441     cacheOp = (DD_CTFP) Cudd_Decreasing;
00442     res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]);
00443     if (res != NULL) {
00444         return(res);
00445     }
00446 
00447     /* Compute cofactors. */
00448     fv = cuddT(F); fvn = cuddE(F);
00449     if (F != f) {
00450         fv = Cudd_Not(fv);
00451         fvn = Cudd_Not(fvn);
00452     }
00453 
00454     if (topf == (unsigned) level) {
00455         /* Special case: if fv is regular, fv(1,...,1) = 1;
00456         ** If in addition fvn is complemented, fvn(1,...,1) = 0.
00457         ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not
00458         ** monotonic decreasing in i.
00459         */
00460         if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) {
00461             return(Cudd_Not(DD_ONE(dd)));
00462         }
00463         res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd));
00464     } else {
00465         res = Cudd_Decreasing(dd,fv,i);
00466         if (res == DD_ONE(dd)) {
00467             res = Cudd_Decreasing(dd,fvn,i);
00468         }
00469     }
00470 
00471     cuddCacheInsert2(dd,cacheOp,f,dd->vars[i],res);
00472     return(res);
00473 
00474 } /* end of Cudd_Decreasing */

void Cudd_DelayedDerefBdd ( DdManager table,
DdNode n 
)

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

Synopsis [Decreases the reference count of BDD node n.]

Description [Enqueues node n for later dereferencing. If the queue is full decreases the reference count of the oldest node N to make room for n. If N dies, recursively decreases the reference counts of its children. It is used to dispose of a BDD that is currently not needed, but may be useful again in the near future. The dereferencing proper is done as in Cudd_IterDerefBdd.]

SideEffects [None]

SeeAlso [Cudd_RecursiveDeref Cudd_IterDerefBdd]

Definition at line 270 of file cuddRef.c.

00273 {
00274     DdNode *N;
00275     int ord;
00276     DdNodePtr *stack;
00277     int SP;
00278 
00279     unsigned int live = table->keys - table->dead;
00280     if (live > table->peakLiveNodes) {
00281         table->peakLiveNodes = live;
00282     }
00283 
00284     n = Cudd_Regular(n);
00285 #ifdef DD_DEBUG
00286     assert(n->ref != 0);
00287 #endif
00288 
00289 #ifdef DD_NO_DEATH_ROW
00290     N = n;
00291 #else
00292     if (cuddIsConstant(n) || n->ref > 1) {
00293 #ifdef DD_DEBUG
00294         assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table)));
00295 #endif
00296         cuddSatDec(n->ref);
00297         return;
00298     }
00299 
00300     N = table->deathRow[table->nextDead];
00301 
00302     if (N != NULL) {
00303 #endif
00304 #ifdef DD_DEBUG
00305         assert(!Cudd_IsComplement(N));
00306 #endif
00307         stack = table->stack;
00308         SP = 1;
00309         do {
00310 #ifdef DD_DEBUG
00311             assert(N->ref != 0);
00312 #endif
00313             if (N->ref == 1) {
00314                 N->ref = 0;
00315                 table->dead++;
00316 #ifdef DD_STATS
00317                 table->nodesDropped++;
00318 #endif
00319                 ord = table->perm[N->index];
00320                 stack[SP++] = Cudd_Regular(cuddE(N));
00321                 table->subtables[ord].dead++;
00322                 N = cuddT(N);
00323             } else {
00324                 cuddSatDec(N->ref);
00325                 N = stack[--SP];
00326             }
00327         } while (SP != 0);
00328 #ifndef DD_NO_DEATH_ROW
00329     }
00330     table->deathRow[table->nextDead] = n;
00331 
00332     /* Udate insertion point. */
00333     table->nextDead++;
00334     table->nextDead &= table->deadMask;
00335 #if 0
00336     if (table->nextDead == table->deathRowDepth) {
00337         if (table->deathRowDepth < table->looseUpTo / 2) {
00338             extern void (*MMoutOfMemory)(long);
00339             void (*saveHandler)(long) = MMoutOfMemory;
00340             DdNodePtr *newRow;
00341             MMoutOfMemory = Cudd_OutOfMem;
00342             newRow = REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth);
00343             MMoutOfMemory = saveHandler;
00344             if (newRow == NULL) {
00345                 table->nextDead = 0;
00346             } else {
00347                 int i;
00348                 table->memused += table->deathRowDepth;
00349                 i = table->deathRowDepth;
00350                 table->deathRowDepth <<= 1;
00351                 for (; i < table->deathRowDepth; i++) {
00352                     newRow[i] = NULL;
00353                 }
00354                 table->deadMask = table->deathRowDepth - 1;
00355                 table->deathRow = newRow;
00356             }
00357         } else {
00358             table->nextDead = 0;
00359         }
00360     }
00361 #endif
00362 #endif
00363 
00364 } /* end of Cudd_DelayedDerefBdd */

double Cudd_Density ( DdManager dd,
DdNode f,
int  nvars 
)

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

Synopsis [Computes the density of a BDD or ADD.]

Description [Computes the density of a BDD or ADD. The density is the ratio of the number of minterms to the number of nodes. If 0 is passed as number of variables, the number of variables existing in the manager is used. Returns the density if successful; (double) CUDD_OUT_OF_MEM otherwise.]

SideEffects [None]

SeeAlso [Cudd_CountMinterm Cudd_DagSize]

Definition at line 2798 of file cuddUtil.c.

02802 {
02803     double minterms;
02804     int nodes;
02805     double density;
02806 
02807     if (nvars == 0) nvars = dd->size;
02808     minterms = Cudd_CountMinterm(dd,f,nvars);
02809     if (minterms == (double) CUDD_OUT_OF_MEM) return(minterms);
02810     nodes = Cudd_DagSize(f);
02811     density = minterms / (double) nodes;
02812     return(density);
02813 
02814 } /* end of Cudd_Density */

void Cudd_Deref ( DdNode node  ) 

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

Synopsis [Decreases the reference count of node.]

Description [Decreases the reference count of node. It is primarily used in recursive procedures to decrease the ref count of a result node before returning it. This accomplishes the goal of removing the protection applied by a previous Cudd_Ref.]

SideEffects [None]

SeeAlso [Cudd_RecursiveDeref Cudd_RecursiveDerefZdd Cudd_Ref]

Definition at line 434 of file cuddRef.c.

00436 {
00437     node = Cudd_Regular(node);
00438     cuddSatDec(node->ref);
00439 
00440 } /* end of Cudd_Deref */

void Cudd_DisableGarbageCollection ( DdManager dd  ) 

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

Synopsis [Disables garbage collection.]

Description [Disables garbage collection. Garbage collection is initially enabled. This function may be called to disable it. However, garbage collection will still occur when a new node must be created and no memory is left, or when garbage collection is required for correctness. (E.g., before reordering.)]

SideEffects [None]

SeeAlso [Cudd_EnableGarbageCollection Cudd_GarbageCollectionEnabled]

Definition at line 2559 of file cuddAPI.c.

02561 {
02562     dd->gcEnabled = 0;
02563 
02564 } /* end of Cudd_DisableGarbageCollection */

int Cudd_DisableReorderingReporting ( DdManager dd  ) 

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

Synopsis [Disables reporting of reordering stats.]

Description [Disables reporting of reordering stats. Returns 1 if successful; 0 otherwise.]

SideEffects [Removes functions from the pre-reordering and post-reordering hooks.]

SeeAlso [Cudd_EnableReorderingReporting Cudd_ReorderingReporting]

Definition at line 3561 of file cuddAPI.c.

03563 {
03564     if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) {
03565         return(0);
03566     }
03567     if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) {
03568         return(0);
03569     }
03570     return(1);
03571 
03572 } /* end of Cudd_DisableReorderingReporting */

DdNode* Cudd_Disequality ( DdManager dd,
int  N,
int  c,
DdNode **  x,
DdNode **  y 
)

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

Synopsis [Generates a BDD for the function x - y != c.]

Description [This function generates a BDD for the function x -y != c. Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. The BDD is built bottom-up. It has a linear number of nodes if the variables are ordered as follows: x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].]

SideEffects [None]

SeeAlso [Cudd_Xgty]

Definition at line 928 of file cuddPriority.c.

00934 {
00935     /* The nodes at level i represent values of the difference that are
00936     ** multiples of 2^i.  We use variables with names starting with k
00937     ** to denote the multipliers of 2^i in such multiples. */
00938     int kTrueLb = c + 1;
00939     int kTrueUb = c - 1;
00940     int kFalse = c;
00941     /* Mask used to compute the ceiling function.  Since we divide by 2^i,
00942     ** we want to know whether the dividend is a multiple of 2^i.  If it is,
00943     ** then ceiling and floor coincide; otherwise, they differ by one. */
00944     int mask = 1;
00945     int i;
00946 
00947     DdNode *f = NULL;           /* the eventual result */
00948     DdNode *one = DD_ONE(dd);
00949     DdNode *zero = Cudd_Not(one);
00950 
00951     /* Two x-labeled nodes are created at most at each iteration.  They are
00952     ** stored, along with their k values, in these variables.  At each level,
00953     ** the old nodes are freed and the new nodes are copied into the old map.
00954     */
00955     DdNode *map[2];
00956     int invalidIndex = 1 << (N-1);
00957     int index[2] = {invalidIndex, invalidIndex};
00958 
00959     /* This should never happen. */
00960     if (N < 0) return(NULL);
00961 
00962     /* If there are no bits, both operands are 0.  The result depends on c. */
00963     if (N == 0) {
00964         if (c != 0) return(one);
00965         else return(zero);
00966     }
00967 
00968     /* The maximum or the minimum difference comparing to c can generate the terminal case */
00969     if ((1 << N) - 1 < c || (-(1 << N) + 1) > c) return(one);
00970 
00971     /* Build the result bottom up. */
00972     for (i = 1; i <= N; i++) {
00973         int kTrueLbLower, kTrueUbLower;
00974         int leftChild, middleChild, rightChild;
00975         DdNode *g0, *g1, *fplus, *fequal, *fminus;
00976         int j;
00977         DdNode *newMap[2];
00978         int newIndex[2];
00979 
00980         kTrueLbLower = kTrueLb;
00981         kTrueUbLower = kTrueUb;
00982         /* kTrueLb = floor((c-1)/2^i) + 2 */
00983         kTrueLb = ((c-1) >> i) + 2;
00984         /* kTrueUb = ceiling((c+1)/2^i) - 2 */
00985         kTrueUb = ((c+1) >> i) + (((c+2) & mask) != 1) - 2;
00986         mask = (mask << 1) | 1;
00987         newIndex[0] = invalidIndex;
00988         newIndex[1] = invalidIndex;
00989 
00990         for (j = kTrueUb + 1; j < kTrueLb; j++) {
00991             /* Skip if node is not reachable from top of BDD. */
00992             if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue;
00993 
00994             /* Find f- */
00995             leftChild = (j << 1) - 1;
00996             if (leftChild >= kTrueLbLower || leftChild <= kTrueUbLower) {
00997                 fminus = one;
00998             } else if (i == 1 && leftChild == kFalse) {
00999                 fminus = zero;
01000             } else {
01001                 assert(leftChild == index[0] || leftChild == index[1]);
01002                 if (leftChild == index[0]) {
01003                     fminus = map[0];
01004                 } else {
01005                     fminus = map[1];
01006                 }
01007             }
01008 
01009             /* Find f= */
01010             middleChild = j << 1;
01011             if (middleChild >= kTrueLbLower || middleChild <= kTrueUbLower) {
01012                 fequal = one;
01013             } else if (i == 1 && middleChild == kFalse) {
01014                 fequal = zero;
01015             } else {
01016                 assert(middleChild == index[0] || middleChild == index[1]);
01017                 if (middleChild == index[0]) {
01018                     fequal = map[0];
01019                 } else {
01020                     fequal = map[1];
01021                 }
01022             }
01023 
01024             /* Find f+ */
01025             rightChild = (j << 1) + 1;
01026             if (rightChild >= kTrueLbLower || rightChild <= kTrueUbLower) {
01027                 fplus = one;
01028             } else if (i == 1 && rightChild == kFalse) {
01029                 fplus = zero;
01030             } else {
01031                 assert(rightChild == index[0] || rightChild == index[1]);
01032                 if (rightChild == index[0]) {
01033                     fplus = map[0];
01034                 } else {
01035                     fplus = map[1];
01036                 }
01037             }
01038 
01039             /* Build new nodes. */
01040             g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus);
01041             if (g1 == NULL) {
01042                 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
01043                 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
01044                 if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]);
01045                 if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]);
01046                 return(NULL);
01047             }
01048             cuddRef(g1);
01049             g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal);
01050             if (g0 == NULL) {
01051                 Cudd_IterDerefBdd(dd, g1);
01052                 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
01053                 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
01054                 if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]);
01055                 if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]);
01056                 return(NULL);
01057             }
01058             cuddRef(g0);
01059             f = Cudd_bddIte(dd, x[N - i], g1, g0);
01060             if (f == NULL) {
01061                 Cudd_IterDerefBdd(dd, g1);
01062                 Cudd_IterDerefBdd(dd, g0);
01063                 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
01064                 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
01065                 if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]);
01066                 if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]);
01067                 return(NULL);
01068             }
01069             cuddRef(f);
01070             Cudd_IterDerefBdd(dd, g1);
01071             Cudd_IterDerefBdd(dd, g0);
01072 
01073             /* Save newly computed node in map. */
01074             assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex);
01075             if (newIndex[0] == invalidIndex) {
01076                 newIndex[0] = j;
01077                 newMap[0] = f;
01078             } else {
01079                 newIndex[1] = j;
01080                 newMap[1] = f;
01081             }
01082         }
01083 
01084         /* Copy new map to map. */
01085         if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
01086         if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
01087         map[0] = newMap[0];
01088         map[1] = newMap[1];
01089         index[0] = newIndex[0];
01090         index[1] = newIndex[1];
01091     }
01092 
01093     cuddDeref(f);
01094     return(f);
01095 
01096 } /* end of Cudd_Disequality */

int Cudd_DumpBlif ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
char *  mname,
FILE *  fp,
int  mv 
)

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

Synopsis [Writes a blif file representing the argument BDDs.]

Description [Writes a blif file representing the argument BDDs as a network of multiplexers. One multiplexer is written for each BDD node. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full, or an ADD with constants different from 0 and 1). Cudd_DumpBlif does not close the file: This is the caller responsibility. Cudd_DumpBlif uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames.]

SideEffects [None]

SeeAlso [Cudd_DumpBlifBody Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm]

Definition at line 132 of file cuddExport.c.

00140              : blif, 1: blif-MV */)
00141 {
00142     DdNode      *support = NULL;
00143     DdNode      *scan;
00144     int         *sorted = NULL;
00145     int         nvars = dd->size;
00146     int         retval;
00147     int         i;
00148 
00149     /* Build a bit array with the support of f. */
00150     sorted = ALLOC(int,nvars);
00151     if (sorted == NULL) {
00152         dd->errorCode = CUDD_MEMORY_OUT;
00153         goto failure;
00154     }
00155     for (i = 0; i < nvars; i++) sorted[i] = 0;
00156 
00157     /* Take the union of the supports of each output function. */
00158     support = Cudd_VectorSupport(dd,f,n);
00159     if (support == NULL) goto failure;
00160     cuddRef(support);
00161     scan = support;
00162     while (!cuddIsConstant(scan)) {
00163         sorted[scan->index] = 1;
00164         scan = cuddT(scan);
00165     }
00166     Cudd_RecursiveDeref(dd,support);
00167     support = NULL; /* so that we do not try to free it in case of failure */
00168 
00169     /* Write the header (.model .inputs .outputs). */
00170     if (mname == NULL) {
00171         retval = fprintf(fp,".model DD\n.inputs");
00172     } else {
00173         retval = fprintf(fp,".model %s\n.inputs",mname);
00174     }
00175     if (retval == EOF) {
00176         FREE(sorted);
00177         return(0);
00178     }
00179 
00180     /* Write the input list by scanning the support array. */
00181     for (i = 0; i < nvars; i++) {
00182         if (sorted[i]) {
00183             if (inames == NULL) {
00184                 retval = fprintf(fp," %d", i);
00185             } else {
00186                 retval = fprintf(fp," %s", inames[i]);
00187             }
00188             if (retval == EOF) goto failure;
00189         }
00190     }
00191     FREE(sorted);
00192     sorted = NULL;
00193 
00194     /* Write the .output line. */
00195     retval = fprintf(fp,"\n.outputs");
00196     if (retval == EOF) goto failure;
00197     for (i = 0; i < n; i++) {
00198         if (onames == NULL) {
00199             retval = fprintf(fp," f%d", i);
00200         } else {
00201             retval = fprintf(fp," %s", onames[i]);
00202         }
00203         if (retval == EOF) goto failure;
00204     }
00205     retval = fprintf(fp,"\n");
00206     if (retval == EOF) goto failure;
00207 
00208     retval = Cudd_DumpBlifBody(dd, n, f, inames, onames, fp, mv);
00209     if (retval == 0) goto failure;
00210 
00211     /* Write trailer and return. */
00212     retval = fprintf(fp,".end\n");
00213     if (retval == EOF) goto failure;
00214 
00215     return(1);
00216 
00217 failure:
00218     if (sorted != NULL) FREE(sorted);
00219     if (support != NULL) Cudd_RecursiveDeref(dd,support);
00220     return(0);
00221 
00222 } /* end of Cudd_DumpBlif */

int Cudd_DumpBlifBody ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
FILE *  fp,
int  mv 
)

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

Synopsis [Writes a blif body representing the argument BDDs.]

Description [Writes a blif body representing the argument BDDs as a network of multiplexers. No header (.model, .inputs, and .outputs) and footer (.end) are produced by this function. One multiplexer is written for each BDD node. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full, or an ADD with constants different from 0 and 1). Cudd_DumpBlifBody does not close the file: This is the caller responsibility. Cudd_DumpBlifBody uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames. This function prints out only .names part.]

SideEffects [None]

SeeAlso [Cudd_DumpBlif Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm]

Definition at line 248 of file cuddExport.c.

00255              : blif, 1: blif-MV */)
00256 {
00257     st_table    *visited = NULL;
00258     int         retval;
00259     int         i;
00260 
00261     /* Initialize symbol table for visited nodes. */
00262     visited = st_init_table(st_ptrcmp, st_ptrhash);
00263     if (visited == NULL) goto failure;
00264 
00265     /* Call the function that really gets the job done. */
00266     for (i = 0; i < n; i++) {
00267         retval = ddDoDumpBlif(dd,Cudd_Regular(f[i]),fp,visited,inames,mv);
00268         if (retval == 0) goto failure;
00269     }
00270 
00271     /* To account for the possible complement on the root,
00272     ** we put either a buffer or an inverter at the output of
00273     ** the multiplexer representing the top node.
00274     */
00275     for (i = 0; i < n; i++) {
00276         if (onames == NULL) {
00277             retval = fprintf(fp,
00278 #if SIZEOF_VOID_P == 8
00279                 ".names %lx f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i);
00280 #else
00281                 ".names %x f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i);
00282 #endif
00283         } else {
00284             retval = fprintf(fp,
00285 #if SIZEOF_VOID_P == 8
00286                 ".names %lx %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]);
00287 #else
00288                 ".names %x %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]);
00289 #endif
00290         }
00291         if (retval == EOF) goto failure;
00292         if (Cudd_IsComplement(f[i])) {
00293             retval = fprintf(fp,"%s0 1\n", mv ? ".def 0\n" : "");
00294         } else {
00295             retval = fprintf(fp,"%s1 1\n", mv ? ".def 0\n" : "");
00296         }
00297         if (retval == EOF) goto failure;
00298     }
00299 
00300     st_free_table(visited);
00301     return(1);
00302 
00303 failure:
00304     if (visited != NULL) st_free_table(visited);
00305     return(0);
00306 
00307 } /* end of Cudd_DumpBlifBody */

int Cudd_DumpDaVinci ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
FILE *  fp 
)

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

Synopsis [Writes a daVinci file representing the argument BDDs.]

Description [Writes a daVinci file representing the argument BDDs. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or file system full). Cudd_DumpDaVinci does not close the file: This is the caller responsibility. Cudd_DumpDaVinci uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames.]

SideEffects [None]

SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDDcal Cudd_DumpFactoredForm]

Definition at line 626 of file cuddExport.c.

00633 {
00634     DdNode        *support = NULL;
00635     DdNode        *scan;
00636     st_table      *visited = NULL;
00637     int           retval;
00638     int           i;
00639     st_generator  *gen;
00640     ptruint       refAddr, diff, mask;
00641 
00642     /* Initialize symbol table for visited nodes. */
00643     visited = st_init_table(st_ptrcmp, st_ptrhash);
00644     if (visited == NULL) goto failure;
00645 
00646     /* Collect all the nodes of this DD in the symbol table. */
00647     for (i = 0; i < n; i++) {
00648         retval = cuddCollectNodes(Cudd_Regular(f[i]),visited);
00649         if (retval == 0) goto failure;
00650     }
00651 
00652     /* Find how many most significant hex digits are identical
00653     ** in the addresses of all the nodes. Build a mask based
00654     ** on this knowledge, so that digits that carry no information
00655     ** will not be printed. This is done in two steps.
00656     **  1. We scan the symbol table to find the bits that differ
00657     **     in at least 2 addresses.
00658     **  2. We choose one of the possible masks. There are 8 possible
00659     **     masks for 32-bit integer, and 16 possible masks for 64-bit
00660     **     integers.
00661     */
00662 
00663     /* Find the bits that are different. */
00664     refAddr = (ptruint) Cudd_Regular(f[0]);
00665     diff = 0;
00666     gen = st_init_gen(visited);
00667     while (st_gen(gen, &scan, NULL)) {
00668         diff |= refAddr ^ (ptruint) scan;
00669     }
00670     st_free_gen(gen);
00671 
00672     /* Choose the mask. */
00673     for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) {
00674         mask = (1 << i) - 1;
00675         if (diff <= mask) break;
00676     }
00677     st_free_table(visited);
00678 
00679     /* Initialize symbol table for visited nodes. */
00680     visited = st_init_table(st_ptrcmp, st_ptrhash);
00681     if (visited == NULL) goto failure;
00682 
00683     retval = fprintf(fp, "[");
00684     if (retval == EOF) goto failure;
00685     /* Call the function that really gets the job done. */
00686     for (i = 0; i < n; i++) {
00687         if (onames == NULL) {
00688             retval = fprintf(fp,
00689                              "l(\"f%d\",n(\"root\",[a(\"OBJECT\",\"f%d\")],",
00690                              i,i);
00691         } else {
00692             retval = fprintf(fp,
00693                              "l(\"%s\",n(\"root\",[a(\"OBJECT\",\"%s\")],",
00694                              onames[i], onames[i]);
00695         }
00696         if (retval == EOF) goto failure;
00697         retval = fprintf(fp, "[e(\"edge\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],",
00698                          Cudd_IsComplement(f[i]) ? "red" : "blue");
00699         if (retval == EOF) goto failure;
00700         retval = ddDoDumpDaVinci(dd,Cudd_Regular(f[i]),fp,visited,inames,mask);
00701         if (retval == 0) goto failure;
00702         retval = fprintf(fp, ")]))%s", i == n-1 ? "" : ",");
00703         if (retval == EOF) goto failure;
00704     }
00705 
00706     /* Write trailer and return. */
00707     retval = fprintf(fp, "]\n");
00708     if (retval == EOF) goto failure;
00709 
00710     st_free_table(visited);
00711     return(1);
00712 
00713 failure:
00714     if (support != NULL) Cudd_RecursiveDeref(dd,support);
00715     if (visited != NULL) st_free_table(visited);
00716     return(0);
00717 
00718 } /* end of Cudd_DumpDaVinci */

int Cudd_DumpDDcal ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
FILE *  fp 
)

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

Synopsis [Writes a DDcal file representing the argument BDDs.]

Description [Writes a DDcal file representing the argument BDDs. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory or file system full). Cudd_DumpDDcal does not close the file: This is the caller responsibility. Cudd_DumpDDcal uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames.]

SideEffects [None]

SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci Cudd_DumpFactoredForm]

Definition at line 740 of file cuddExport.c.

00747 {
00748     DdNode        *support = NULL;
00749     DdNode        *scan;
00750     int           *sorted = NULL;
00751     int           nvars = dd->size;
00752     st_table      *visited = NULL;
00753     int           retval;
00754     int           i;
00755     st_generator  *gen;
00756     ptruint       refAddr, diff, mask;
00757 
00758     /* Initialize symbol table for visited nodes. */
00759     visited = st_init_table(st_ptrcmp, st_ptrhash);
00760     if (visited == NULL) goto failure;
00761 
00762     /* Collect all the nodes of this DD in the symbol table. */
00763     for (i = 0; i < n; i++) {
00764         retval = cuddCollectNodes(Cudd_Regular(f[i]),visited);
00765         if (retval == 0) goto failure;
00766     }
00767 
00768     /* Find how many most significant hex digits are identical
00769     ** in the addresses of all the nodes. Build a mask based
00770     ** on this knowledge, so that digits that carry no information
00771     ** will not be printed. This is done in two steps.
00772     **  1. We scan the symbol table to find the bits that differ
00773     **     in at least 2 addresses.
00774     **  2. We choose one of the possible masks. There are 8 possible
00775     **     masks for 32-bit integer, and 16 possible masks for 64-bit
00776     **     integers.
00777     */
00778 
00779     /* Find the bits that are different. */
00780     refAddr = (ptruint) Cudd_Regular(f[0]);
00781     diff = 0;
00782     gen = st_init_gen(visited);
00783     while (st_gen(gen, &scan, NULL)) {
00784         diff |= refAddr ^ (ptruint) scan;
00785     }
00786     st_free_gen(gen);
00787 
00788     /* Choose the mask. */
00789     for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) {
00790         mask = (1 << i) - 1;
00791         if (diff <= mask) break;
00792     }
00793     st_free_table(visited);
00794 
00795     /* Build a bit array with the support of f. */
00796     sorted = ALLOC(int,nvars);
00797     if (sorted == NULL) {
00798         dd->errorCode = CUDD_MEMORY_OUT;
00799         goto failure;
00800     }
00801     for (i = 0; i < nvars; i++) sorted[i] = 0;
00802 
00803     /* Take the union of the supports of each output function. */
00804     support = Cudd_VectorSupport(dd,f,n);
00805     if (support == NULL) goto failure;
00806     cuddRef(support);
00807     scan = support;
00808     while (!cuddIsConstant(scan)) {
00809         sorted[scan->index] = 1;
00810         scan = cuddT(scan);
00811     }
00812     Cudd_RecursiveDeref(dd,support);
00813     support = NULL; /* so that we do not try to free it in case of failure */
00814     for (i = 0; i < nvars; i++) {
00815         if (sorted[dd->invperm[i]]) {
00816             if (inames == NULL || inames[dd->invperm[i]] == NULL) {
00817                 retval = fprintf(fp,"v%d", dd->invperm[i]);
00818             } else {
00819                 retval = fprintf(fp,"%s", inames[dd->invperm[i]]);
00820             }
00821             if (retval == EOF) goto failure;
00822         }
00823         retval = fprintf(fp,"%s", i == nvars - 1 ? "\n" : " * ");
00824         if (retval == EOF) goto failure;
00825     }
00826     FREE(sorted);
00827     sorted = NULL;
00828 
00829     /* Initialize symbol table for visited nodes. */
00830     visited = st_init_table(st_ptrcmp, st_ptrhash);
00831     if (visited == NULL) goto failure;
00832 
00833     /* Call the function that really gets the job done. */
00834     for (i = 0; i < n; i++) {
00835         retval = ddDoDumpDDcal(dd,Cudd_Regular(f[i]),fp,visited,inames,mask);
00836         if (retval == 0) goto failure;
00837         if (onames == NULL) {
00838             retval = fprintf(fp, "f%d = ", i);
00839         } else {
00840             retval = fprintf(fp, "%s = ", onames[i]);
00841         }
00842         if (retval == EOF) goto failure;
00843         retval = fprintf(fp, "n%p%s\n",
00844                          (void *) (((ptruint) f[i] & mask) /
00845                          (ptruint) sizeof(DdNode)),
00846                          Cudd_IsComplement(f[i]) ? "'" : "");
00847         if (retval == EOF) goto failure;
00848     }
00849 
00850     /* Write trailer and return. */
00851     retval = fprintf(fp, "[");
00852     if (retval == EOF) goto failure;
00853     for (i = 0; i < n; i++) {
00854         if (onames == NULL) {
00855             retval = fprintf(fp, "f%d", i);
00856         } else {
00857             retval = fprintf(fp, "%s", onames[i]);
00858         }
00859         retval = fprintf(fp, "%s", i == n-1 ? "" : " ");
00860         if (retval == EOF) goto failure;
00861     }
00862     retval = fprintf(fp, "]\n");
00863     if (retval == EOF) goto failure;
00864 
00865     st_free_table(visited);
00866     return(1);
00867 
00868 failure:
00869     if (sorted != NULL) FREE(sorted);
00870     if (support != NULL) Cudd_RecursiveDeref(dd,support);
00871     if (visited != NULL) st_free_table(visited);
00872     return(0);
00873 
00874 } /* end of Cudd_DumpDDcal */

int Cudd_DumpDot ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
FILE *  fp 
)

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

Synopsis [Writes a dot file representing the argument DDs.]

Description [Writes a file representing the argument DDs in a format suitable for the graph drawing program dot. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full). Cudd_DumpDot does not close the file: This is the caller responsibility. Cudd_DumpDot uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames. Cudd_DumpDot uses the following convention to draw arcs:

  • solid line: THEN arcs;
  • dotted line: complement arcs;
  • dashed line: regular ELSE arcs.

The dot options are chosen so that the drawing fits on a letter-size sheet. ]

SideEffects [None]

SeeAlso [Cudd_DumpBlif Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm]

Definition at line 340 of file cuddExport.c.

00347 {
00348     DdNode      *support = NULL;
00349     DdNode      *scan;
00350     int         *sorted = NULL;
00351     int         nvars = dd->size;
00352     st_table    *visited = NULL;
00353     st_generator *gen = NULL;
00354     int         retval;
00355     int         i, j;
00356     int         slots;
00357     DdNodePtr   *nodelist;
00358     long        refAddr, diff, mask;
00359 
00360     /* Build a bit array with the support of f. */
00361     sorted = ALLOC(int,nvars);
00362     if (sorted == NULL) {
00363         dd->errorCode = CUDD_MEMORY_OUT;
00364         goto failure;
00365     }
00366     for (i = 0; i < nvars; i++) sorted[i] = 0;
00367 
00368     /* Take the union of the supports of each output function. */
00369     support = Cudd_VectorSupport(dd,f,n);
00370     if (support == NULL) goto failure;
00371     cuddRef(support);
00372     scan = support;
00373     while (!cuddIsConstant(scan)) {
00374         sorted[scan->index] = 1;
00375         scan = cuddT(scan);
00376     }
00377     Cudd_RecursiveDeref(dd,support);
00378     support = NULL; /* so that we do not try to free it in case of failure */
00379 
00380     /* Initialize symbol table for visited nodes. */
00381     visited = st_init_table(st_ptrcmp, st_ptrhash);
00382     if (visited == NULL) goto failure;
00383 
00384     /* Collect all the nodes of this DD in the symbol table. */
00385     for (i = 0; i < n; i++) {
00386         retval = cuddCollectNodes(Cudd_Regular(f[i]),visited);
00387         if (retval == 0) goto failure;
00388     }
00389 
00390     /* Find how many most significant hex digits are identical
00391     ** in the addresses of all the nodes. Build a mask based
00392     ** on this knowledge, so that digits that carry no information
00393     ** will not be printed. This is done in two steps.
00394     **  1. We scan the symbol table to find the bits that differ
00395     **     in at least 2 addresses.
00396     **  2. We choose one of the possible masks. There are 8 possible
00397     **     masks for 32-bit integer, and 16 possible masks for 64-bit
00398     **     integers.
00399     */
00400 
00401     /* Find the bits that are different. */
00402     refAddr = (long) Cudd_Regular(f[0]);
00403     diff = 0;
00404     gen = st_init_gen(visited);
00405     if (gen == NULL) goto failure;
00406     while (st_gen(gen, &scan, NULL)) {
00407         diff |= refAddr ^ (long) scan;
00408     }
00409     st_free_gen(gen); gen = NULL;
00410 
00411     /* Choose the mask. */
00412     for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) {
00413         mask = (1 << i) - 1;
00414         if (diff <= mask) break;
00415     }
00416 
00417     /* Write the header and the global attributes. */
00418     retval = fprintf(fp,"digraph \"DD\" {\n");
00419     if (retval == EOF) return(0);
00420     retval = fprintf(fp,
00421         "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n");
00422     if (retval == EOF) return(0);
00423 
00424     /* Write the input name subgraph by scanning the support array. */
00425     retval = fprintf(fp,"{ node [shape = plaintext];\n");
00426     if (retval == EOF) goto failure;
00427     retval = fprintf(fp,"  edge [style = invis];\n");
00428     if (retval == EOF) goto failure;
00429     /* We use a name ("CONST NODES") with an embedded blank, because
00430     ** it is unlikely to appear as an input name.
00431     */
00432     retval = fprintf(fp,"  \"CONST NODES\" [style = invis];\n");
00433     if (retval == EOF) goto failure;
00434     for (i = 0; i < nvars; i++) {
00435         if (sorted[dd->invperm[i]]) {
00436             if (inames == NULL || inames[dd->invperm[i]] == NULL) {
00437                 retval = fprintf(fp,"\" %d \" -> ", dd->invperm[i]);
00438             } else {
00439                 retval = fprintf(fp,"\" %s \" -> ", inames[dd->invperm[i]]);
00440             }
00441             if (retval == EOF) goto failure;
00442         }
00443     }
00444     retval = fprintf(fp,"\"CONST NODES\"; \n}\n");
00445     if (retval == EOF) goto failure;
00446 
00447     /* Write the output node subgraph. */
00448     retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n");
00449     if (retval == EOF) goto failure;
00450     for (i = 0; i < n; i++) {
00451         if (onames == NULL) {
00452             retval = fprintf(fp,"\"F%d\"", i);
00453         } else {
00454             retval = fprintf(fp,"\"  %s  \"", onames[i]);
00455         }
00456         if (retval == EOF) goto failure;
00457         if (i == n - 1) {
00458             retval = fprintf(fp,"; }\n");
00459         } else {
00460             retval = fprintf(fp," -> ");
00461         }
00462         if (retval == EOF) goto failure;
00463     }
00464 
00465     /* Write rank info: All nodes with the same index have the same rank. */
00466     for (i = 0; i < nvars; i++) {
00467         if (sorted[dd->invperm[i]]) {
00468             retval = fprintf(fp,"{ rank = same; ");
00469             if (retval == EOF) goto failure;
00470             if (inames == NULL || inames[dd->invperm[i]] == NULL) {
00471                 retval = fprintf(fp,"\" %d \";\n", dd->invperm[i]);
00472             } else {
00473                 retval = fprintf(fp,"\" %s \";\n", inames[dd->invperm[i]]);
00474             }
00475             if (retval == EOF) goto failure;
00476             nodelist = dd->subtables[i].nodelist;
00477             slots = dd->subtables[i].slots;
00478             for (j = 0; j < slots; j++) {
00479                 scan = nodelist[j];
00480                 while (scan != NULL) {
00481                     if (st_is_member(visited,(char *) scan)) {
00482                         retval = fprintf(fp,"\"%p\";\n",
00483                             (void *) ((mask & (ptrint) scan) /
00484                             sizeof(DdNode)));
00485                         if (retval == EOF) goto failure;
00486                     }
00487                     scan = scan->next;
00488                 }
00489             }
00490             retval = fprintf(fp,"}\n");
00491             if (retval == EOF) goto failure;
00492         }
00493     }
00494 
00495     /* All constants have the same rank. */
00496     retval = fprintf(fp,
00497         "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; ");
00498     if (retval == EOF) goto failure;
00499     nodelist = dd->constants.nodelist;
00500     slots = dd->constants.slots;
00501     for (j = 0; j < slots; j++) {
00502         scan = nodelist[j];
00503         while (scan != NULL) {
00504             if (st_is_member(visited,(char *) scan)) {
00505                 retval = fprintf(fp,"\"%p\";\n",
00506                     (void *) ((mask & (ptrint) scan) / sizeof(DdNode)));
00507                 if (retval == EOF) goto failure;
00508             }
00509             scan = scan->next;
00510         }
00511     }
00512     retval = fprintf(fp,"}\n}\n");
00513     if (retval == EOF) goto failure;
00514 
00515     /* Write edge info. */
00516     /* Edges from the output nodes. */
00517     for (i = 0; i < n; i++) {
00518         if (onames == NULL) {
00519             retval = fprintf(fp,"\"F%d\"", i);
00520         } else {
00521             retval = fprintf(fp,"\"  %s  \"", onames[i]);
00522         }
00523         if (retval == EOF) goto failure;
00524         /* Account for the possible complement on the root. */
00525         if (Cudd_IsComplement(f[i])) {
00526             retval = fprintf(fp," -> \"%p\" [style = dotted];\n",
00527                 (void *) ((mask & (ptrint) f[i]) / sizeof(DdNode)));
00528         } else {
00529             retval = fprintf(fp," -> \"%p\" [style = solid];\n",
00530                 (void *) ((mask & (ptrint) f[i]) / sizeof(DdNode)));
00531         }
00532         if (retval == EOF) goto failure;
00533     }
00534 
00535     /* Edges from internal nodes. */
00536     for (i = 0; i < nvars; i++) {
00537         if (sorted[dd->invperm[i]]) {
00538             nodelist = dd->subtables[i].nodelist;
00539             slots = dd->subtables[i].slots;
00540             for (j = 0; j < slots; j++) {
00541                 scan = nodelist[j];
00542                 while (scan != NULL) {
00543                     if (st_is_member(visited,(char *) scan)) {
00544                         retval = fprintf(fp,
00545                             "\"%p\" -> \"%p\";\n",
00546                             (void *) ((mask & (ptrint) scan) /
00547                             sizeof(DdNode)),
00548                             (void *) ((mask & (ptrint) cuddT(scan)) /
00549                             sizeof(DdNode)));
00550                         if (retval == EOF) goto failure;
00551                         if (Cudd_IsComplement(cuddE(scan))) {
00552                             retval = fprintf(fp,
00553                                 "\"%p\" -> \"%p\" [style = dotted];\n",
00554                                 (void *) ((mask & (ptrint) scan) /
00555                                 sizeof(DdNode)),
00556                                 (void *) ((mask & (ptrint) cuddE(scan)) /
00557                                 sizeof(DdNode)));
00558                         } else {
00559                             retval = fprintf(fp,
00560                                 "\"%p\" -> \"%p\" [style = dashed];\n",
00561                                 (void *) ((mask & (ptrint) scan) /
00562                                 sizeof(DdNode)),
00563                                 (void *) ((mask & (ptrint) cuddE(scan)) /
00564                                 sizeof(DdNode)));
00565                         }
00566                         if (retval == EOF) goto failure;
00567                     }
00568                     scan = scan->next;
00569                 }
00570             }
00571         }
00572     }
00573 
00574     /* Write constant labels. */
00575     nodelist = dd->constants.nodelist;
00576     slots = dd->constants.slots;
00577     for (j = 0; j < slots; j++) {
00578         scan = nodelist[j];
00579         while (scan != NULL) {
00580             if (st_is_member(visited,(char *) scan)) {
00581                 retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n",
00582                     (void *) ((mask & (ptrint) scan) / sizeof(DdNode)),
00583                     cuddV(scan));
00584                 if (retval == EOF) goto failure;
00585             }
00586             scan = scan->next;
00587         }
00588     }
00589 
00590     /* Write trailer and return. */
00591     retval = fprintf(fp,"}\n");
00592     if (retval == EOF) goto failure;
00593 
00594     st_free_table(visited);
00595     FREE(sorted);
00596     return(1);
00597 
00598 failure:
00599     if (sorted != NULL) FREE(sorted);
00600     if (support != NULL) Cudd_RecursiveDeref(dd,support);
00601     if (visited != NULL) st_free_table(visited);
00602     return(0);
00603 
00604 } /* end of Cudd_DumpDot */

int Cudd_DumpFactoredForm ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
FILE *  fp 
)

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

Synopsis [Writes factored forms representing the argument BDDs.]

Description [Writes factored forms representing the argument BDDs. The format of the factored form is the one used in the genlib files for technology mapping in sis. It returns 1 in case of success; 0 otherwise (e.g., file system full). Cudd_DumpFactoredForm does not close the file: This is the caller responsibility. Caution must be exercised because a factored form may be exponentially larger than the argument BDD. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames.]

SideEffects [None]

SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpBlif Cudd_DumpDaVinci Cudd_DumpDDcal]

Definition at line 898 of file cuddExport.c.

00905 {
00906     int         retval;
00907     int         i;
00908 
00909     /* Call the function that really gets the job done. */
00910     for (i = 0; i < n; i++) {
00911         if (onames == NULL) {
00912             retval = fprintf(fp, "f%d = ", i);
00913         } else {
00914             retval = fprintf(fp, "%s = ", onames[i]);
00915         }
00916         if (retval == EOF) return(0);
00917         if (f[i] == DD_ONE(dd)) {
00918             retval = fprintf(fp, "CONST1");
00919             if (retval == EOF) return(0);
00920         } else if (f[i] == Cudd_Not(DD_ONE(dd)) || f[i] == DD_ZERO(dd)) {
00921             retval = fprintf(fp, "CONST0");
00922             if (retval == EOF) return(0);
00923         } else {
00924             retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? "!(" : "");
00925             if (retval == EOF) return(0);
00926             retval = ddDoDumpFactoredForm(dd,Cudd_Regular(f[i]),fp,inames);
00927             if (retval == 0) return(0);
00928             retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? ")" : "");
00929             if (retval == EOF) return(0);
00930         }
00931         retval = fprintf(fp, "%s", i == n-1 ? "" : "\n");
00932         if (retval == EOF) return(0);
00933     }
00934 
00935     return(1);
00936 
00937 } /* end of Cudd_DumpFactoredForm */

DdNode* Cudd_Dxygtdxz ( DdManager dd,
int  N,
DdNode **  x,
DdNode **  y,
DdNode **  z 
)

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

Synopsis [Generates a BDD for the function d(x,y) > d(x,z).]

Description [This function generates a BDD for the function d(x,y) > d(x,z); x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\], y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\], with 0 the most significant bit. The distance d(x,y) is defined as: {i=0}^{N-1}(|x_i - y_i| 2^{N-i-1}). The BDD is built bottom-up. It has 7*N-3 internal nodes, if the variables are ordered as follows: x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ]

SideEffects [None]

SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdyz Cudd_Xgty Cudd_bddAdjPermuteX]

Definition at line 490 of file cuddPriority.c.

00496 {
00497     DdNode *one, *zero;
00498     DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1;
00499     int     i;
00500 
00501     one = DD_ONE(dd);
00502     zero = Cudd_Not(one);
00503 
00504     /* Build bottom part of BDD outside loop. */
00505     y1_ = Cudd_bddIte(dd, y[N-1], one, Cudd_Not(z[N-1]));
00506     if (y1_ == NULL) return(NULL);
00507     cuddRef(y1_);
00508     y2 = Cudd_bddIte(dd, y[N-1], z[N-1], one);
00509     if (y2 == NULL) {
00510         Cudd_RecursiveDeref(dd, y1_);
00511         return(NULL);
00512     }
00513     cuddRef(y2);
00514     x1 = Cudd_bddIte(dd, x[N-1], y1_, y2);
00515     if (x1 == NULL) {
00516         Cudd_RecursiveDeref(dd, y1_);
00517         Cudd_RecursiveDeref(dd, y2);
00518         return(NULL);
00519     }
00520     cuddRef(x1);
00521     Cudd_RecursiveDeref(dd, y1_);
00522     Cudd_RecursiveDeref(dd, y2);
00523 
00524     /* Loop to build the rest of the BDD. */
00525     for (i = N-2; i >= 0; i--) {
00526         z1 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1));
00527         if (z1 == NULL) {
00528             Cudd_RecursiveDeref(dd, x1);
00529             return(NULL);
00530         }
00531         cuddRef(z1);
00532         z2 = Cudd_bddIte(dd, z[i], x1, one);
00533         if (z2 == NULL) {
00534             Cudd_RecursiveDeref(dd, x1);
00535             Cudd_RecursiveDeref(dd, z1);
00536             return(NULL);
00537         }
00538         cuddRef(z2);
00539         z3 = Cudd_bddIte(dd, z[i], one, x1);
00540         if (z3 == NULL) {
00541             Cudd_RecursiveDeref(dd, x1);
00542             Cudd_RecursiveDeref(dd, z1);
00543             Cudd_RecursiveDeref(dd, z2);
00544             return(NULL);
00545         }
00546         cuddRef(z3);
00547         z4 = Cudd_bddIte(dd, z[i], x1, zero);
00548         if (z4 == NULL) {
00549             Cudd_RecursiveDeref(dd, x1);
00550             Cudd_RecursiveDeref(dd, z1);
00551             Cudd_RecursiveDeref(dd, z2);
00552             Cudd_RecursiveDeref(dd, z3);
00553             return(NULL);
00554         }
00555         cuddRef(z4);
00556         Cudd_RecursiveDeref(dd, x1);
00557         y1_ = Cudd_bddIte(dd, y[i], z2, Cudd_Not(z1));
00558         if (y1_ == NULL) {
00559             Cudd_RecursiveDeref(dd, z1);
00560             Cudd_RecursiveDeref(dd, z2);
00561             Cudd_RecursiveDeref(dd, z3);
00562             Cudd_RecursiveDeref(dd, z4);
00563             return(NULL);
00564         }
00565         cuddRef(y1_);
00566         y2 = Cudd_bddIte(dd, y[i], z4, z3);
00567         if (y2 == NULL) {
00568             Cudd_RecursiveDeref(dd, z1);
00569             Cudd_RecursiveDeref(dd, z2);
00570             Cudd_RecursiveDeref(dd, z3);
00571             Cudd_RecursiveDeref(dd, z4);
00572             Cudd_RecursiveDeref(dd, y1_);
00573             return(NULL);
00574         }
00575         cuddRef(y2);
00576         Cudd_RecursiveDeref(dd, z1);
00577         Cudd_RecursiveDeref(dd, z2);
00578         Cudd_RecursiveDeref(dd, z3);
00579         Cudd_RecursiveDeref(dd, z4);
00580         x1 = Cudd_bddIte(dd, x[i], y1_, y2);
00581         if (x1 == NULL) {
00582             Cudd_RecursiveDeref(dd, y1_);
00583             Cudd_RecursiveDeref(dd, y2);
00584             return(NULL);
00585         }
00586         cuddRef(x1);
00587         Cudd_RecursiveDeref(dd, y1_);
00588         Cudd_RecursiveDeref(dd, y2);
00589     }
00590     cuddDeref(x1);
00591     return(Cudd_Not(x1));
00592 
00593 } /* end of Cudd_Dxygtdxz */

DdNode* Cudd_Dxygtdyz ( DdManager dd,
int  N,
DdNode **  x,
DdNode **  y,
DdNode **  z 
)

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

Synopsis [Generates a BDD for the function d(x,y) > d(y,z).]

Description [This function generates a BDD for the function d(x,y) > d(y,z); x, y, and z are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\], y\[0\] y\[1\] ... y\[N-1\], and z\[0\] z\[1\] ... z\[N-1\], with 0 the most significant bit. The distance d(x,y) is defined as: {i=0}^{N-1}(|x_i - y_i| 2^{N-i-1}). The BDD is built bottom-up. It has 7*N-3 internal nodes, if the variables are ordered as follows: x\[0\] y\[0\] z\[0\] x\[1\] y\[1\] z\[1\] ... x\[N-1\] y\[N-1\] z\[N-1\]. ]

SideEffects [None]

SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Xgty Cudd_bddAdjPermuteX]

Definition at line 617 of file cuddPriority.c.

00623 {
00624     DdNode *one, *zero;
00625     DdNode *z1, *z2, *z3, *z4, *y1_, *y2, *x1;
00626     int     i;
00627 
00628     one = DD_ONE(dd);
00629     zero = Cudd_Not(one);
00630 
00631     /* Build bottom part of BDD outside loop. */
00632     y1_ = Cudd_bddIte(dd, y[N-1], one, z[N-1]);
00633     if (y1_ == NULL) return(NULL);
00634     cuddRef(y1_);
00635     y2 = Cudd_bddIte(dd, y[N-1], z[N-1], zero);
00636     if (y2 == NULL) {
00637         Cudd_RecursiveDeref(dd, y1_);
00638         return(NULL);
00639     }
00640     cuddRef(y2);
00641     x1 = Cudd_bddIte(dd, x[N-1], y1_, Cudd_Not(y2));
00642     if (x1 == NULL) {
00643         Cudd_RecursiveDeref(dd, y1_);
00644         Cudd_RecursiveDeref(dd, y2);
00645         return(NULL);
00646     }
00647     cuddRef(x1);
00648     Cudd_RecursiveDeref(dd, y1_);
00649     Cudd_RecursiveDeref(dd, y2);
00650 
00651     /* Loop to build the rest of the BDD. */
00652     for (i = N-2; i >= 0; i--) {
00653         z1 = Cudd_bddIte(dd, z[i], x1, zero);
00654         if (z1 == NULL) {
00655             Cudd_RecursiveDeref(dd, x1);
00656             return(NULL);
00657         }
00658         cuddRef(z1);
00659         z2 = Cudd_bddIte(dd, z[i], x1, one);
00660         if (z2 == NULL) {
00661             Cudd_RecursiveDeref(dd, x1);
00662             Cudd_RecursiveDeref(dd, z1);
00663             return(NULL);
00664         }
00665         cuddRef(z2);
00666         z3 = Cudd_bddIte(dd, z[i], one, x1);
00667         if (z3 == NULL) {
00668             Cudd_RecursiveDeref(dd, x1);
00669             Cudd_RecursiveDeref(dd, z1);
00670             Cudd_RecursiveDeref(dd, z2);
00671             return(NULL);
00672         }
00673         cuddRef(z3);
00674         z4 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1));
00675         if (z4 == NULL) {
00676             Cudd_RecursiveDeref(dd, x1);
00677             Cudd_RecursiveDeref(dd, z1);
00678             Cudd_RecursiveDeref(dd, z2);
00679             Cudd_RecursiveDeref(dd, z3);
00680             return(NULL);
00681         }
00682         cuddRef(z4);
00683         Cudd_RecursiveDeref(dd, x1);
00684         y1_ = Cudd_bddIte(dd, y[i], z2, z1);
00685         if (y1_ == NULL) {
00686             Cudd_RecursiveDeref(dd, z1);
00687             Cudd_RecursiveDeref(dd, z2);
00688             Cudd_RecursiveDeref(dd, z3);
00689             Cudd_RecursiveDeref(dd, z4);
00690             return(NULL);
00691         }
00692         cuddRef(y1_);
00693         y2 = Cudd_bddIte(dd, y[i], z4, Cudd_Not(z3));
00694         if (y2 == NULL) {
00695             Cudd_RecursiveDeref(dd, z1);
00696             Cudd_RecursiveDeref(dd, z2);
00697             Cudd_RecursiveDeref(dd, z3);
00698             Cudd_RecursiveDeref(dd, z4);
00699             Cudd_RecursiveDeref(dd, y1_);
00700             return(NULL);
00701         }
00702         cuddRef(y2);
00703         Cudd_RecursiveDeref(dd, z1);
00704         Cudd_RecursiveDeref(dd, z2);
00705         Cudd_RecursiveDeref(dd, z3);
00706         Cudd_RecursiveDeref(dd, z4);
00707         x1 = Cudd_bddIte(dd, x[i], y1_, Cudd_Not(y2));
00708         if (x1 == NULL) {
00709             Cudd_RecursiveDeref(dd, y1_);
00710             Cudd_RecursiveDeref(dd, y2);
00711             return(NULL);
00712         }
00713         cuddRef(x1);
00714         Cudd_RecursiveDeref(dd, y1_);
00715         Cudd_RecursiveDeref(dd, y2);
00716     }
00717     cuddDeref(x1);
00718     return(Cudd_Not(x1));
00719 
00720 } /* end of Cudd_Dxygtdyz */

void Cudd_EnableGarbageCollection ( DdManager dd  ) 

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

Synopsis [Enables garbage collection.]

Description [Enables garbage collection. Garbage collection is initially enabled. Therefore it is necessary to call this function only if garbage collection has been explicitly disabled.]

SideEffects [None]

SeeAlso [Cudd_DisableGarbageCollection Cudd_GarbageCollectionEnabled]

Definition at line 2535 of file cuddAPI.c.

02537 {
02538     dd->gcEnabled = 1;
02539 
02540 } /* end of Cudd_EnableGarbageCollection */

int Cudd_EnableReorderingReporting ( DdManager dd  ) 

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

Synopsis [Enables reporting of reordering stats.]

Description [Enables reporting of reordering stats. Returns 1 if successful; 0 otherwise.]

SideEffects [Installs functions in the pre-reordering and post-reordering hooks.]

SeeAlso [Cudd_DisableReorderingReporting Cudd_ReorderingReporting]

Definition at line 3533 of file cuddAPI.c.

03535 {
03536     if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) {
03537         return(0);
03538     }
03539     if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) {
03540         return(0);
03541     }
03542     return(1);
03543 
03544 } /* end of Cudd_EnableReorderingReporting */

int Cudd_EpdCountMinterm ( DdManager manager,
DdNode node,
int  nvars,
EpDouble epd 
)

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

Synopsis [Counts the number of minterms of a DD with extended precision.]

Description [Counts the number of minterms of a DD with extended precision. The function is assumed to depend on nvars variables. The minterm count is represented as an EpDouble, to allow any number of variables. Returns 0 if successful; CUDD_OUT_OF_MEM otherwise.]

SideEffects [None]

SeeAlso [Cudd_PrintDebug Cudd_CountPath]

Definition at line 653 of file cuddUtil.c.

00658 {
00659     EpDouble    max, tmp;
00660     st_table    *table;
00661     int         status;
00662 
00663     background = manager->background;
00664     zero = Cudd_Not(manager->one);
00665 
00666     EpdPow2(nvars, &max);
00667     table = st_init_table(EpdCmp, st_ptrhash);
00668     if (table == NULL) {
00669         EpdMakeZero(epd, 0);
00670         return(CUDD_OUT_OF_MEM);
00671     }
00672     status = ddEpdCountMintermAux(Cudd_Regular(node),&max,epd,table);
00673     st_foreach(table, ddEpdFree, NULL);
00674     st_free_table(table);
00675     if (status == CUDD_OUT_OF_MEM) {
00676         EpdMakeZero(epd, 0);
00677         return(CUDD_OUT_OF_MEM);
00678     }
00679     if (Cudd_IsComplement(node)) {
00680         EpdSubtract3(&max, epd, &tmp);
00681         EpdCopy(&tmp, epd);
00682     }
00683     return(0);
00684 
00685 } /* end of Cudd_EpdCountMinterm */

int Cudd_EqualSupNorm ( DdManager dd,
DdNode f,
DdNode g,
CUDD_VALUE_TYPE  tolerance,
int  pr 
)

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

Synopsis [Compares two ADDs for equality within tolerance.]

Description [Compares two ADDs for equality within tolerance. Two ADDs are reported to be equal if the maximum difference between them (the sup norm of their difference) is less than or equal to the tolerance parameter. Returns 1 if the two ADDs are equal (within tolerance); 0 otherwise. If parameter pr is positive the first failure is reported to the standard output.]

SideEffects [None]

SeeAlso []

Definition at line 792 of file cuddSat.c.

00798 {
00799     DdNode *fv, *fvn, *gv, *gvn, *r;
00800     unsigned int topf, topg;
00801 
00802     statLine(dd);
00803     /* Check terminal cases. */
00804     if (f == g) return(1);
00805     if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) {
00806         if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) {
00807             return(1);
00808         } else {
00809             if (pr>0) {
00810                 (void) fprintf(dd->out,"Offending nodes:\n");
00811                 (void) fprintf(dd->out,
00812                                "f: address = %p\t value = %40.30f\n",
00813                                (void *) f, cuddV(f));
00814                 (void) fprintf(dd->out,
00815                                "g: address = %p\t value = %40.30f\n",
00816                                (void *) g, cuddV(g));
00817             }
00818             return(0);
00819         }
00820     }
00821 
00822     /* We only insert the result in the cache if the comparison is
00823     ** successful. Therefore, if we hit we return 1. */
00824     r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g);
00825     if (r != NULL) {
00826         return(1);
00827     }
00828 
00829     /* Compute the cofactors and solve the recursive subproblems. */
00830     topf = cuddI(dd,f->index);
00831     topg = cuddI(dd,g->index);
00832 
00833     if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;}
00834     if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;}
00835 
00836     if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0);
00837     if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0);
00838 
00839     cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g,DD_ONE(dd));
00840 
00841     return(1);
00842 
00843 } /* end of Cudd_EqualSupNorm */

int Cudd_EquivDC ( DdManager dd,
DdNode F,
DdNode G,
DdNode D 
)

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

Synopsis [Tells whether F and G are identical wherever D is 0.]

Description [Tells whether F and G are identical wherever D is 0. F and G are either two ADDs or two BDDs. D is either a 0-1 ADD or a BDD. The function returns 1 if F and G are equivalent, and 0 otherwise. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_bddLeqUnless]

Definition at line 518 of file cuddSat.c.

00523 {
00524     DdNode *tmp, *One, *Gr, *Dr;
00525     DdNode *Fv, *Fvn, *Gv, *Gvn, *Dv, *Dvn;
00526     int res;
00527     unsigned int flevel, glevel, dlevel, top;
00528 
00529     One = DD_ONE(dd);
00530 
00531     statLine(dd);
00532     /* Check terminal cases. */
00533     if (D == One || F == G) return(1);
00534     if (D == Cudd_Not(One) || D == DD_ZERO(dd) || F == Cudd_Not(G)) return(0);
00535 
00536     /* From now on, D is non-constant. */
00537 
00538     /* Normalize call to increase cache efficiency. */
00539     if (F > G) {
00540         tmp = F;
00541         F = G;
00542         G = tmp;
00543     }
00544     if (Cudd_IsComplement(F)) {
00545         F = Cudd_Not(F);
00546         G = Cudd_Not(G);
00547     }
00548 
00549     /* From now on, F is regular. */
00550 
00551     /* Check cache. */
00552     tmp = cuddCacheLookup(dd,DD_EQUIV_DC_TAG,F,G,D);
00553     if (tmp != NULL) return(tmp == One);
00554 
00555     /* Find splitting variable. */
00556     flevel = cuddI(dd,F->index);
00557     Gr = Cudd_Regular(G);
00558     glevel = cuddI(dd,Gr->index);
00559     top = ddMin(flevel,glevel);
00560     Dr = Cudd_Regular(D);
00561     dlevel = dd->perm[Dr->index];
00562     top = ddMin(top,dlevel);
00563 
00564     /* Compute cofactors. */
00565     if (top == flevel) {
00566         Fv = cuddT(F);
00567         Fvn = cuddE(F);
00568     } else {
00569         Fv = Fvn = F;
00570     }
00571     if (top == glevel) {
00572         Gv = cuddT(Gr);
00573         Gvn = cuddE(Gr);
00574         if (G != Gr) {
00575             Gv = Cudd_Not(Gv);
00576             Gvn = Cudd_Not(Gvn);
00577         }
00578     } else {
00579         Gv = Gvn = G;
00580     }
00581     if (top == dlevel) {
00582         Dv = cuddT(Dr);
00583         Dvn = cuddE(Dr);
00584         if (D != Dr) {
00585             Dv = Cudd_Not(Dv);
00586             Dvn = Cudd_Not(Dvn);
00587         }
00588     } else {
00589         Dv = Dvn = D;
00590     }
00591 
00592     /* Solve recursively. */
00593     res = Cudd_EquivDC(dd,Fv,Gv,Dv);
00594     if (res != 0) {
00595         res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn);
00596     }
00597     cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One));
00598 
00599     return(res);
00600 
00601 } /* end of Cudd_EquivDC */

int Cudd_EstimateCofactor ( DdManager dd,
DdNode f,
int  i,
int  phase 
)

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

Synopsis [Estimates the number of nodes in a cofactor of a DD.]

Description [Estimates the number of nodes in a cofactor of a DD. Returns an estimate of the number of nodes in a cofactor of the graph rooted at node with respect to the variable whose index is i. In case of failure, returns CUDD_OUT_OF_MEM. This function uses a refinement of the algorithm of Cabodi et al. (ICCAD96). The refinement allows the procedure to account for part of the recombination that may occur in the part of the cofactor above the cofactoring variable. This procedure does no create any new node. It does keep a small table of results; therefore it may run out of memory. If this is a concern, one should use Cudd_EstimateCofactorSimple, which is faster, does not allocate any memory, but is less accurate.]

SideEffects [None]

SeeAlso [Cudd_DagSize Cudd_EstimateCofactorSimple]

Definition at line 473 of file cuddUtil.c.

00477                     : positive; 0: negative */
00478   )
00479 {
00480     int val;
00481     DdNode *ptr;
00482     st_table *table;
00483 
00484     table = st_init_table(st_ptrcmp,st_ptrhash);
00485     if (table == NULL) return(CUDD_OUT_OF_MEM);
00486     val = cuddEstimateCofactor(dd,table,Cudd_Regular(f),i,phase,&ptr);
00487     ddClearFlag(Cudd_Regular(f));
00488     st_free_table(table);
00489 
00490     return(val);
00491 
00492 } /* end of Cudd_EstimateCofactor */

int Cudd_EstimateCofactorSimple ( DdNode node,
int  i 
)

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

Synopsis [Estimates the number of nodes in a cofactor of a DD.]

Description [Estimates the number of nodes in a cofactor of a DD. Returns an estimate of the number of nodes in the positive cofactor of the graph rooted at node with respect to the variable whose index is i. This procedure implements with minor changes the algorithm of Cabodi et al. (ICCAD96). It does not allocate any memory, it does not change the state of the manager, and it is fast. However, it has been observed to overestimate the size of the cofactor by as much as a factor of 2.]

SideEffects [None]

SeeAlso [Cudd_DagSize]

Definition at line 513 of file cuddUtil.c.

00516 {
00517     int val;
00518 
00519     val = cuddEstimateCofactorSimple(Cudd_Regular(node),i);
00520     ddClearFlag(Cudd_Regular(node));
00521 
00522     return(val);
00523 
00524 } /* end of Cudd_EstimateCofactorSimple */

DdNode* Cudd_Eval ( DdManager dd,
DdNode f,
int *  inputs 
)

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

Synopsis [Returns the value of a DD for a given variable assignment.]

Description [Finds the value of a DD for a given variable assignment. The variable assignment is passed in an array of int's, that should specify a zero or a one for each variable in the support of the function. Returns a pointer to a constant node. No new nodes are produced.]

SideEffects [None]

SeeAlso [Cudd_bddLeq Cudd_addEvalConst]

Definition at line 153 of file cuddSat.c.

00157 {
00158     int comple;
00159     DdNode *ptr;
00160 
00161     comple = Cudd_IsComplement(f);
00162     ptr = Cudd_Regular(f);
00163 
00164     while (!cuddIsConstant(ptr)) {
00165         if (inputs[ptr->index] == 1) {
00166             ptr = cuddT(ptr);
00167         } else {
00168             comple ^= Cudd_IsComplement(cuddE(ptr));
00169             ptr = Cudd_Regular(cuddE(ptr));
00170         }
00171     }
00172     return(Cudd_NotCond(ptr,comple));
00173 
00174 } /* end of Cudd_Eval */

double Cudd_ExpectedUsedSlots ( DdManager dd  ) 

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

Synopsis [Computes the expected fraction of used slots in the unique table.]

Description [Computes the fraction of slots in the unique table that should be in use. This expected value is based on the assumption that the hash function distributes the keys randomly; it can be compared with the result of Cudd_ReadUsedSlots to monitor the performance of the unique table hash function.]

SideEffects [None]

SeeAlso [Cudd_ReadSlots Cudd_ReadUsedSlots]

Definition at line 1568 of file cuddAPI.c.

01570 {
01571     int i;
01572     int size = dd->size;
01573     DdSubtable *subtable;
01574     double empty = 0.0;
01575 
01576     /* To each subtable we apply the corollary to Theorem 8.5 (occupancy
01577     ** distribution) from Sedgewick and Flajolet's Analysis of Algorithms.
01578     ** The corollary says that for a table with M buckets and a load ratio
01579     ** of r, the expected number of empty buckets is asymptotically given
01580     ** by M * exp(-r).
01581     */
01582 
01583     /* Scan each BDD/ADD subtable. */
01584     for (i = 0; i < size; i++) {
01585         subtable = &(dd->subtables[i]);
01586         empty += (double) subtable->slots *
01587             exp(-(double) subtable->keys / (double) subtable->slots);
01588     }
01589 
01590     /* Scan the ZDD subtables. */
01591     size = dd->sizeZ;
01592 
01593     for (i = 0; i < size; i++) {
01594         subtable = &(dd->subtableZ[i]);
01595         empty += (double) subtable->slots *
01596             exp(-(double) subtable->keys / (double) subtable->slots);
01597     }
01598 
01599     /* Constant table. */
01600     subtable = &(dd->constants);
01601     empty += (double) subtable->slots *
01602         exp(-(double) subtable->keys / (double) subtable->slots);
01603 
01604     return(1.0 - empty / (double) dd->slots);
01605 
01606 } /* end of Cudd_ExpectedUsedSlots */

DdNode* Cudd_FindEssential ( DdManager dd,
DdNode f 
)

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

Synopsis [Finds the essential variables of a DD.]

Description [Returns the cube of the essential variables. A positive literal means that the variable must be set to 1 for the function to be 1. A negative literal means that the variable must be set to 0 for the function to be 1. Returns a pointer to the cube BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddIsVarEssential]

Definition at line 205 of file cuddEssent.c.

00208 {
00209     DdNode *res;
00210 
00211     do {
00212         dd->reordered = 0;
00213         res = ddFindEssentialRecur(dd,f);
00214     } while (dd->reordered == 1);
00215     return(res);
00216 
00217 } /* end of Cudd_FindEssential */

DdTlcInfo* Cudd_FindTwoLiteralClauses ( DdManager dd,
DdNode f 
)

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

Synopsis [Finds the two literal clauses of a DD.]

Description [Returns the one- and two-literal clauses of a DD. Returns a pointer to the structure holding the clauses if successful; NULL otherwise. For a constant DD, the empty set of clauses is returned. This is obviously correct for a non-zero constant. For the constant zero, it is based on the assumption that only those clauses containing variables in the support of the function are considered. Since the support of a constant function is empty, no clauses are returned.]

SideEffects [None]

SeeAlso [Cudd_FindEssential]

Definition at line 273 of file cuddEssent.c.

00276 {
00277     DdTlcInfo *res;
00278     st_table *table;
00279     st_generator *gen;
00280     DdTlcInfo *tlc;
00281     DdNode *node;
00282     int size = dd->size;
00283 
00284     if (Cudd_IsConstant(f)) {
00285         res = emptyClauseSet();
00286         return(res);
00287     }
00288     table = st_init_table(st_ptrcmp,st_ptrhash);
00289     if (table == NULL) return(NULL);
00290     Tolv = bitVectorAlloc(size);
00291     if (Tolv == NULL) {
00292         st_free_table(table);
00293         return(NULL);
00294     }
00295     Tolp = bitVectorAlloc(size);
00296     if (Tolp == NULL) {
00297         st_free_table(table);
00298         bitVectorFree(Tolv);
00299         return(NULL);
00300     }
00301     Eolv = bitVectorAlloc(size);
00302     if (Eolv == NULL) {
00303         st_free_table(table);
00304         bitVectorFree(Tolv);
00305         bitVectorFree(Tolp);
00306         return(NULL);
00307     }
00308     Eolp = bitVectorAlloc(size);
00309     if (Eolp == NULL) {
00310         st_free_table(table);
00311         bitVectorFree(Tolv);
00312         bitVectorFree(Tolp);
00313         bitVectorFree(Eolv);
00314         return(NULL);
00315     }
00316 
00317     res = ddFindTwoLiteralClausesRecur(dd,f,table);
00318     /* Dispose of table contents and free table. */
00319     st_foreach_item(table, gen, &node, &tlc) {
00320         if (node != f) {
00321             Cudd_tlcInfoFree(tlc);
00322         }
00323     }
00324     st_free_table(table);
00325     bitVectorFree(Tolv);
00326     bitVectorFree(Tolp);
00327     bitVectorFree(Eolv);
00328     bitVectorFree(Eolp);
00329 
00330     if (res != NULL) {
00331         int i;
00332         for (i = 0; !sentinelp(res->vars[i], res->vars[i+1]); i += 2);
00333         res->cnt = i >> 1;
00334     }
00335 
00336     return(res);
00337 
00338 } /* end of Cudd_FindTwoLiteralClauses */

DdGen* Cudd_FirstCube ( DdManager dd,
DdNode f,
int **  cube,
CUDD_VALUE_TYPE *  value 
)

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

Synopsis [Finds the first cube of a decision diagram.]

Description [Defines an iterator on the onset of a decision diagram and finds its first cube. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise.

A cube is represented as an array of literals, which are integers in {0, 1, 2}; 0 represents a complemented literal, 1 represents an uncomplemented literal, and 2 stands for don't care. The enumeration produces a disjoint cover of the function associated with the diagram. The size of the array equals the number of variables in the manager at the time Cudd_FirstCube is called.

For each cube, a value is also returned. This value is always 1 for a BDD, while it may be different from 1 for an ADD. For BDDs, the offset is the set of cubes whose value is the logical zero. For ADDs, the offset is the set of cubes whose value is the background value. The cubes of the offset are not enumerated.]

SideEffects [The first cube and its value are returned as side effects.]

SeeAlso [Cudd_ForeachCube Cudd_NextCube Cudd_GenFree Cudd_IsGenEmpty Cudd_FirstNode]

Definition at line 1794 of file cuddUtil.c.

01799 {
01800     DdGen *gen;
01801     DdNode *top, *treg, *next, *nreg, *prev, *preg;
01802     int i;
01803     int nvars;
01804 
01805     /* Sanity Check. */
01806     if (dd == NULL || f == NULL) return(NULL);
01807 
01808     /* Allocate generator an initialize it. */
01809     gen = ALLOC(DdGen,1);
01810     if (gen == NULL) {
01811         dd->errorCode = CUDD_MEMORY_OUT;
01812         return(NULL);
01813     }
01814 
01815     gen->manager = dd;
01816     gen->type = CUDD_GEN_CUBES;
01817     gen->status = CUDD_GEN_EMPTY;
01818     gen->gen.cubes.cube = NULL;
01819     gen->gen.cubes.value = DD_ZERO_VAL;
01820     gen->stack.sp = 0;
01821     gen->stack.stack = NULL;
01822     gen->node = NULL;
01823 
01824     nvars = dd->size;
01825     gen->gen.cubes.cube = ALLOC(int,nvars);
01826     if (gen->gen.cubes.cube == NULL) {
01827         dd->errorCode = CUDD_MEMORY_OUT;
01828         FREE(gen);
01829         return(NULL);
01830     }
01831     for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2;
01832 
01833     /* The maximum stack depth is one plus the number of variables.
01834     ** because a path may have nodes at all levels, including the
01835     ** constant level.
01836     */
01837     gen->stack.stack = ALLOC(DdNodePtr, nvars+1);
01838     if (gen->stack.stack == NULL) {
01839         dd->errorCode = CUDD_MEMORY_OUT;
01840         FREE(gen->gen.cubes.cube);
01841         FREE(gen);
01842         return(NULL);
01843     }
01844     for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL;
01845 
01846     /* Find the first cube of the onset. */
01847     gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++;
01848 
01849     while (1) {
01850         top = gen->stack.stack[gen->stack.sp-1];
01851         treg = Cudd_Regular(top);
01852         if (!cuddIsConstant(treg)) {
01853             /* Take the else branch first. */
01854             gen->gen.cubes.cube[treg->index] = 0;
01855             next = cuddE(treg);
01856             if (top != treg) next = Cudd_Not(next);
01857             gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++;
01858         } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) {
01859             /* Backtrack */
01860             while (1) {
01861                 if (gen->stack.sp == 1) {
01862                     /* The current node has no predecessor. */
01863                     gen->status = CUDD_GEN_EMPTY;
01864                     gen->stack.sp--;
01865                     goto done;
01866                 }
01867                 prev = gen->stack.stack[gen->stack.sp-2];
01868                 preg = Cudd_Regular(prev);
01869                 nreg = cuddT(preg);
01870                 if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;}
01871                 if (next != top) { /* follow the then branch next */
01872                     gen->gen.cubes.cube[preg->index] = 1;
01873                     gen->stack.stack[gen->stack.sp-1] = next;
01874                     break;
01875                 }
01876                 /* Pop the stack and try again. */
01877                 gen->gen.cubes.cube[preg->index] = 2;
01878                 gen->stack.sp--;
01879                 top = gen->stack.stack[gen->stack.sp-1];
01880                 treg = Cudd_Regular(top);
01881             }
01882         } else {
01883             gen->status = CUDD_GEN_NONEMPTY;
01884             gen->gen.cubes.value = cuddV(top);
01885             goto done;
01886         }
01887     }
01888 
01889 done:
01890     *cube = gen->gen.cubes.cube;
01891     *value = gen->gen.cubes.value;
01892     return(gen);
01893 
01894 } /* end of Cudd_FirstCube */

DdGen* Cudd_FirstNode ( DdManager dd,
DdNode f,
DdNode **  node 
)

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

Synopsis [Finds the first node of a decision diagram.]

Description [Defines an iterator on the nodes of a decision diagram and finds its first node. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise. The nodes are enumerated in a reverse topological order, so that a node is always preceded in the enumeration by its descendants.]

SideEffects [The first node is returned as a side effect.]

SeeAlso [Cudd_ForeachNode Cudd_NextNode Cudd_GenFree Cudd_IsGenEmpty Cudd_FirstCube]

Definition at line 2396 of file cuddUtil.c.

02400 {
02401     DdGen *gen;
02402     int size;
02403 
02404     /* Sanity Check. */
02405     if (dd == NULL || f == NULL) return(NULL);
02406 
02407     /* Allocate generator an initialize it. */
02408     gen = ALLOC(DdGen,1);
02409     if (gen == NULL) {
02410         dd->errorCode = CUDD_MEMORY_OUT;
02411         return(NULL);
02412     }
02413 
02414     gen->manager = dd;
02415     gen->type = CUDD_GEN_NODES;
02416     gen->status = CUDD_GEN_EMPTY;
02417     gen->stack.sp = 0;
02418     gen->node = NULL;
02419 
02420     /* Collect all the nodes on the generator stack for later perusal. */
02421     gen->stack.stack = cuddNodeArray(Cudd_Regular(f), &size);
02422     if (gen->stack.stack == NULL) {
02423         FREE(gen);
02424         dd->errorCode = CUDD_MEMORY_OUT;
02425         return(NULL);
02426     }
02427     gen->gen.nodes.size = size;
02428 
02429     /* Find the first node. */
02430     if (gen->stack.sp < gen->gen.nodes.size) {
02431         gen->status = CUDD_GEN_NONEMPTY;
02432         gen->node = gen->stack.stack[gen->stack.sp];
02433         *node = gen->node;
02434     }
02435 
02436     return(gen);
02437 
02438 } /* end of Cudd_FirstNode */

DdGen* Cudd_FirstPrime ( DdManager dd,
DdNode l,
DdNode u,
int **  cube 
)

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

Synopsis [Finds the first prime of a Boolean function.]

Description [Defines an iterator on a pair of BDDs describing a (possibly incompletely specified) Boolean functions and finds the first cube of a cover of the function. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise.

The two argument BDDs are the lower and upper bounds of an interval. It is a mistake to call this function with a lower bound that is not less than or equal to the upper bound.

A cube is represented as an array of literals, which are integers in {0, 1, 2}; 0 represents a complemented literal, 1 represents an uncomplemented literal, and 2 stands for don't care. The enumeration produces a prime and irredundant cover of the function associated with the two BDDs. The size of the array equals the number of variables in the manager at the time Cudd_FirstCube is called.

This iterator can only be used on BDDs.]

SideEffects [The first cube is returned as side effect.]

SeeAlso [Cudd_ForeachPrime Cudd_NextPrime Cudd_GenFree Cudd_IsGenEmpty Cudd_FirstCube Cudd_FirstNode]

Definition at line 2024 of file cuddUtil.c.

02029 {
02030     DdGen *gen;
02031     DdNode *implicant, *prime, *tmp;
02032     int length, result;
02033 
02034     /* Sanity Check. */
02035     if (dd == NULL || l == NULL || u == NULL) return(NULL);
02036 
02037     /* Allocate generator an initialize it. */
02038     gen = ALLOC(DdGen,1);
02039     if (gen == NULL) {
02040         dd->errorCode = CUDD_MEMORY_OUT;
02041         return(NULL);
02042     }
02043 
02044     gen->manager = dd;
02045     gen->type = CUDD_GEN_PRIMES;
02046     gen->status = CUDD_GEN_EMPTY;
02047     gen->gen.primes.cube = NULL;
02048     gen->gen.primes.ub = u;
02049     gen->stack.sp = 0;
02050     gen->stack.stack = NULL;
02051     gen->node = l;
02052     cuddRef(l);
02053 
02054     gen->gen.primes.cube = ALLOC(int,dd->size);
02055     if (gen->gen.primes.cube == NULL) {
02056         dd->errorCode = CUDD_MEMORY_OUT;
02057         FREE(gen);
02058         return(NULL);
02059     }
02060 
02061     if (gen->node == Cudd_ReadLogicZero(dd)) {
02062         gen->status = CUDD_GEN_EMPTY;
02063     } else {
02064         implicant = Cudd_LargestCube(dd,gen->node,&length);
02065         if (implicant == NULL) {
02066             Cudd_RecursiveDeref(dd,gen->node);
02067             FREE(gen->gen.primes.cube);
02068             FREE(gen);
02069             return(NULL);
02070         }
02071         cuddRef(implicant);
02072         prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub);
02073         if (prime == NULL) {
02074             Cudd_RecursiveDeref(dd,gen->node);
02075             Cudd_RecursiveDeref(dd,implicant);
02076             FREE(gen->gen.primes.cube);
02077             FREE(gen);
02078             return(NULL);
02079         }
02080         cuddRef(prime);
02081         Cudd_RecursiveDeref(dd,implicant);
02082         tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime));
02083         if (tmp == NULL) {
02084             Cudd_RecursiveDeref(dd,gen->node);
02085             Cudd_RecursiveDeref(dd,prime);
02086             FREE(gen->gen.primes.cube);
02087             FREE(gen);
02088             return(NULL);
02089         }
02090         cuddRef(tmp);
02091         Cudd_RecursiveDeref(dd,gen->node);
02092         gen->node = tmp;
02093         result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube);
02094         if (result == 0) {
02095             Cudd_RecursiveDeref(dd,gen->node);
02096             Cudd_RecursiveDeref(dd,prime);
02097             FREE(gen->gen.primes.cube);
02098             FREE(gen);
02099             return(NULL);
02100         }
02101         Cudd_RecursiveDeref(dd,prime);
02102         gen->status = CUDD_GEN_NONEMPTY;
02103     }
02104     *cube = gen->gen.primes.cube;
02105     return(gen);
02106 
02107 } /* end of Cudd_FirstPrime */

void Cudd_FreeTree ( DdManager dd  ) 

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

Synopsis [Frees the variable group tree of the manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_SetTree Cudd_ReadTree Cudd_FreeZddTree]

Definition at line 2176 of file cuddAPI.c.

02178 {
02179     if (dd->tree != NULL) {
02180         Mtr_FreeTree(dd->tree);
02181         dd->tree = NULL;
02182     }
02183     return;
02184 
02185 } /* end of Cudd_FreeTree */

void Cudd_FreeZddTree ( DdManager dd  ) 

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

Synopsis [Frees the variable group tree of the manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_SetZddTree Cudd_ReadZddTree Cudd_FreeTree]

Definition at line 2248 of file cuddAPI.c.

02250 {
02251     if (dd->treeZ != NULL) {
02252         Mtr_FreeTree(dd->treeZ);
02253         dd->treeZ = NULL;
02254     }
02255     return;
02256 
02257 } /* end of Cudd_FreeZddTree */

int Cudd_GarbageCollectionEnabled ( DdManager dd  ) 

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

Synopsis [Tells whether garbage collection is enabled.]

Description [Returns 1 if garbage collection is enabled; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_EnableGarbageCollection Cudd_DisableGarbageCollection]

Definition at line 2513 of file cuddAPI.c.

02515 {
02516     return(dd->gcEnabled);
02517 
02518 } /* end of Cudd_GarbageCollectionEnabled */

int Cudd_GenFree ( DdGen gen  ) 

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

Synopsis [Frees a CUDD generator.]

Description [Frees a CUDD generator. Always returns 0, so that it can be used in mis-like foreach constructs.]

SideEffects [None]

SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_FirstNode Cudd_NextNode Cudd_IsGenEmpty]

Definition at line 2487 of file cuddUtil.c.

02489 {
02490     if (gen == NULL) return(0);
02491     switch (gen->type) {
02492     case CUDD_GEN_CUBES:
02493     case CUDD_GEN_ZDD_PATHS:
02494         FREE(gen->gen.cubes.cube);
02495         FREE(gen->stack.stack);
02496         break;
02497     case CUDD_GEN_PRIMES:
02498         FREE(gen->gen.primes.cube);
02499         Cudd_RecursiveDeref(gen->manager,gen->node);
02500         break;
02501     case CUDD_GEN_NODES:
02502         FREE(gen->stack.stack);
02503         break;
02504     default:
02505         return(0);
02506     }
02507     FREE(gen);
02508     return(0);
02509 
02510 } /* end of Cudd_GenFree */

DdNode* Cudd_Increasing ( DdManager dd,
DdNode f,
int  i 
)

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

Synopsis [Determines whether a BDD is positive unate in a variable.]

Description [Determines whether the function represented by BDD f is positive unate (monotonic increasing) in variable i. It is based on Cudd_Decreasing and the fact that f is monotonic increasing in i if and only if its complement is monotonic decreasing in i.]

SideEffects [None]

SeeAlso [Cudd_Decreasing]

Definition at line 493 of file cuddSat.c.

00497 {
00498     return(Cudd_Decreasing(dd,Cudd_Not(f),i));
00499 
00500 } /* end of Cudd_Increasing */

DdNode* Cudd_IndicesToCube ( DdManager dd,
int *  array,
int  n 
)

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

Synopsis [Builds a cube of BDD variables from an array of indices.]

Description [Builds a cube of BDD variables from an array of indices. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddComputeCube Cudd_CubeArrayToBdd]

Definition at line 2549 of file cuddUtil.c.

02553 {
02554     DdNode *cube, *tmp;
02555     int i;
02556 
02557     cube = DD_ONE(dd);
02558     cuddRef(cube);
02559     for (i = n - 1; i >= 0; i--) {
02560         tmp = Cudd_bddAnd(dd,Cudd_bddIthVar(dd,array[i]),cube);
02561         if (tmp == NULL) {
02562             Cudd_RecursiveDeref(dd,cube);
02563             return(NULL);
02564         }
02565         cuddRef(tmp);
02566         Cudd_RecursiveDeref(dd,cube);
02567         cube = tmp;
02568     }
02569 
02570     cuddDeref(cube);
02571     return(cube);
02572 
02573 } /* end of Cudd_IndicesToCube */

DdNode* Cudd_Inequality ( DdManager dd,
int  N,
int  c,
DdNode **  x,
DdNode **  y 
)

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

Synopsis [Generates a BDD for the function x - y c.]

Description [This function generates a BDD for the function x -y c. Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. The BDD is built bottom-up. It has a linear number of nodes if the variables are ordered as follows: x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].]

SideEffects [None]

SeeAlso [Cudd_Xgty]

Definition at line 740 of file cuddPriority.c.

00746 {
00747     /* The nodes at level i represent values of the difference that are
00748     ** multiples of 2^i.  We use variables with names starting with k
00749     ** to denote the multipliers of 2^i in such multiples. */
00750     int kTrue = c;
00751     int kFalse = c - 1;
00752     /* Mask used to compute the ceiling function.  Since we divide by 2^i,
00753     ** we want to know whether the dividend is a multiple of 2^i.  If it is,
00754     ** then ceiling and floor coincide; otherwise, they differ by one. */
00755     int mask = 1;
00756     int i;
00757 
00758     DdNode *f = NULL;           /* the eventual result */
00759     DdNode *one = DD_ONE(dd);
00760     DdNode *zero = Cudd_Not(one);
00761 
00762     /* Two x-labeled nodes are created at most at each iteration.  They are
00763     ** stored, along with their k values, in these variables.  At each level,
00764     ** the old nodes are freed and the new nodes are copied into the old map.
00765     */
00766     DdNode *map[2];
00767     int invalidIndex = 1 << (N-1);
00768     int index[2] = {invalidIndex, invalidIndex};
00769 
00770     /* This should never happen. */
00771     if (N < 0) return(NULL);
00772 
00773     /* If there are no bits, both operands are 0.  The result depends on c. */
00774     if (N == 0) {
00775         if (c >= 0) return(one);
00776         else return(zero);
00777     }
00778 
00779     /* The maximum or the minimum difference comparing to c can generate the terminal case */
00780     if ((1 << N) - 1 < c) return(zero);
00781     else if ((-(1 << N) + 1) >= c) return(one);
00782 
00783     /* Build the result bottom up. */
00784     for (i = 1; i <= N; i++) {
00785         int kTrueLower, kFalseLower;
00786         int leftChild, middleChild, rightChild;
00787         DdNode *g0, *g1, *fplus, *fequal, *fminus;
00788         int j;
00789         DdNode *newMap[2];
00790         int newIndex[2];
00791 
00792         kTrueLower = kTrue;
00793         kFalseLower = kFalse;
00794         /* kTrue = ceiling((c-1)/2^i) + 1 */
00795         kTrue = ((c-1) >> i) + ((c & mask) != 1) + 1;
00796         mask = (mask << 1) | 1;
00797         /* kFalse = floor(c/2^i) - 1 */
00798         kFalse = (c >> i) - 1;
00799         newIndex[0] = invalidIndex;
00800         newIndex[1] = invalidIndex;
00801 
00802         for (j = kFalse + 1; j < kTrue; j++) {
00803             /* Skip if node is not reachable from top of BDD. */
00804             if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue;
00805 
00806             /* Find f- */
00807             leftChild = (j << 1) - 1;
00808             if (leftChild >= kTrueLower) {
00809                 fminus = one;
00810             } else if (leftChild <= kFalseLower) {
00811                 fminus = zero;
00812             } else {
00813                 assert(leftChild == index[0] || leftChild == index[1]);
00814                 if (leftChild == index[0]) {
00815                     fminus = map[0];
00816                 } else {
00817                     fminus = map[1];
00818                 }
00819             }
00820 
00821             /* Find f= */
00822             middleChild = j << 1;
00823             if (middleChild >= kTrueLower) {
00824                 fequal = one;
00825             } else if (middleChild <= kFalseLower) {
00826                 fequal = zero;
00827             } else {
00828                 assert(middleChild == index[0] || middleChild == index[1]);
00829                 if (middleChild == index[0]) {
00830                     fequal = map[0];
00831                 } else {
00832                     fequal = map[1];
00833                 }
00834             }
00835 
00836             /* Find f+ */
00837             rightChild = (j << 1) + 1;
00838             if (rightChild >= kTrueLower) {
00839                 fplus = one;
00840             } else if (rightChild <= kFalseLower) {
00841                 fplus = zero;
00842             } else {
00843                 assert(rightChild == index[0] || rightChild == index[1]);
00844                 if (rightChild == index[0]) {
00845                     fplus = map[0];
00846                 } else {
00847                     fplus = map[1];
00848                 }
00849             }
00850 
00851             /* Build new nodes. */
00852             g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus);
00853             if (g1 == NULL) {
00854                 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
00855                 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
00856                 if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]);
00857                 if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]);
00858                 return(NULL);
00859             }
00860             cuddRef(g1);
00861             g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal);
00862             if (g0 == NULL) {
00863                 Cudd_IterDerefBdd(dd, g1);
00864                 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
00865                 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
00866                 if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]);
00867                 if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]);
00868                 return(NULL);
00869             }
00870             cuddRef(g0);
00871             f = Cudd_bddIte(dd, x[N - i], g1, g0);
00872             if (f == NULL) {
00873                 Cudd_IterDerefBdd(dd, g1);
00874                 Cudd_IterDerefBdd(dd, g0);
00875                 if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
00876                 if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
00877                 if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]);
00878                 if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]);
00879                 return(NULL);
00880             }
00881             cuddRef(f);
00882             Cudd_IterDerefBdd(dd, g1);
00883             Cudd_IterDerefBdd(dd, g0);
00884 
00885             /* Save newly computed node in map. */
00886             assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex);
00887             if (newIndex[0] == invalidIndex) {
00888                 newIndex[0] = j;
00889                 newMap[0] = f;
00890             } else {
00891                 newIndex[1] = j;
00892                 newMap[1] = f;
00893             }
00894         }
00895 
00896         /* Copy new map to map. */
00897         if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]);
00898         if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]);
00899         map[0] = newMap[0];
00900         map[1] = newMap[1];
00901         index[0] = newIndex[0];
00902         index[1] = newIndex[1];
00903     }
00904 
00905     cuddDeref(f);
00906     return(f);
00907 
00908 } /* end of Cudd_Inequality */

DdManager* Cudd_Init ( unsigned int  numVars,
unsigned int  numVarsZ,
unsigned int  numSlots,
unsigned int  cacheSize,
unsigned long  maxMemory 
)

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

Synopsis [Creates a new DD manager.]

Description [Creates a new DD manager, initializes the table, the basic constants and the projection functions. If maxMemory is 0, Cudd_Init decides suitable values for the maximum size of the cache and for the limit for fast unique table growth based on the available memory. Returns a pointer to the manager if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_Quit]

Definition at line 121 of file cuddInit.c.

00127 {
00128     DdManager *unique;
00129     int i,result;
00130     DdNode *one, *zero;
00131     unsigned int maxCacheSize;
00132     unsigned int looseUpTo;
00133     extern DD_OOMFP MMoutOfMemory;
00134     DD_OOMFP saveHandler;
00135 
00136     if (maxMemory == 0) {
00137         maxMemory = getSoftDataLimit();
00138     }
00139     looseUpTo = (unsigned int) ((maxMemory / sizeof(DdNode)) /
00140                                 DD_MAX_LOOSE_FRACTION);
00141     unique = cuddInitTable(numVars,numVarsZ,numSlots,looseUpTo);
00142     if (unique == NULL) return(NULL);
00143     unique->maxmem = (unsigned long) maxMemory / 10 * 9;
00144     maxCacheSize = (unsigned int) ((maxMemory / sizeof(DdCache)) /
00145                                    DD_MAX_CACHE_FRACTION);
00146     result = cuddInitCache(unique,cacheSize,maxCacheSize);
00147     if (result == 0) return(NULL);
00148 
00149     saveHandler = MMoutOfMemory;
00150     MMoutOfMemory = Cudd_OutOfMem;
00151     unique->stash = ALLOC(char,(maxMemory / DD_STASH_FRACTION) + 4);
00152     MMoutOfMemory = saveHandler;
00153     if (unique->stash == NULL) {
00154         (void) fprintf(unique->err,"Unable to set aside memory\n");
00155     }
00156 
00157     /* Initialize constants. */
00158     unique->one = cuddUniqueConst(unique,1.0);
00159     if (unique->one == NULL) return(0);
00160     cuddRef(unique->one);
00161     unique->zero = cuddUniqueConst(unique,0.0);
00162     if (unique->zero == NULL) return(0);
00163     cuddRef(unique->zero);
00164 #ifdef HAVE_IEEE_754
00165     if (DD_PLUS_INF_VAL != DD_PLUS_INF_VAL * 3 ||
00166         DD_PLUS_INF_VAL != DD_PLUS_INF_VAL / 3) {
00167         (void) fprintf(unique->err,"Warning: Crippled infinite values\n");
00168         (void) fprintf(unique->err,"Recompile without -DHAVE_IEEE_754\n");
00169     }
00170 #endif
00171     unique->plusinfinity = cuddUniqueConst(unique,DD_PLUS_INF_VAL);
00172     if (unique->plusinfinity == NULL) return(0);
00173     cuddRef(unique->plusinfinity);
00174     unique->minusinfinity = cuddUniqueConst(unique,DD_MINUS_INF_VAL);
00175     if (unique->minusinfinity == NULL) return(0);
00176     cuddRef(unique->minusinfinity);
00177     unique->background = unique->zero;
00178 
00179     /* The logical zero is different from the CUDD_VALUE_TYPE zero! */
00180     one = unique->one;
00181     zero = Cudd_Not(one);
00182     /* Create the projection functions. */
00183     unique->vars = ALLOC(DdNodePtr,unique->maxSize);
00184     if (unique->vars == NULL) {
00185         unique->errorCode = CUDD_MEMORY_OUT;
00186         return(NULL);
00187     }
00188     for (i = 0; i < unique->size; i++) {
00189         unique->vars[i] = cuddUniqueInter(unique,i,one,zero);
00190         if (unique->vars[i] == NULL) return(0);
00191         cuddRef(unique->vars[i]);
00192     }
00193 
00194     if (unique->sizeZ)
00195         cuddZddInitUniv(unique);
00196 
00197     unique->memused += sizeof(DdNode *) * unique->maxSize;
00198 
00199     return(unique);
00200 
00201 } /* end of Cudd_Init */

int Cudd_IsGenEmpty ( DdGen gen  ) 

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

Synopsis [Queries the status of a generator.]

Description [Queries the status of a generator. Returns 1 if the generator is empty or NULL; 0 otherswise.]

SideEffects [None]

SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_FirstNode Cudd_NextNode Cudd_GenFree]

Definition at line 2527 of file cuddUtil.c.

02529 {
02530     if (gen == NULL) return(1);
02531     return(gen->status == CUDD_GEN_EMPTY);
02532 
02533 } /* end of Cudd_IsGenEmpty */

int Cudd_IsInHook ( DdManager dd,
DD_HFP  f,
Cudd_HookType  where 
)

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

Synopsis [Checks whether a function is in a hook.]

Description [Checks whether a function is in a hook. A hook is a list of application-provided functions called on certain occasions by the package. Returns 1 if the function is found; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_AddHook Cudd_RemoveHook]

Definition at line 3356 of file cuddAPI.c.

03360 {
03361     DdHook *hook;
03362 
03363     switch (where) {
03364     case CUDD_PRE_GC_HOOK:
03365         hook = dd->preGCHook;
03366         break;
03367     case CUDD_POST_GC_HOOK:
03368         hook = dd->postGCHook;
03369         break;
03370     case CUDD_PRE_REORDERING_HOOK:
03371         hook = dd->preReorderingHook;
03372         break;
03373     case CUDD_POST_REORDERING_HOOK:
03374         hook = dd->postReorderingHook;
03375         break;
03376     default:
03377         return(0);
03378     }
03379     /* Scan the list and find whether the function is already there. */
03380     while (hook != NULL) {
03381         if (hook->f == f) {
03382             return(1);
03383         }
03384         hook = hook->next;
03385     }
03386     return(0);
03387 
03388 } /* end of Cudd_IsInHook */

int Cudd_IsNonConstant ( DdNode f  ) 

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

Synopsis [Returns 1 if a DD node is not constant.]

Description [Returns 1 if a DD node is not constant. This function is useful to test the results of Cudd_bddIteConstant, Cudd_addIteConstant, Cudd_addEvalConst. These results may be a special value signifying non-constant. In the other cases the macro Cudd_IsConstant can be used.]

SideEffects [None]

SeeAlso [Cudd_IsConstant Cudd_bddIteConstant Cudd_addIteConstant Cudd_addEvalConst]

Definition at line 641 of file cuddAPI.c.

00643 {
00644     return(f == DD_NON_CONSTANT || !Cudd_IsConstant(f));
00645 
00646 } /* end of Cudd_IsNonConstant */

void Cudd_IterDerefBdd ( DdManager table,
DdNode n 
)

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

Synopsis [Decreases the reference count of BDD node n.]

Description [Decreases the reference count of node n. If n dies, recursively decreases the reference counts of its children. It is used to dispose of a BDD that is no longer needed. It is more efficient than Cudd_RecursiveDeref, but it cannot be used on ADDs. The greater efficiency comes from being able to assume that no constant node will ever die as a result of a call to this procedure.]

SideEffects [None]

SeeAlso [Cudd_RecursiveDeref Cudd_DelayedDerefBdd]

Definition at line 213 of file cuddRef.c.

00216 {
00217     DdNode *N;
00218     int ord;
00219     DdNodePtr *stack = table->stack;
00220     int SP = 1;
00221 
00222     unsigned int live = table->keys - table->dead;
00223     if (live > table->peakLiveNodes) {
00224         table->peakLiveNodes = live;
00225     }
00226 
00227     N = Cudd_Regular(n);
00228 
00229     do {
00230 #ifdef DD_DEBUG
00231         assert(N->ref != 0);
00232 #endif
00233 
00234         if (N->ref == 1) {
00235             N->ref = 0;
00236             table->dead++;
00237 #ifdef DD_STATS
00238             table->nodesDropped++;
00239 #endif
00240             ord = table->perm[N->index];
00241             stack[SP++] = Cudd_Regular(cuddE(N));
00242             table->subtables[ord].dead++;
00243             N = cuddT(N);
00244         } else {
00245             cuddSatDec(N->ref);
00246             N = stack[--SP];
00247         }
00248     } while (SP != 0);
00249 
00250 } /* end of Cudd_IterDerefBdd */

DdNode* Cudd_LargestCube ( DdManager manager,
DdNode f,
int *  length 
)

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

Synopsis [Finds a largest cube in a DD.]

Description [Finds a largest cube in a DD. f is the DD we want to get the largest cube for. The problem is translated into the one of finding a shortest path in f, when both THEN and ELSE arcs are assumed to have unit length. This yields a largest cube in the disjoint cover corresponding to the DD. Therefore, it is not necessarily the largest implicant of f. Returns the largest cube as a BDD.]

SideEffects [The number of literals of the cube is returned in length.]

SeeAlso [Cudd_ShortestPath]

Definition at line 281 of file cuddSat.c.

00285 {
00286     register    DdNode  *F;
00287     st_table    *visited;
00288     DdNode      *sol;
00289     cuddPathPair *rootPair;
00290     int         complement, cost;
00291 
00292     one = DD_ONE(manager);
00293     zero = DD_ZERO(manager);
00294 
00295     if (f == Cudd_Not(one) || f == zero) {
00296         *length = DD_BIGGY;
00297         return(Cudd_Not(one));
00298     }
00299     /* From this point on, a path exists. */
00300 
00301     do {
00302         manager->reordered = 0;
00303 
00304         /* Initialize visited table. */
00305         visited = st_init_table(st_ptrcmp, st_ptrhash);
00306 
00307         /* Now get the length of the shortest path(s) from f to 1. */
00308         (void) getLargest(f, visited);
00309 
00310         complement = Cudd_IsComplement(f);
00311 
00312         F = Cudd_Regular(f);
00313 
00314         if (!st_lookup(visited, F, &rootPair)) return(NULL);
00315 
00316         if (complement) {
00317           cost = rootPair->neg;
00318         } else {
00319           cost = rootPair->pos;
00320         }
00321 
00322         /* Recover an actual shortest path. */
00323         sol = getCube(manager,visited,f,cost);
00324 
00325         st_foreach(visited, freePathPair, NULL);
00326         st_free_table(visited);
00327 
00328     } while (manager->reordered == 1);
00329 
00330     *length = cost;
00331     return(sol);
00332 
00333 } /* end of Cudd_LargestCube */

DdNode* Cudd_MakeBddFromZddCover ( 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.]

SideEffects []

SeeAlso [cuddMakeBddFromZddCover]

Definition at line 199 of file cuddZddIsop.c.

00202 {
00203     DdNode      *res;
00204 
00205     do {
00206         dd->reordered = 0;
00207         res = cuddMakeBddFromZddCover(dd, node);
00208     } while (dd->reordered == 1);
00209     return(res);
00210 } /* end of Cudd_MakeBddFromZddCover */

MtrNode* Cudd_MakeTreeNode ( DdManager dd,
unsigned int  low,
unsigned int  size,
unsigned int  type 
)

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

Synopsis [Creates a new variable group.]

Description [Creates a new variable group. The group starts at variable and contains size variables. The parameter low is the index of the first variable. If the variable already exists, its current position in the order is known to the manager. If the variable does not exist yet, the position is assumed to be the same as the index. The group tree is created if it does not exist yet. Returns a pointer to the group if successful; NULL otherwise.]

SideEffects [The variable tree is changed.]

SeeAlso [Cudd_MakeZddTreeNode]

Definition at line 202 of file cuddGroup.c.

00207 {
00208     MtrNode *group;
00209     MtrNode *tree;
00210     unsigned int level;
00211 
00212     /* If the variable does not exist yet, the position is assumed to be
00213     ** the same as the index. Therefore, applications that rely on
00214     ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new
00215     ** variables have to create the variables before they group them.
00216     */
00217     level = (low < (unsigned int) dd->size) ? dd->perm[low] : low;
00218 
00219     if (level + size - 1> (int) MTR_MAXHIGH)
00220         return(NULL);
00221 
00222     /* If the tree does not exist yet, create it. */
00223     tree = dd->tree;
00224     if (tree == NULL) {
00225         dd->tree = tree = Mtr_InitGroupTree(0, dd->size);
00226         if (tree == NULL)
00227             return(NULL);
00228         tree->index = dd->invperm[0];
00229     }
00230 
00231     /* Extend the upper bound of the tree if necessary. This allows the
00232     ** application to create groups even before the variables are created.
00233     */
00234     tree->size = ddMax(tree->size, ddMax(level + size, (unsigned) dd->size));
00235 
00236     /* Create the group. */
00237     group = Mtr_MakeGroup(tree, level, size, type);
00238     if (group == NULL)
00239         return(NULL);
00240 
00241     /* Initialize the index field to the index of the variable currently
00242     ** in position low. This field will be updated by the reordering
00243     ** procedure to provide a handle to the group once it has been moved.
00244     */
00245     group->index = (MtrHalfWord) low;
00246 
00247     return(group);
00248 
00249 } /* end of Cudd_MakeTreeNode */

MtrNode* Cudd_MakeZddTreeNode ( DdManager dd,
unsigned int  low,
unsigned int  size,
unsigned int  type 
)

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

Synopsis [Creates a new ZDD variable group.]

Description [Creates a new ZDD variable group. The group starts at variable and contains size variables. The parameter low is the index of the first variable. If the variable already exists, its current position in the order is known to the manager. If the variable does not exist yet, the position is assumed to be the same as the index. The group tree is created if it does not exist yet. Returns a pointer to the group if successful; NULL otherwise.]

SideEffects [The ZDD variable tree is changed.]

SeeAlso [Cudd_MakeTreeNode]

Definition at line 159 of file cuddZddGroup.c.

00164 {
00165     MtrNode *group;
00166     MtrNode *tree;
00167     unsigned int level;
00168 
00169     /* If the variable does not exist yet, the position is assumed to be
00170     ** the same as the index. Therefore, applications that rely on
00171     ** Cudd_bddNewVarAtLevel or Cudd_addNewVarAtLevel to create new
00172     ** variables have to create the variables before they group them.
00173     */
00174     level = (low < (unsigned int) dd->sizeZ) ? dd->permZ[low] : low;
00175 
00176     if (level + size - 1> (int) MTR_MAXHIGH)
00177         return(NULL);
00178 
00179     /* If the tree does not exist yet, create it. */
00180     tree = dd->treeZ;
00181     if (tree == NULL) {
00182         dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ);
00183         if (tree == NULL)
00184             return(NULL);
00185         tree->index = dd->invpermZ[0];
00186     }
00187 
00188     /* Extend the upper bound of the tree if necessary. This allows the
00189     ** application to create groups even before the variables are created.
00190     */
00191     tree->size = ddMax(tree->size, level + size);
00192 
00193     /* Create the group. */
00194     group = Mtr_MakeGroup(tree, level, size, type);
00195     if (group == NULL)
00196         return(NULL);
00197 
00198     /* Initialize the index field to the index of the variable currently
00199     ** in position low. This field will be updated by the reordering
00200     ** procedure to provide a handle to the group once it has been moved.
00201     */
00202     group->index = (MtrHalfWord) low;
00203 
00204     return(group);
00205 
00206 } /* end of Cudd_MakeZddTreeNode */

int Cudd_MinHammingDist ( DdManager dd,
DdNode f,
int *  minterm,
int  upperBound 
)

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

Synopsis [Returns the minimum Hamming distance between f and minterm.]

Description [Returns the minimum Hamming distance between the minterms of a function f and a reference minterm. The function is given as a BDD; the minterm is given as an array of integers, one for each variable in the manager. Returns the minimum distance if it is less than the upper bound; the upper bound if the minimum distance is at least as large; CUDD_OUT_OF_MEM in case of failure.]

SideEffects [None]

SeeAlso [Cudd_addHamming Cudd_bddClosestCube]

Definition at line 1314 of file cuddPriority.c.

01319 {
01320     DdHashTable *table;
01321     CUDD_VALUE_TYPE epsilon;
01322     int res;
01323 
01324     table = cuddHashTableInit(dd,1,2);
01325     if (table == NULL) {
01326         return(CUDD_OUT_OF_MEM);
01327     }
01328     epsilon = Cudd_ReadEpsilon(dd);
01329     Cudd_SetEpsilon(dd,(CUDD_VALUE_TYPE)0.0);
01330     res = cuddMinHammingDistRecur(f,minterm,table,upperBound);
01331     cuddHashTableQuit(table);
01332     Cudd_SetEpsilon(dd,epsilon);
01333 
01334     return(res);
01335 
01336 } /* end of Cudd_MinHammingDist */

DdApaNumber Cudd_NewApaNumber ( int  digits  ) 

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

Synopsis [Allocates memory for an arbitrary precision integer.]

Description [Allocates memory for an arbitrary precision integer. Returns a pointer to the allocated memory if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 170 of file cuddApa.c.

00172 {
00173     return(ALLOC(DdApaDigit, digits));
00174 
00175 } /* end of Cudd_NewApaNumber */

int Cudd_NextCube ( DdGen gen,
int **  cube,
CUDD_VALUE_TYPE *  value 
)

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

Synopsis [Generates the next cube of a decision diagram onset.]

Description [Generates the next cube of a decision diagram onset, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]

SideEffects [The cube and its value are returned as side effects. The generator is modified.]

SeeAlso [Cudd_ForeachCube Cudd_FirstCube Cudd_GenFree Cudd_IsGenEmpty Cudd_NextNode]

Definition at line 1913 of file cuddUtil.c.

01917 {
01918     DdNode *top, *treg, *next, *nreg, *prev, *preg;
01919     DdManager *dd = gen->manager;
01920 
01921     /* Backtrack from previously reached terminal node. */
01922     while (1) {
01923         if (gen->stack.sp == 1) {
01924             /* The current node has no predecessor. */
01925             gen->status = CUDD_GEN_EMPTY;
01926             gen->stack.sp--;
01927             goto done;
01928         }
01929         top = gen->stack.stack[gen->stack.sp-1];
01930         treg = Cudd_Regular(top);
01931         prev = gen->stack.stack[gen->stack.sp-2];
01932         preg = Cudd_Regular(prev);
01933         nreg = cuddT(preg);
01934         if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;}
01935         if (next != top) { /* follow the then branch next */
01936             gen->gen.cubes.cube[preg->index] = 1;
01937             gen->stack.stack[gen->stack.sp-1] = next;
01938             break;
01939         }
01940         /* Pop the stack and try again. */
01941         gen->gen.cubes.cube[preg->index] = 2;
01942         gen->stack.sp--;
01943     }
01944 
01945     while (1) {
01946         top = gen->stack.stack[gen->stack.sp-1];
01947         treg = Cudd_Regular(top);
01948         if (!cuddIsConstant(treg)) {
01949             /* Take the else branch first. */
01950             gen->gen.cubes.cube[treg->index] = 0;
01951             next = cuddE(treg);
01952             if (top != treg) next = Cudd_Not(next);
01953             gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++;
01954         } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) {
01955             /* Backtrack */
01956             while (1) {
01957                 if (gen->stack.sp == 1) {
01958                     /* The current node has no predecessor. */
01959                     gen->status = CUDD_GEN_EMPTY;
01960                     gen->stack.sp--;
01961                     goto done;
01962                 }
01963                 prev = gen->stack.stack[gen->stack.sp-2];
01964                 preg = Cudd_Regular(prev);
01965                 nreg = cuddT(preg);
01966                 if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;}
01967                 if (next != top) { /* follow the then branch next */
01968                     gen->gen.cubes.cube[preg->index] = 1;
01969                     gen->stack.stack[gen->stack.sp-1] = next;
01970                     break;
01971                 }
01972                 /* Pop the stack and try again. */
01973                 gen->gen.cubes.cube[preg->index] = 2;
01974                 gen->stack.sp--;
01975                 top = gen->stack.stack[gen->stack.sp-1];
01976                 treg = Cudd_Regular(top);
01977             }
01978         } else {
01979             gen->status = CUDD_GEN_NONEMPTY;
01980             gen->gen.cubes.value = cuddV(top);
01981             goto done;
01982         }
01983     }
01984 
01985 done:
01986     if (gen->status == CUDD_GEN_EMPTY) return(0);
01987     *cube = gen->gen.cubes.cube;
01988     *value = gen->gen.cubes.value;
01989     return(1);
01990 
01991 } /* end of Cudd_NextCube */

int Cudd_NextNode ( DdGen gen,
DdNode **  node 
)

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

Synopsis [Finds the next node of a decision diagram.]

Description [Finds the node of a decision diagram, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]

SideEffects [The next node is returned as a side effect.]

SeeAlso [Cudd_ForeachNode Cudd_FirstNode Cudd_GenFree Cudd_IsGenEmpty Cudd_NextCube]

Definition at line 2455 of file cuddUtil.c.

02458 {
02459     /* Find the next node. */
02460     gen->stack.sp++;
02461     if (gen->stack.sp < gen->gen.nodes.size) {
02462         gen->node = gen->stack.stack[gen->stack.sp];
02463         *node = gen->node;
02464         return(1);
02465     } else {
02466         gen->status = CUDD_GEN_EMPTY;
02467         return(0);
02468     }
02469 
02470 } /* end of Cudd_NextNode */

int Cudd_NextPrime ( DdGen gen,
int **  cube 
)

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

Synopsis [Generates the next prime of a Boolean function.]

Description [Generates the next cube of a Boolean function, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]

SideEffects [The cube and is returned as side effects. The generator is modified.]

SeeAlso [Cudd_ForeachPrime Cudd_FirstPrime Cudd_GenFree Cudd_IsGenEmpty Cudd_NextCube Cudd_NextNode]

Definition at line 2126 of file cuddUtil.c.

02129 {
02130     DdNode *implicant, *prime, *tmp;
02131     DdManager *dd = gen->manager;
02132     int length, result;
02133 
02134     if (gen->node == Cudd_ReadLogicZero(dd)) {
02135         gen->status = CUDD_GEN_EMPTY;
02136     } else {
02137         implicant = Cudd_LargestCube(dd,gen->node,&length);
02138         if (implicant == NULL) {
02139             gen->status = CUDD_GEN_EMPTY;
02140             return(0);
02141         }
02142         cuddRef(implicant);
02143         prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub);
02144         if (prime == NULL) {
02145             Cudd_RecursiveDeref(dd,implicant);
02146             gen->status = CUDD_GEN_EMPTY;
02147             return(0);
02148         }
02149         cuddRef(prime);
02150         Cudd_RecursiveDeref(dd,implicant);
02151         tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime));
02152         if (tmp == NULL) {
02153             Cudd_RecursiveDeref(dd,prime);
02154             gen->status = CUDD_GEN_EMPTY;
02155             return(0);
02156         }
02157         cuddRef(tmp);
02158         Cudd_RecursiveDeref(dd,gen->node);
02159         gen->node = tmp;
02160         result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube);
02161         if (result == 0) {
02162             Cudd_RecursiveDeref(dd,prime);
02163             gen->status = CUDD_GEN_EMPTY;
02164             return(0);
02165         }
02166         Cudd_RecursiveDeref(dd,prime);
02167         gen->status = CUDD_GEN_NONEMPTY;
02168     }
02169     if (gen->status == CUDD_GEN_EMPTY) return(0);
02170     *cube = gen->gen.primes.cube;
02171     return(1);
02172 
02173 } /* end of Cudd_NextPrime */

unsigned int Cudd_NodeReadIndex ( DdNode node  ) 

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

Synopsis [Returns the index of the node.]

Description [Returns the index of the node. The node pointer can be either regular or complemented.]

SideEffects [None]

SeeAlso [Cudd_ReadIndex]

Definition at line 2273 of file cuddAPI.c.

02275 {
02276     return((unsigned int) Cudd_Regular(node)->index);
02277 
02278 } /* end of Cudd_NodeReadIndex */

void Cudd_OutOfMem ( long  size  ) 

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

Synopsis [Warns that a memory allocation failed.]

Description [Warns that a memory allocation failed. This function can be used as replacement of MMout_of_memory to prevent the safe_mem functions of the util package from exiting when malloc returns NULL. One possible use is in case of discretionary allocations; for instance, the allocation of memory to enlarge the computed table.]

SideEffects [None]

SeeAlso []

Definition at line 2833 of file cuddUtil.c.

02835 {
02836     (void) fflush(stdout);
02837     (void) fprintf(stderr, "\nunable to allocate %ld bytes\n", size);
02838     return;
02839 
02840 } /* end of Cudd_OutOfMem */

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

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

Synopsis [Extracts a dense superset from a BDD with Shiple's underapproximation method.]

Description [Extracts a dense superset from a BDD. The procedure is identical to the underapproximation procedure except for the fact that it works on the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. Returns a pointer to the BDD of the superset if successful. NULL if intermediate result causes the procedure to run out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize]

Definition at line 271 of file cuddApprox.c.

00278 {
00279     DdNode *subset, *g;
00280 
00281     g = Cudd_Not(f);    
00282     do {
00283         dd->reordered = 0;
00284         subset = cuddUnderApprox(dd, g, numVars, threshold, safe, quality);
00285     } while (dd->reordered == 1);
00286     
00287     return(Cudd_NotCond(subset, (subset != NULL)));
00288     
00289 } /* end of Cudd_OverApprox */

unsigned int Cudd_Prime ( unsigned int  p  ) 

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

Synopsis [Returns the next prime >= p.]

Description []

SideEffects [None]

Definition at line 184 of file cuddTable.c.

00186 {
00187     int i,pn;
00188 
00189     p--;
00190     do {
00191         p++;
00192         if (p&1) {
00193             pn = 1;
00194             i = 3;
00195             while ((unsigned) (i * i) <= p) {
00196                 if (p % i == 0) {
00197                     pn = 0;
00198                     break;
00199                 }
00200                 i += 2;
00201             }
00202         } else {
00203             pn = 0;
00204         }
00205     } while (!pn);
00206     return(p);
00207 
00208 } /* end of Cudd_Prime */

int Cudd_PrintDebug ( DdManager dd,
DdNode f,
int  n,
int  pr 
)

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

Synopsis [Prints to the standard output a DD and its statistics.]

Description [Prints to the standard output a DD and its statistics. The statistics include the number of nodes, the number of leaves, and the number of minterms. (The number of minterms is the number of assignments to the variables that cause the function to be different from the logical zero (for BDDs) and from the background value (for ADDs.) The statistics are printed if pr > 0. Specifically:

  • pr = 0 : prints nothing
  • pr = 1 : prints counts of nodes and minterms
  • pr = 2 : prints counts + disjoint sum of product
  • pr = 3 : prints counts + list of nodes
  • pr > 3 : prints counts + disjoint sum of product + list of nodes

For the purpose of counting the number of minterms, the function is supposed to depend on n variables. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_DagSize Cudd_CountLeaves Cudd_CountMinterm Cudd_PrintMinterm]

Definition at line 378 of file cuddUtil.c.

00383 {
00384     DdNode *azero, *bzero;
00385     int    nodes;
00386     int    leaves;
00387     double minterms;
00388     int    retval = 1;
00389 
00390     if (f == NULL) {
00391         (void) fprintf(dd->out,": is the NULL DD\n");
00392         (void) fflush(dd->out);
00393         return(0);
00394     }
00395     azero = DD_ZERO(dd);
00396     bzero = Cudd_Not(DD_ONE(dd));
00397     if ((f == azero || f == bzero) && pr > 0){
00398        (void) fprintf(dd->out,": is the zero DD\n");
00399        (void) fflush(dd->out);
00400        return(1);
00401     }
00402     if (pr > 0) {
00403         nodes = Cudd_DagSize(f);
00404         if (nodes == CUDD_OUT_OF_MEM) retval = 0;
00405         leaves = Cudd_CountLeaves(f);
00406         if (leaves == CUDD_OUT_OF_MEM) retval = 0;
00407         minterms = Cudd_CountMinterm(dd, f, n);
00408         if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0;
00409         (void) fprintf(dd->out,": %d nodes %d leaves %g minterms\n",
00410                        nodes, leaves, minterms);
00411         if (pr > 2) {
00412             if (!cuddP(dd, f)) retval = 0;
00413         }
00414         if (pr == 2 || pr > 3) {
00415             if (!Cudd_PrintMinterm(dd,f)) retval = 0;
00416             (void) fprintf(dd->out,"\n");
00417         }
00418         (void) fflush(dd->out);
00419     }
00420     return(retval);
00421 
00422 } /* end of Cudd_PrintDebug */

int Cudd_PrintInfo ( DdManager dd,
FILE *  fp 
)

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

Synopsis [Prints out statistics and settings for a CUDD manager.]

Description [Prints out statistics and settings for a CUDD manager. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 2933 of file cuddAPI.c.

02936 {
02937     int retval;
02938     Cudd_ReorderingType autoMethod, autoMethodZ;
02939 
02940     /* Modifiable parameters. */
02941     retval = fprintf(fp,"**** CUDD modifiable parameters ****\n");
02942     if (retval == EOF) return(0);
02943     retval = fprintf(fp,"Hard limit for cache size: %u\n",
02944                      Cudd_ReadMaxCacheHard(dd));
02945     if (retval == EOF) return(0);
02946     retval = fprintf(fp,"Cache hit threshold for resizing: %u%%\n",
02947                      Cudd_ReadMinHit(dd));
02948     if (retval == EOF) return(0);
02949     retval = fprintf(fp,"Garbage collection enabled: %s\n",
02950                      Cudd_GarbageCollectionEnabled(dd) ? "yes" : "no");
02951     if (retval == EOF) return(0);
02952     retval = fprintf(fp,"Limit for fast unique table growth: %u\n",
02953                      Cudd_ReadLooseUpTo(dd));
02954     if (retval == EOF) return(0);
02955     retval = fprintf(fp,
02956                      "Maximum number of variables sifted per reordering: %d\n",
02957                      Cudd_ReadSiftMaxVar(dd));
02958     if (retval == EOF) return(0);
02959     retval = fprintf(fp,
02960                      "Maximum number of variable swaps per reordering: %d\n",
02961                      Cudd_ReadSiftMaxSwap(dd));
02962     if (retval == EOF) return(0);
02963     retval = fprintf(fp,"Maximum growth while sifting a variable: %g\n",
02964                      Cudd_ReadMaxGrowth(dd));
02965     if (retval == EOF) return(0);
02966     retval = fprintf(fp,"Dynamic reordering of BDDs enabled: %s\n",
02967                      Cudd_ReorderingStatus(dd,&autoMethod) ? "yes" : "no");
02968     if (retval == EOF) return(0);
02969     retval = fprintf(fp,"Default BDD reordering method: %d\n",
02970                      (int) autoMethod);
02971     if (retval == EOF) return(0);
02972     retval = fprintf(fp,"Dynamic reordering of ZDDs enabled: %s\n",
02973                      Cudd_ReorderingStatusZdd(dd,&autoMethodZ) ? "yes" : "no");
02974     if (retval == EOF) return(0);
02975     retval = fprintf(fp,"Default ZDD reordering method: %d\n",
02976                      (int) autoMethodZ);
02977     if (retval == EOF) return(0);
02978     retval = fprintf(fp,"Realignment of ZDDs to BDDs enabled: %s\n",
02979                      Cudd_zddRealignmentEnabled(dd) ? "yes" : "no");
02980     if (retval == EOF) return(0);
02981     retval = fprintf(fp,"Realignment of BDDs to ZDDs enabled: %s\n",
02982                      Cudd_bddRealignmentEnabled(dd) ? "yes" : "no");
02983     if (retval == EOF) return(0);
02984     retval = fprintf(fp,"Dead nodes counted in triggering reordering: %s\n",
02985                      Cudd_DeadAreCounted(dd) ? "yes" : "no");
02986     if (retval == EOF) return(0);
02987     retval = fprintf(fp,"Group checking criterion: %d\n",
02988                      (int) Cudd_ReadGroupcheck(dd));
02989     if (retval == EOF) return(0);
02990     retval = fprintf(fp,"Recombination threshold: %d\n", Cudd_ReadRecomb(dd));
02991     if (retval == EOF) return(0);
02992     retval = fprintf(fp,"Symmetry violation threshold: %d\n",
02993                      Cudd_ReadSymmviolation(dd));
02994     if (retval == EOF) return(0);
02995     retval = fprintf(fp,"Arc violation threshold: %d\n",
02996                      Cudd_ReadArcviolation(dd));
02997     if (retval == EOF) return(0);
02998     retval = fprintf(fp,"GA population size: %d\n",
02999                      Cudd_ReadPopulationSize(dd));
03000     if (retval == EOF) return(0);
03001     retval = fprintf(fp,"Number of crossovers for GA: %d\n",
03002                      Cudd_ReadNumberXovers(dd));
03003     if (retval == EOF) return(0);
03004     retval = fprintf(fp,"Next reordering threshold: %u\n",
03005                      Cudd_ReadNextReordering(dd));
03006     if (retval == EOF) return(0);
03007 
03008     /* Non-modifiable parameters. */
03009     retval = fprintf(fp,"**** CUDD non-modifiable parameters ****\n");
03010     if (retval == EOF) return(0);
03011     retval = fprintf(fp,"Memory in use: %lu\n", Cudd_ReadMemoryInUse(dd));
03012     if (retval == EOF) return(0);
03013     retval = fprintf(fp,"Peak number of nodes: %ld\n",
03014                      Cudd_ReadPeakNodeCount(dd));
03015     if (retval == EOF) return(0);
03016     retval = fprintf(fp,"Peak number of live nodes: %d\n",
03017                      Cudd_ReadPeakLiveNodeCount(dd));
03018     if (retval == EOF) return(0);
03019     retval = fprintf(fp,"Number of BDD variables: %d\n", dd->size);
03020     if (retval == EOF) return(0);
03021     retval = fprintf(fp,"Number of ZDD variables: %d\n", dd->sizeZ);
03022     if (retval == EOF) return(0);
03023     retval = fprintf(fp,"Number of cache entries: %u\n", dd->cacheSlots);
03024     if (retval == EOF) return(0);
03025     retval = fprintf(fp,"Number of cache look-ups: %.0f\n",
03026                      Cudd_ReadCacheLookUps(dd));
03027     if (retval == EOF) return(0);
03028     retval = fprintf(fp,"Number of cache hits: %.0f\n",
03029                      Cudd_ReadCacheHits(dd));
03030     if (retval == EOF) return(0);
03031     retval = fprintf(fp,"Number of cache insertions: %.0f\n",
03032                      dd->cacheinserts);
03033     if (retval == EOF) return(0);
03034     retval = fprintf(fp,"Number of cache collisions: %.0f\n",
03035                      dd->cachecollisions);
03036     if (retval == EOF) return(0);
03037     retval = fprintf(fp,"Number of cache deletions: %.0f\n",
03038                      dd->cachedeletions);
03039     if (retval == EOF) return(0);
03040     retval = cuddCacheProfile(dd,fp);
03041     if (retval == 0) return(0);
03042     retval = fprintf(fp,"Soft limit for cache size: %u\n",
03043                      Cudd_ReadMaxCache(dd));
03044     if (retval == EOF) return(0);
03045     retval = fprintf(fp,"Number of buckets in unique table: %u\n", dd->slots);
03046     if (retval == EOF) return(0);
03047     retval = fprintf(fp,"Used buckets in unique table: %.2f%% (expected %.2f%%)\n",
03048                      100.0 * Cudd_ReadUsedSlots(dd),
03049                      100.0 * Cudd_ExpectedUsedSlots(dd));
03050     if (retval == EOF) return(0);
03051 #ifdef DD_UNIQUE_PROFILE
03052     retval = fprintf(fp,"Unique lookups: %.0f\n", dd->uniqueLookUps);
03053     if (retval == EOF) return(0);
03054     retval = fprintf(fp,"Unique links: %.0f (%g per lookup)\n",
03055             dd->uniqueLinks, dd->uniqueLinks / dd->uniqueLookUps);
03056     if (retval == EOF) return(0);
03057 #endif
03058     retval = fprintf(fp,"Number of BDD and ADD nodes: %u\n", dd->keys);
03059     if (retval == EOF) return(0);
03060     retval = fprintf(fp,"Number of ZDD nodes: %u\n", dd->keysZ);
03061     if (retval == EOF) return(0);
03062     retval = fprintf(fp,"Number of dead BDD and ADD nodes: %u\n", dd->dead);
03063     if (retval == EOF) return(0);
03064     retval = fprintf(fp,"Number of dead ZDD nodes: %u\n", dd->deadZ);
03065     if (retval == EOF) return(0);
03066     retval = fprintf(fp,"Total number of nodes allocated: %.0f\n",
03067                      dd->allocated);
03068     if (retval == EOF) return(0);
03069     retval = fprintf(fp,"Total number of nodes reclaimed: %.0f\n",
03070                      dd->reclaimed);
03071     if (retval == EOF) return(0);
03072 #ifdef DD_STATS
03073     retval = fprintf(fp,"Nodes freed: %.0f\n", dd->nodesFreed);
03074     if (retval == EOF) return(0);
03075     retval = fprintf(fp,"Nodes dropped: %.0f\n", dd->nodesDropped);
03076     if (retval == EOF) return(0);
03077 #endif
03078 #ifdef DD_COUNT
03079     retval = fprintf(fp,"Number of recursive calls: %.0f\n",
03080                      Cudd_ReadRecursiveCalls(dd));
03081     if (retval == EOF) return(0);
03082 #endif
03083     retval = fprintf(fp,"Garbage collections so far: %d\n",
03084                      Cudd_ReadGarbageCollections(dd));
03085     if (retval == EOF) return(0);
03086     retval = fprintf(fp,"Time for garbage collection: %.2f sec\n",
03087                      ((double)Cudd_ReadGarbageCollectionTime(dd)/1000.0));
03088     if (retval == EOF) return(0);
03089     retval = fprintf(fp,"Reorderings so far: %d\n", dd->reorderings);
03090     if (retval == EOF) return(0);
03091     retval = fprintf(fp,"Time for reordering: %.2f sec\n",
03092                      ((double)Cudd_ReadReorderingTime(dd)/1000.0));
03093     if (retval == EOF) return(0);
03094 #ifdef DD_COUNT
03095     retval = fprintf(fp,"Node swaps in reordering: %.0f\n",
03096         Cudd_ReadSwapSteps(dd));
03097     if (retval == EOF) return(0);
03098 #endif
03099 
03100     return(1);
03101 
03102 } /* end of Cudd_PrintInfo */

int Cudd_PrintLinear ( DdManager table  ) 

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

Synopsis [Prints the linear transform matrix.]

Description [Prints the linear transform matrix. Returns 1 in case of success; 0 otherwise.]

SideEffects [none]

SeeAlso []

Definition at line 149 of file cuddLinear.c.

00151 {
00152     int i,j,k;
00153     int retval;
00154     int nvars = table->linearSize;
00155     int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
00156     long word;
00157 
00158     for (i = 0; i < nvars; i++) {
00159         for (j = 0; j < wordsPerRow; j++) {
00160             word = table->linear[i*wordsPerRow + j];
00161             for (k = 0; k < BPL; k++) {
00162                 retval = fprintf(table->out,"%ld",word & 1);
00163                 if (retval == 0) return(0);
00164                 word >>= 1;
00165             }
00166         }
00167         retval = fprintf(table->out,"\n");
00168         if (retval == 0) return(0);
00169     }
00170     return(1);
00171 
00172 } /* end of Cudd_PrintLinear */

int Cudd_PrintMinterm ( DdManager manager,
DdNode node 
)

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

Synopsis [Prints a disjoint sum of products.]

Description [Prints a disjoint sum of product cover for the function rooted at node. Each product corresponds to a path from node to a leaf node different from the logical zero, and different from the background value. Uses the package default output file. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_PrintDebug Cudd_bddPrintCover]

Definition at line 212 of file cuddUtil.c.

00215 {
00216     int         i, *list;
00217 
00218     background = manager->background;
00219     zero = Cudd_Not(manager->one);
00220     list = ALLOC(int,manager->size);
00221     if (list == NULL) {
00222         manager->errorCode = CUDD_MEMORY_OUT;
00223         return(0);
00224     }
00225     for (i = 0; i < manager->size; i++) list[i] = 2;
00226     ddPrintMintermAux(manager,node,list);
00227     FREE(list);
00228     return(1);
00229 
00230 } /* end of Cudd_PrintMinterm */

int Cudd_PrintTwoLiteralClauses ( DdManager dd,
DdNode f,
char **  names,
FILE *  fp 
)

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

Synopsis [Prints the two literal clauses of a DD.]

Description [Prints the one- and two-literal clauses. Returns 1 if successful; 0 otherwise. The argument "names" can be NULL, in which case the variable indices are printed.]

SideEffects [None]

SeeAlso [Cudd_FindTwoLiteralClauses]

Definition at line 389 of file cuddEssent.c.

00394 {
00395     DdHalfWord *vars;
00396     BitVector *phases;
00397     int i;
00398     DdTlcInfo *res = Cudd_FindTwoLiteralClauses(dd, f);
00399     FILE *ifp = fp == NULL ? dd->out : fp;
00400 
00401     if (res == NULL) return(0);
00402     vars = res->vars;
00403     phases = res->phases;
00404     for (i = 0; !sentinelp(vars[i], vars[i+1]); i += 2) {
00405         if (names != NULL) {
00406             if (vars[i+1] == CUDD_MAXINDEX) {
00407                 (void) fprintf(ifp, "%s%s\n",
00408                                bitVectorRead(phases, i) ? "~" : " ",
00409                                names[vars[i]]);
00410             } else {
00411                 (void) fprintf(ifp, "%s%s | %s%s\n",
00412                                bitVectorRead(phases, i) ? "~" : " ",
00413                                names[vars[i]],
00414                                bitVectorRead(phases, i+1) ? "~" : " ",
00415                                names[vars[i+1]]);
00416             }
00417         } else {
00418             if (vars[i+1] == CUDD_MAXINDEX) {
00419                 (void) fprintf(ifp, "%s%d\n",
00420                                bitVectorRead(phases, i) ? "~" : " ",
00421                                (int) vars[i]);
00422             } else {
00423                 (void) fprintf(ifp, "%s%d | %s%d\n",
00424                                bitVectorRead(phases, i) ? "~" : " ",
00425                                (int) vars[i],
00426                                bitVectorRead(phases, i+1) ? "~" : " ",
00427                                (int) vars[i+1]);
00428             }
00429         }
00430     }
00431     Cudd_tlcInfoFree(res);
00432 
00433     return(1);
00434 
00435 } /* end of Cudd_PrintTwoLiteralClauses */

void Cudd_PrintVersion ( FILE *  fp  ) 

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

Synopsis [Prints the package version number.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 2588 of file cuddUtil.c.

02590 {
02591     (void) fprintf(fp, "%s\n", CUDD_VERSION);
02592 
02593 } /* end of Cudd_PrintVersion */

DdNode* Cudd_PrioritySelect ( DdManager dd,
DdNode R,
DdNode **  x,
DdNode **  y,
DdNode **  z,
DdNode Pi,
int  n,
DdNode *)(DdManager *, int, DdNode **, DdNode **, DdNode ** 
)
void Cudd_Quit ( DdManager unique  ) 

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

Synopsis [Deletes resources associated with a DD manager.]

Description [Deletes resources associated with a DD manager and resets the global statistical counters. (Otherwise, another manaqger subsequently created would inherit the stats of this one.)]

SideEffects [None]

SeeAlso [Cudd_Init]

Definition at line 218 of file cuddInit.c.

00220 {
00221     if (unique->stash != NULL) FREE(unique->stash);
00222     cuddFreeTable(unique);
00223 
00224 } /* end of Cudd_Quit */

long Cudd_Random ( void   ) 

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

Synopsis [Portable random number generator.]

Description [Portable number generator based on ran2 from "Numerical Recipes in C." It is a long period (> 2 * 10^18) random number generator of L'Ecuyer with Bays-Durham shuffle. Returns a long integer uniformly distributed between 0 and 2147483561 (inclusive of the endpoint values). The random generator can be explicitly initialized by calling Cudd_Srandom. If no explicit initialization is performed, then the seed 1 is assumed.]

SideEffects [None]

SeeAlso [Cudd_Srandom]

Definition at line 2698 of file cuddUtil.c.

02699 {
02700     int i;      /* index in the shuffle table */
02701     long int w; /* work variable */
02702 
02703     /* cuddRand == 0 if the geneartor has not been initialized yet. */
02704     if (cuddRand == 0) Cudd_Srandom(1);
02705 
02706     /* Compute cuddRand = (cuddRand * LEQA1) % MODULUS1 avoiding
02707     ** overflows by Schrage's method.
02708     */
02709     w          = cuddRand / LEQQ1;
02710     cuddRand   = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1;
02711     cuddRand  += (cuddRand < 0) * MODULUS1;
02712 
02713     /* Compute cuddRand2 = (cuddRand2 * LEQA2) % MODULUS2 avoiding
02714     ** overflows by Schrage's method.
02715     */
02716     w          = cuddRand2 / LEQQ2;
02717     cuddRand2  = LEQA2 * (cuddRand2 - w * LEQQ2) - w * LEQR2;
02718     cuddRand2 += (cuddRand2 < 0) * MODULUS2;
02719 
02720     /* cuddRand is shuffled with the Bays-Durham algorithm.
02721     ** shuffleSelect and cuddRand2 are combined to generate the output.
02722     */
02723 
02724     /* Pick one element from the shuffle table; "i" will be in the range
02725     ** from 0 to STAB_SIZE-1.
02726     */
02727     i = (int) (shuffleSelect / STAB_DIV);
02728     /* Mix the element of the shuffle table with the current iterate of
02729     ** the second sub-generator, and replace the chosen element of the
02730     ** shuffle table with the current iterate of the first sub-generator.
02731     */
02732     shuffleSelect   = shuffleTable[i] - cuddRand2;
02733     shuffleTable[i] = cuddRand;
02734     shuffleSelect  += (shuffleSelect < 1) * (MODULUS1 - 1);
02735     /* Since shuffleSelect != 0, and we want to be able to return 0,
02736     ** here we subtract 1 before returning.
02737     */
02738     return(shuffleSelect - 1);
02739 
02740 } /* end of Cudd_Random */

int Cudd_ReadArcviolation ( DdManager dd  ) 

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

Synopsis [Returns the current value of the arcviolation parameter used in group sifting.]

Description [Returns the current value of the arcviolation parameter. This parameter is used in group sifting to decide how many arcs into y not coming from x are tolerable when checking for aggregation due to extended symmetry. The value should be between 0 and 100. A small value causes fewer variables to be aggregated. The default value is 0.]

SideEffects [None]

SeeAlso [Cudd_SetArcviolation]

Definition at line 2760 of file cuddAPI.c.

02762 {
02763     return(dd->arcviolation);
02764 
02765 } /* end of Cudd_ReadArcviolation */

DdNode* Cudd_ReadBackground ( DdManager dd  ) 

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

Synopsis [Reads the background constant of the manager.]

Description []

SideEffects [None]

Definition at line 1108 of file cuddAPI.c.

01110 {
01111     return(dd->background);
01112 
01113 } /* end of Cudd_ReadBackground */

double Cudd_ReadCacheHits ( DdManager dd  ) 

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

Synopsis [Returns the number of cache hits.]

Description []

SideEffects [None]

SeeAlso [Cudd_ReadCacheLookUps]

Definition at line 1221 of file cuddAPI.c.

01223 {
01224     return(dd->cacheHits + dd->totCachehits);
01225 
01226 } /* end of Cudd_ReadCacheHits */

double Cudd_ReadCacheLookUps ( DdManager dd  ) 

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

Synopsis [Returns the number of cache look-ups.]

Description [Returns the number of cache look-ups.]

SideEffects [None]

SeeAlso [Cudd_ReadCacheHits]

Definition at line 1200 of file cuddAPI.c.

01202 {
01203     return(dd->cacheHits + dd->cacheMisses +
01204            dd->totCachehits + dd->totCacheMisses);
01205 
01206 } /* end of Cudd_ReadCacheLookUps */

unsigned int Cudd_ReadCacheSlots ( DdManager dd  ) 

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

Synopsis [Reads the number of slots in the cache.]

Description []

SideEffects [None]

SeeAlso [Cudd_ReadCacheUsedSlots]

Definition at line 1148 of file cuddAPI.c.

01150 {
01151     return(dd->cacheSlots);
01152 
01153 } /* end of Cudd_ReadCacheSlots */

double Cudd_ReadCacheUsedSlots ( DdManager dd  ) 

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

Synopsis [Reads the fraction of used slots in the cache.]

Description [Reads the fraction of used slots in the cache. The unused slots are those in which no valid data is stored. Garbage collection, variable reordering, and cache resizing may cause used slots to become unused.]

SideEffects [None]

SeeAlso [Cudd_ReadCacheSlots]

Definition at line 1171 of file cuddAPI.c.

01173 {
01174     unsigned long used = 0;
01175     int slots = dd->cacheSlots;
01176     DdCache *cache = dd->cache;
01177     int i;
01178 
01179     for (i = 0; i < slots; i++) {
01180         used += cache[i].h != 0;
01181     }
01182 
01183     return((double)used / (double) dd->cacheSlots);
01184 
01185 } /* end of Cudd_ReadCacheUsedSlots */

unsigned int Cudd_ReadDead ( DdManager dd  ) 

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

Synopsis [Returns the number of dead nodes in the unique table.]

Description []

SideEffects [None]

SeeAlso [Cudd_ReadKeys]

Definition at line 1642 of file cuddAPI.c.

01644 {
01645     return(dd->dead);
01646 
01647 } /* end of Cudd_ReadDead */

CUDD_VALUE_TYPE Cudd_ReadEpsilon ( DdManager dd  ) 

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

Synopsis [Reads the epsilon parameter of the manager.]

Description [Reads the epsilon parameter of the manager. The epsilon parameter control the comparison between floating point numbers.]

SideEffects [None]

SeeAlso [Cudd_SetEpsilon]

Definition at line 2426 of file cuddAPI.c.

02428 {
02429     return(dd->epsilon);
02430 
02431 } /* end of Cudd_ReadEpsilon */

Cudd_ErrorType Cudd_ReadErrorCode ( DdManager dd  ) 

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

Synopsis [Returns the code of the last error.]

Description [Returns the code of the last error. The error codes are defined in cudd.h.]

SideEffects [None]

SeeAlso [Cudd_ClearErrorCode]

Definition at line 3609 of file cuddAPI.c.

03611 {
03612     return(dd->errorCode);
03613 
03614 } /* end of Cudd_ReadErrorCode */

int Cudd_ReadGarbageCollections ( DdManager dd  ) 

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

Synopsis [Returns the number of times garbage collection has occurred.]

Description [Returns the number of times garbage collection has occurred in the manager. The number includes both the calls from reordering procedures and those caused by requests to create new nodes.]

SideEffects [None]

SeeAlso [Cudd_ReadGarbageCollectionTime]

Definition at line 1737 of file cuddAPI.c.

01739 {
01740     return(dd->garbageCollections);
01741 
01742 } /* end of Cudd_ReadGarbageCollections */

long Cudd_ReadGarbageCollectionTime ( DdManager dd  ) 

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

Synopsis [Returns the time spent in garbage collection.]

Description [Returns the number of milliseconds spent doing garbage collection since the manager was initialized.]

SideEffects [None]

SeeAlso [Cudd_ReadGarbageCollections]

Definition at line 1758 of file cuddAPI.c.

01760 {
01761     return(dd->GCTime);
01762 
01763 } /* end of Cudd_ReadGarbageCollectionTime */

Cudd_AggregationType Cudd_ReadGroupcheck ( DdManager dd  ) 

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

Synopsis [Reads the groupcheck parameter of the manager.]

Description [Reads the groupcheck parameter of the manager. The groupcheck parameter determines the aggregation criterion in group sifting.]

SideEffects [None]

SeeAlso [Cudd_SetGroupcheck]

Definition at line 2470 of file cuddAPI.c.

02472 {
02473     return(dd->groupcheck);
02474 
02475 } /* end of Cudd_ReadGroupCheck */

int Cudd_ReadInvPerm ( DdManager dd,
int  i 
)

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

Synopsis [Returns the index of the variable currently in the i-th position of the order.]

Description [Returns the index of the variable currently in the i-th position of the order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]

SideEffects [None]

SeeAlso [Cudd_ReadPerm Cudd_ReadInvPermZdd]

Definition at line 2350 of file cuddAPI.c.

02353 {
02354     if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
02355     if (i < 0 || i >= dd->size) return(-1);
02356     return(dd->invperm[i]);
02357 
02358 } /* end of Cudd_ReadInvPerm */

int Cudd_ReadInvPermZdd ( DdManager dd,
int  i 
)

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

Synopsis [Returns the index of the ZDD variable currently in the i-th position of the order.]

Description [Returns the index of the ZDD variable currently in the i-th position of the order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]

SideEffects [None]

SeeAlso [Cudd_ReadPerm Cudd_ReadInvPermZdd]

Definition at line 2376 of file cuddAPI.c.

02379 {
02380     if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
02381     if (i < 0 || i >= dd->sizeZ) return(-1);
02382     return(dd->invpermZ[i]);
02383 
02384 } /* end of Cudd_ReadInvPermZdd */

int Cudd_ReadIthClause ( DdTlcInfo tlc,
int  i,
DdHalfWord var1,
DdHalfWord var2,
int *  phase1,
int *  phase2 
)

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

Synopsis [Accesses the i-th clause of a DD.]

Description [Accesses the i-th clause of a DD given the clause set which must be already computed. Returns 1 if successful; 0 if i is out of range, or in case of error.]

SideEffects [the four components of a clause are returned as side effects.]

SeeAlso [Cudd_FindTwoLiteralClauses]

Definition at line 355 of file cuddEssent.c.

00362 {
00363     if (tlc == NULL) return(0);
00364     if (tlc->vars == NULL || tlc->phases == NULL) return(0);
00365     if (i < 0 || (unsigned) i >= tlc->cnt) return(0);
00366     *var1 = tlc->vars[2*i];
00367     *var2 = tlc->vars[2*i+1];
00368     *phase1 = (int) bitVectorRead(tlc->phases, 2*i);
00369     *phase2 = (int) bitVectorRead(tlc->phases, 2*i+1);
00370     return(1);
00371 
00372 } /* end of Cudd_ReadIthClause */

unsigned int Cudd_ReadKeys ( DdManager dd  ) 

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

Synopsis [Returns the number of nodes in the unique table.]

Description [Returns the total number of nodes currently in the unique table, including the dead nodes.]

SideEffects [None]

SeeAlso [Cudd_ReadDead]

Definition at line 1622 of file cuddAPI.c.

01624 {
01625     return(dd->keys);
01626 
01627 } /* end of Cudd_ReadKeys */

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

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

Synopsis [Reads an entry of the linear transform matrix.]

Description [Reads an entry of the linear transform matrix.]

SideEffects [none]

SeeAlso []

Definition at line 187 of file cuddLinear.c.

00191 {
00192     int nvars = table->size;
00193     int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
00194     long word;
00195     int bit;
00196     int result;
00197 
00198     assert(table->size == table->linearSize);
00199 
00200     word = wordsPerRow * x + (y >> LOGBPL);
00201     bit  = y & (BPL-1);
00202     result = (int) ((table->linear[word] >> bit) & 1);
00203     return(result);
00204 
00205 } /* end of Cudd_ReadLinear */

DdNode* Cudd_ReadLogicZero ( DdManager dd  ) 

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

Synopsis [Returns the logic zero constant of the manager.]

Description [Returns the zero constant of the manager. The logic zero constant is the complement of the one constant, and is distinct from the arithmetic zero.]

SideEffects [None]

SeeAlso [Cudd_ReadOne Cudd_ReadZero]

Definition at line 1054 of file cuddAPI.c.

01056 {
01057     return(Cudd_Not(DD_ONE(dd)));
01058 
01059 } /* end of Cudd_ReadLogicZero */

unsigned int Cudd_ReadLooseUpTo ( DdManager dd  ) 

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

Synopsis [Reads the looseUpTo parameter of the manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_SetLooseUpTo Cudd_ReadMinHit Cudd_ReadMinDead]

Definition at line 1317 of file cuddAPI.c.

01319 {
01320     return(dd->looseUpTo);
01321 
01322 } /* end of Cudd_ReadLooseUpTo */

unsigned int Cudd_ReadMaxCache ( DdManager dd  ) 

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

Synopsis [Returns the soft limit for the cache size.]

Description [Returns the soft limit for the cache size. The soft limit]

SideEffects [None]

SeeAlso [Cudd_ReadMaxCache]

Definition at line 1367 of file cuddAPI.c.

01369 {
01370     return(2 * dd->cacheSlots + dd->cacheSlack);
01371 
01372 } /* end of Cudd_ReadMaxCache */

unsigned int Cudd_ReadMaxCacheHard ( DdManager dd  ) 

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

Synopsis [Reads the maxCacheHard parameter of the manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_SetMaxCacheHard Cudd_ReadMaxCache]

Definition at line 1387 of file cuddAPI.c.

01389 {
01390     return(dd->maxCacheHard);
01391 
01392 } /* end of Cudd_ReadMaxCache */

double Cudd_ReadMaxGrowth ( DdManager dd  ) 

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

Synopsis [Reads the maxGrowth parameter of the manager.]

Description [Reads the maxGrowth parameter of the manager. This parameter determines how much the number of nodes can grow during sifting of a variable. Overall, sifting never increases the size of the decision diagrams. This parameter only refers to intermediate results. A lower value will speed up sifting, possibly at the expense of quality.]

SideEffects [None]

SeeAlso [Cudd_SetMaxGrowth Cudd_ReadMaxGrowthAlternate]

Definition at line 1984 of file cuddAPI.c.

01986 {
01987     return(dd->maxGrowth);
01988 
01989 } /* end of Cudd_ReadMaxGrowth */

double Cudd_ReadMaxGrowthAlternate ( DdManager dd  ) 

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

Synopsis [Reads the maxGrowthAlt parameter of the manager.]

Description [Reads the maxGrowthAlt parameter of the manager. This parameter is analogous to the maxGrowth paramter, and is used every given number of reorderings instead of maxGrowth. The number of reorderings is set with Cudd_SetReorderingCycle. If the number of reorderings is 0 (default) maxGrowthAlt is never used.]

SideEffects [None]

SeeAlso [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate Cudd_SetReorderingCycle Cudd_ReadReorderingCycle]

Definition at line 2035 of file cuddAPI.c.

02037 {
02038     return(dd->maxGrowthAlt);
02039 
02040 } /* end of Cudd_ReadMaxGrowthAlternate */

unsigned int Cudd_ReadMaxLive ( DdManager dd  ) 

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

Synopsis [Reads the maximum allowed number of live nodes.]

Description [Reads the maximum allowed number of live nodes. When this number is exceeded, the package returns NULL.]

SideEffects [none]

SeeAlso [Cudd_SetMaxLive]

Definition at line 3809 of file cuddAPI.c.

03811 {
03812     return(dd->maxLive);
03813 
03814 } /* end of Cudd_ReadMaxLive */

unsigned long Cudd_ReadMaxMemory ( DdManager dd  ) 

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

Synopsis [Reads the maximum allowed memory.]

Description [Reads the maximum allowed memory. When this number is exceeded, the package returns NULL.]

SideEffects [none]

SeeAlso [Cudd_SetMaxMemory]

Definition at line 3852 of file cuddAPI.c.

03854 {
03855     return(dd->maxmemhard);
03856 
03857 } /* end of Cudd_ReadMaxMemory */

unsigned long Cudd_ReadMemoryInUse ( DdManager dd  ) 

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

Synopsis [Returns the memory in use by the manager measured in bytes.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 2912 of file cuddAPI.c.

02914 {
02915     return(dd->memused);
02916 
02917 } /* end of Cudd_ReadMemoryInUse */

unsigned int Cudd_ReadMinDead ( DdManager dd  ) 

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

Synopsis [Reads the minDead parameter of the manager.]

Description [Reads the minDead parameter of the manager. The minDead parameter is used by the package to decide whether to collect garbage or resize a subtable of the unique table when the subtable becomes too full. The application can indirectly control the value of minDead by setting the looseUpTo parameter.]

SideEffects [None]

SeeAlso [Cudd_ReadDead Cudd_ReadLooseUpTo Cudd_SetLooseUpTo]

Definition at line 1666 of file cuddAPI.c.

01668 {
01669     return(dd->minDead);
01670 
01671 } /* end of Cudd_ReadMinDead */

unsigned int Cudd_ReadMinHit ( DdManager dd  ) 

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

Synopsis [Reads the hit rate that causes resizinig of the computed table.]

Description []

SideEffects [None]

SeeAlso [Cudd_SetMinHit]

Definition at line 1268 of file cuddAPI.c.

01270 {
01271     /* Internally, the package manipulates the ratio of hits to
01272     ** misses instead of the ratio of hits to accesses. */
01273     return((unsigned int) (0.5 + 100 * dd->minHit / (1 + dd->minHit)));
01274 
01275 } /* end of Cudd_ReadMinHit */

DdNode* Cudd_ReadMinusInfinity ( DdManager dd  ) 

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

Synopsis [Reads the minus-infinity constant from the manager.]

Description []

SideEffects [None]

Definition at line 1090 of file cuddAPI.c.

01092 {
01093     return(dd->minusinfinity);
01094 
01095 } /* end of Cudd_ReadMinusInfinity */

unsigned int Cudd_ReadNextReordering ( DdManager dd  ) 

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

Synopsis [Returns the threshold for the next dynamic reordering.]

Description [Returns the threshold for the next dynamic reordering. The threshold is in terms of number of nodes and is in effect only if reordering is enabled. The count does not include the dead nodes, unless the countDead parameter of the manager has been changed from its default setting.]

SideEffects [None]

SeeAlso [Cudd_SetNextReordering]

Definition at line 3739 of file cuddAPI.c.

03741 {
03742     return(dd->nextDyn);
03743 
03744 } /* end of Cudd_ReadNextReordering */

long Cudd_ReadNodeCount ( DdManager dd  ) 

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

Synopsis [Reports the number of nodes in BDDs and ADDs.]

Description [Reports the number of live nodes in BDDs and ADDs. This number does not include the isolated projection functions and the unused constants. These nodes that are not counted are not part of the DDs manipulated by the application.]

SideEffects [None]

SeeAlso [Cudd_ReadPeakNodeCount Cudd_zddReadNodeCount]

Definition at line 3176 of file cuddAPI.c.

03178 {
03179     long count;
03180     int i;
03181 
03182 #ifndef DD_NO_DEATH_ROW
03183     cuddClearDeathRow(dd);
03184 #endif
03185 
03186     count = (long) (dd->keys - dd->dead);
03187 
03188     /* Count isolated projection functions. Their number is subtracted
03189     ** from the node count because they are not part of the BDDs.
03190     */
03191     for (i=0; i < dd->size; i++) {
03192         if (dd->vars[i]->ref == 1) count--;
03193     }
03194     /* Subtract from the count the unused constants. */
03195     if (DD_ZERO(dd)->ref == 1) count--;
03196     if (DD_PLUS_INFINITY(dd)->ref == 1) count--;
03197     if (DD_MINUS_INFINITY(dd)->ref == 1) count--;
03198 
03199     return(count);
03200 
03201 } /* end of Cudd_ReadNodeCount */

double Cudd_ReadNodesDropped ( DdManager dd  ) 

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

Synopsis [Returns the number of nodes dropped.]

Description [Returns the number of nodes killed by dereferencing if the keeping of this statistic is enabled; -1 otherwise. This statistic is enabled only if the package is compiled with DD_STATS defined.]

SideEffects [None]

SeeAlso [Cudd_ReadNodesFreed]

Definition at line 1806 of file cuddAPI.c.

01808 {
01809 #ifdef DD_STATS
01810     return(dd->nodesDropped);
01811 #else
01812     return(-1.0);
01813 #endif
01814 
01815 } /* end of Cudd_ReadNodesDropped */

double Cudd_ReadNodesFreed ( DdManager dd  ) 

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

Synopsis [Returns the number of nodes freed.]

Description [Returns the number of nodes returned to the free list if the keeping of this statistic is enabled; -1 otherwise. This statistic is enabled only if the package is compiled with DD_STATS defined.]

SideEffects [None]

SeeAlso [Cudd_ReadNodesDropped]

Definition at line 1780 of file cuddAPI.c.

01782 {
01783 #ifdef DD_STATS
01784     return(dd->nodesFreed);
01785 #else
01786     return(-1.0);
01787 #endif
01788 
01789 } /* end of Cudd_ReadNodesFreed */

int Cudd_ReadNumberXovers ( DdManager dd  ) 

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

Synopsis [Reads the current number of crossovers used by the genetic algorithm for reordering.]

Description [Reads the current number of crossovers used by the genetic algorithm for variable reordering. A larger number of crossovers will cause the genetic algorithm to take more time, but will generally produce better results. The default value is 0, in which case the package uses three times the number of variables as number of crossovers, with a maximum of 60.]

SideEffects [None]

SeeAlso [Cudd_SetNumberXovers]

Definition at line 2866 of file cuddAPI.c.

02868 {
02869     return(dd->numberXovers);
02870 
02871 } /* end of Cudd_ReadNumberXovers */

DdNode* Cudd_ReadOne ( DdManager dd  ) 

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

Synopsis [Returns the one constant of the manager.]

Description [Returns the one constant of the manager. The one constant is common to ADDs and BDDs.]

SideEffects [None]

SeeAlso [Cudd_ReadZero Cudd_ReadLogicZero Cudd_ReadZddOne]

Definition at line 983 of file cuddAPI.c.

00985 {
00986     return(dd->one);
00987 
00988 } /* end of Cudd_ReadOne */

int Cudd_ReadPeakLiveNodeCount ( DdManager dd  ) 

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

Synopsis [Reports the peak number of live nodes.]

Description [Reports the peak number of live nodes. This count is kept only if CUDD is compiled with DD_STATS defined. If DD_STATS is not defined, this function returns -1.]

SideEffects [None]

SeeAlso [Cudd_ReadNodeCount Cudd_PrintInfo Cudd_ReadPeakNodeCount]

Definition at line 3148 of file cuddAPI.c.

03150 {
03151     unsigned int live = dd->keys - dd->dead;
03152 
03153     if (live > dd->peakLiveNodes) {
03154         dd->peakLiveNodes = live;
03155     }
03156     return((int)dd->peakLiveNodes);
03157 
03158 } /* end of Cudd_ReadPeakLiveNodeCount */

long Cudd_ReadPeakNodeCount ( DdManager dd  ) 

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

Synopsis [Reports the peak number of nodes.]

Description [Reports the peak number of nodes. This number includes node on the free list. At the peak, the number of nodes on the free list is guaranteed to be less than DD_MEM_CHUNK.]

SideEffects [None]

SeeAlso [Cudd_ReadNodeCount Cudd_PrintInfo]

Definition at line 3119 of file cuddAPI.c.

03121 {
03122     long count = 0;
03123     DdNodePtr *scan = dd->memoryList;
03124 
03125     while (scan != NULL) {
03126         count += DD_MEM_CHUNK;
03127         scan = (DdNodePtr *) *scan;
03128     }
03129     return(count);
03130 
03131 } /* end of Cudd_ReadPeakNodeCount */

int Cudd_ReadPerm ( DdManager dd,
int  i 
)

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

Synopsis [Returns the current position of the i-th variable in the order.]

Description [Returns the current position of the i-th variable in the order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]

SideEffects [None]

SeeAlso [Cudd_ReadInvPerm Cudd_ReadPermZdd]

Definition at line 2297 of file cuddAPI.c.

02300 {
02301     if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
02302     if (i < 0 || i >= dd->size) return(-1);
02303     return(dd->perm[i]);
02304 
02305 } /* end of Cudd_ReadPerm */

int Cudd_ReadPermZdd ( DdManager dd,
int  i 
)

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

Synopsis [Returns the current position of the i-th ZDD variable in the order.]

Description [Returns the current position of the i-th ZDD variable in the order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]

SideEffects [None]

SeeAlso [Cudd_ReadInvPermZdd Cudd_ReadPerm]

Definition at line 2324 of file cuddAPI.c.

02327 {
02328     if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
02329     if (i < 0 || i >= dd->sizeZ) return(-1);
02330     return(dd->permZ[i]);
02331 
02332 } /* end of Cudd_ReadPermZdd */

DdNode* Cudd_ReadPlusInfinity ( DdManager dd  ) 

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

Synopsis [Reads the plus-infinity constant from the manager.]

Description []

SideEffects [None]

Definition at line 1072 of file cuddAPI.c.

01074 {
01075     return(dd->plusinfinity);
01076 
01077 } /* end of Cudd_ReadPlusInfinity */

int Cudd_ReadPopulationSize ( DdManager dd  ) 

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

Synopsis [Reads the current size of the population used by the genetic algorithm for reordering.]

Description [Reads the current size of the population used by the genetic algorithm for variable reordering. A larger population size will cause the genetic algorithm to take more time, but will generally produce better results. The default value is 0, in which case the package uses three times the number of variables as population size, with a maximum of 120.]

SideEffects [None]

SeeAlso [Cudd_SetPopulationSize]

Definition at line 2813 of file cuddAPI.c.

02815 {
02816     return(dd->populationSize);
02817 
02818 } /* end of Cudd_ReadPopulationSize */

int Cudd_ReadRecomb ( DdManager dd  ) 

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

Synopsis [Returns the current value of the recombination parameter used in group sifting.]

Description [Returns the current value of the recombination parameter used in group sifting. A larger (positive) value makes the aggregation of variables due to the second difference criterion more likely. A smaller (negative) value makes aggregation less likely.]

SideEffects [None]

SeeAlso [Cudd_SetRecomb]

Definition at line 2653 of file cuddAPI.c.

02655 {
02656     return(dd->recomb);
02657 
02658 } /* end of Cudd_ReadRecomb */

double Cudd_ReadRecursiveCalls ( DdManager dd  ) 

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

Synopsis [Returns the number of recursive calls.]

Description [Returns the number of recursive calls if the package is compiled with DD_COUNT defined.]

SideEffects [None]

SeeAlso []

Definition at line 1242 of file cuddAPI.c.

01244 {
01245 #ifdef DD_COUNT
01246     return(dd->recursiveCalls);
01247 #else
01248     return(-1.0);
01249 #endif
01250 
01251 } /* end of Cudd_ReadRecursiveCalls */

int Cudd_ReadReorderingCycle ( DdManager dd  ) 

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

Synopsis [Reads the reordCycle parameter of the manager.]

Description [Reads the reordCycle parameter of the manager. This parameter determines how often the alternate threshold on maximum growth is used in reordering.]

SideEffects [None]

SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate Cudd_SetReorderingCycle]

Definition at line 2084 of file cuddAPI.c.

02086 {
02087     return(dd->reordCycle);
02088 
02089 } /* end of Cudd_ReadReorderingCycle */

int Cudd_ReadReorderings ( DdManager dd  ) 

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

Synopsis [Returns the number of times reordering has occurred.]

Description [Returns the number of times reordering has occurred in the manager. The number includes both the calls to Cudd_ReduceHeap from the application program and those automatically performed by the package. However, calls that do not even initiate reordering are not counted. A call may not initiate reordering if there are fewer than minsize live nodes in the manager, or if CUDD_REORDER_NONE is specified as reordering method. The calls to Cudd_ShuffleHeap are not counted.]

SideEffects [None]

SeeAlso [Cudd_ReduceHeap Cudd_ReadReorderingTime]

Definition at line 1692 of file cuddAPI.c.

01694 {
01695     return(dd->reorderings);
01696 
01697 } /* end of Cudd_ReadReorderings */

long Cudd_ReadReorderingTime ( DdManager dd  ) 

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

Synopsis [Returns the time spent in reordering.]

Description [Returns the number of milliseconds spent reordering variables since the manager was initialized. The time spent in collecting garbage before reordering is included.]

SideEffects [None]

SeeAlso [Cudd_ReadReorderings]

Definition at line 1714 of file cuddAPI.c.

01716 {
01717     return(dd->reordTime);
01718 
01719 } /* end of Cudd_ReadReorderingTime */

int Cudd_ReadSiftMaxSwap ( DdManager dd  ) 

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

Synopsis [Reads the siftMaxSwap parameter of the manager.]

Description [Reads the siftMaxSwap parameter of the manager. This parameter gives the maximum number of swaps that will be attempted for each invocation of sifting. The real number of swaps may exceed the set limit because the package will always complete the sifting of the variable that causes the limit to be reached.]

SideEffects [None]

SeeAlso [Cudd_ReadSiftMaxVar Cudd_SetSiftMaxSwap]

Definition at line 1934 of file cuddAPI.c.

01936 {
01937     return(dd->siftMaxSwap);
01938 
01939 } /* end of Cudd_ReadSiftMaxSwap */

int Cudd_ReadSiftMaxVar ( DdManager dd  ) 

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

Synopsis [Reads the siftMaxVar parameter of the manager.]

Description [Reads the siftMaxVar parameter of the manager. This parameter gives the maximum number of variables that will be sifted for each invocation of sifting.]

SideEffects [None]

SeeAlso [Cudd_ReadSiftMaxSwap Cudd_SetSiftMaxVar]

Definition at line 1887 of file cuddAPI.c.

01889 {
01890     return(dd->siftMaxVar);
01891 
01892 } /* end of Cudd_ReadSiftMaxVar */

int Cudd_ReadSize ( DdManager dd  ) 

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

Synopsis [Returns the number of BDD variables in existance.]

Description []

SideEffects [None]

SeeAlso [Cudd_ReadZddSize]

Definition at line 1437 of file cuddAPI.c.

01439 {
01440     return(dd->size);
01441 
01442 } /* end of Cudd_ReadSize */

unsigned int Cudd_ReadSlots ( DdManager dd  ) 

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

Synopsis [Returns the total number of slots of the unique table.]

Description [Returns the total number of slots of the unique table. This number ismainly for diagnostic purposes.]

SideEffects [None]

Definition at line 1476 of file cuddAPI.c.

01478 {
01479     return(dd->slots);
01480 
01481 } /* end of Cudd_ReadSlots */

FILE* Cudd_ReadStderr ( DdManager dd  ) 

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

Synopsis [Reads the stderr of a manager.]

Description [Reads the stderr of a manager. This is the file pointer to which messages normally going to stderr are written. It is initialized to stderr. Cudd_SetStderr allows the application to redirect it.]

SideEffects [None]

SeeAlso [Cudd_SetStderr Cudd_ReadStdout]

Definition at line 3694 of file cuddAPI.c.

03696 {
03697     return(dd->err);
03698 
03699 } /* end of Cudd_ReadStderr */

FILE* Cudd_ReadStdout ( DdManager dd  ) 

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

Synopsis [Reads the stdout of a manager.]

Description [Reads the stdout of a manager. This is the file pointer to which messages normally going to stdout are written. It is initialized to stdout. Cudd_SetStdout allows the application to redirect it.]

SideEffects [None]

SeeAlso [Cudd_SetStdout Cudd_ReadStderr]

Definition at line 3651 of file cuddAPI.c.

03653 {
03654     return(dd->out);
03655 
03656 } /* end of Cudd_ReadStdout */

double Cudd_ReadSwapSteps ( DdManager dd  ) 

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

Synopsis [Reads the number of elementary reordering steps.]

Description []

SideEffects [none]

SeeAlso []

Definition at line 3784 of file cuddAPI.c.

03786 {
03787 #ifdef DD_COUNT
03788     return(dd->swapSteps);
03789 #else
03790     return(-1);
03791 #endif
03792 
03793 } /* end of Cudd_ReadSwapSteps */

int Cudd_ReadSymmviolation ( DdManager dd  ) 

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

Synopsis [Returns the current value of the symmviolation parameter used in group sifting.]

Description [Returns the current value of the symmviolation parameter. This parameter is used in group sifting to decide how many violations to the symmetry conditions f10 = f01 or f11 = f00 are tolerable when checking for aggregation due to extended symmetry. The value should be between 0 and 100. A small value causes fewer variables to be aggregated. The default value is 0.]

SideEffects [None]

SeeAlso [Cudd_SetSymmviolation]

Definition at line 2706 of file cuddAPI.c.

02708 {
02709     return(dd->symmviolation);
02710 
02711 } /* end of Cudd_ReadSymmviolation */

MtrNode* Cudd_ReadTree ( DdManager dd  ) 

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

Synopsis [Returns the variable group tree of the manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_SetTree Cudd_FreeTree Cudd_ReadZddTree]

Definition at line 2128 of file cuddAPI.c.

02130 {
02131     return(dd->tree);
02132 
02133 } /* end of Cudd_ReadTree */

double Cudd_ReadUniqueLinks ( DdManager dd  ) 

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

Synopsis [Returns the number of links followed in the unique table.]

Description [Returns the number of links followed during look-ups in the unique table if the keeping of this statistic is enabled; -1 otherwise. If an item is found in the first position of its collision list, the number of links followed is taken to be 0. If it is in second position, the number of links is 1, and so on. This statistic is enabled only if the package is compiled with DD_UNIQUE_PROFILE defined.]

SideEffects [None]

SeeAlso [Cudd_ReadUniqueLookUps]

Definition at line 1861 of file cuddAPI.c.

01863 {
01864 #ifdef DD_UNIQUE_PROFILE
01865     return(dd->uniqueLinks);
01866 #else
01867     return(-1.0);
01868 #endif
01869 
01870 } /* end of Cudd_ReadUniqueLinks */

double Cudd_ReadUniqueLookUps ( DdManager dd  ) 

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

Synopsis [Returns the number of look-ups in the unique table.]

Description [Returns the number of look-ups in the unique table if the keeping of this statistic is enabled; -1 otherwise. This statistic is enabled only if the package is compiled with DD_UNIQUE_PROFILE defined.]

SideEffects [None]

SeeAlso [Cudd_ReadUniqueLinks]

Definition at line 1832 of file cuddAPI.c.

01834 {
01835 #ifdef DD_UNIQUE_PROFILE
01836     return(dd->uniqueLookUps);
01837 #else
01838     return(-1.0);
01839 #endif
01840 
01841 } /* end of Cudd_ReadUniqueLookUps */

double Cudd_ReadUsedSlots ( DdManager dd  ) 

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

Synopsis [Reads the fraction of used slots in the unique table.]

Description [Reads the fraction of used slots in the unique table. The unused slots are those in which no valid data is stored. Garbage collection, variable reordering, and subtable resizing may cause used slots to become unused.]

SideEffects [None]

SeeAlso [Cudd_ReadSlots]

Definition at line 1499 of file cuddAPI.c.

01501 {
01502     unsigned long used = 0;
01503     int i, j;
01504     int size = dd->size;
01505     DdNodePtr *nodelist;
01506     DdSubtable *subtable;
01507     DdNode *node;
01508     DdNode *sentinel = &(dd->sentinel);
01509 
01510     /* Scan each BDD/ADD subtable. */
01511     for (i = 0; i < size; i++) {
01512         subtable = &(dd->subtables[i]);
01513         nodelist = subtable->nodelist;
01514         for (j = 0; (unsigned) j < subtable->slots; j++) {
01515             node = nodelist[j];
01516             if (node != sentinel) {
01517                 used++;
01518             }
01519         }
01520     }
01521 
01522     /* Scan the ZDD subtables. */
01523     size = dd->sizeZ;
01524 
01525     for (i = 0; i < size; i++) {
01526         subtable = &(dd->subtableZ[i]);
01527         nodelist = subtable->nodelist;
01528         for (j = 0; (unsigned) j < subtable->slots; j++) {
01529             node = nodelist[j];
01530             if (node != NULL) {
01531                 used++;
01532             }
01533         }
01534     }
01535 
01536     /* Constant table. */
01537     subtable = &(dd->constants);
01538     nodelist = subtable->nodelist;
01539     for (j = 0; (unsigned) j < subtable->slots; j++) {
01540         node = nodelist[j];
01541         if (node != NULL) {
01542             used++;
01543         }
01544     }
01545 
01546     return((double)used / (double) dd->slots);
01547 
01548 } /* end of Cudd_ReadUsedSlots */

DdNode* Cudd_ReadVars ( DdManager dd,
int  i 
)

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

Synopsis [Returns the i-th element of the vars array.]

Description [Returns the i-th element of the vars array if it falls within the array bounds; NULL otherwise. If i is the index of an existing variable, this function produces the same result as Cudd_bddIthVar. However, if the i-th var does not exist yet, Cudd_bddIthVar will create it, whereas Cudd_ReadVars will not.]

SideEffects [None]

SeeAlso [Cudd_bddIthVar]

Definition at line 2403 of file cuddAPI.c.

02406 {
02407     if (i < 0 || i > dd->size) return(NULL);
02408     return(dd->vars[i]);
02409 
02410 } /* end of Cudd_ReadVars */

DdNode* Cudd_ReadZddOne ( DdManager dd,
int  i 
)

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

Synopsis [Returns the ZDD for the constant 1 function.]

Description [Returns the ZDD for the constant 1 function. The representation of the constant 1 function as a ZDD depends on how many variables it (nominally) depends on. The index of the topmost variable in the support is given as argument i.]

SideEffects [None]

SeeAlso [Cudd_ReadOne]

Definition at line 1006 of file cuddAPI.c.

01009 {
01010     if (i < 0)
01011         return(NULL);
01012     return(i < dd->sizeZ ? dd->univ[i] : DD_ONE(dd));
01013 
01014 } /* end of Cudd_ReadZddOne */

int Cudd_ReadZddSize ( DdManager dd  ) 

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

Synopsis [Returns the number of ZDD variables in existance.]

Description []

SideEffects [None]

SeeAlso [Cudd_ReadSize]

Definition at line 1457 of file cuddAPI.c.

01459 {
01460     return(dd->sizeZ);
01461 
01462 } /* end of Cudd_ReadZddSize */

MtrNode* Cudd_ReadZddTree ( DdManager dd  ) 

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

Synopsis [Returns the variable group tree of the manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_SetZddTree Cudd_FreeZddTree Cudd_ReadTree]

Definition at line 2200 of file cuddAPI.c.

02202 {
02203     return(dd->treeZ);
02204 
02205 } /* end of Cudd_ReadZddTree */

DdNode* Cudd_ReadZero ( DdManager dd  ) 

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

Synopsis [Returns the zero constant of the manager.]

Description [Returns the zero constant of the manager. The zero constant is the arithmetic zero, rather than the logic zero. The latter is the complement of the one constant.]

SideEffects [None]

SeeAlso [Cudd_ReadOne Cudd_ReadLogicZero]

Definition at line 1032 of file cuddAPI.c.

01034 {
01035     return(DD_ZERO(dd));
01036 
01037 } /* end of Cudd_ReadZero */

void Cudd_RecursiveDeref ( DdManager table,
DdNode n 
)

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

Synopsis [Decreases the reference count of node n.]

Description [Decreases the reference count of node n. If n dies, recursively decreases the reference counts of its children. It is used to dispose of a DD that is no longer needed.]

SideEffects [None]

SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDerefZdd]

Definition at line 150 of file cuddRef.c.

00153 {
00154     DdNode *N;
00155     int ord;
00156     DdNodePtr *stack = table->stack;
00157     int SP = 1;
00158 
00159     unsigned int live = table->keys - table->dead;
00160     if (live > table->peakLiveNodes) {
00161         table->peakLiveNodes = live;
00162     }
00163 
00164     N = Cudd_Regular(n);
00165 
00166     do {
00167 #ifdef DD_DEBUG
00168         assert(N->ref != 0);
00169 #endif
00170 
00171         if (N->ref == 1) {
00172             N->ref = 0;
00173             table->dead++;
00174 #ifdef DD_STATS
00175             table->nodesDropped++;
00176 #endif
00177             if (cuddIsConstant(N)) {
00178                 table->constants.dead++;
00179                 N = stack[--SP];
00180             } else {
00181                 ord = table->perm[N->index];
00182                 stack[SP++] = Cudd_Regular(cuddE(N));
00183                 table->subtables[ord].dead++;
00184                 N = cuddT(N);
00185             }
00186         } else {
00187             cuddSatDec(N->ref);
00188             N = stack[--SP];
00189         }
00190     } while (SP != 0);
00191 
00192 } /* end of Cudd_RecursiveDeref */

void Cudd_RecursiveDerefZdd ( DdManager table,
DdNode n 
)

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

Synopsis [Decreases the reference count of ZDD node n.]

Description [Decreases the reference count of ZDD node n. If n dies, recursively decreases the reference counts of its children. It is used to dispose of a ZDD that is no longer needed.]

SideEffects [None]

SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDeref]

Definition at line 381 of file cuddRef.c.

00384 {
00385     DdNode *N;
00386     int ord;
00387     DdNodePtr *stack = table->stack;
00388     int SP = 1;
00389 
00390     N = n;
00391 
00392     do {
00393 #ifdef DD_DEBUG
00394         assert(N->ref != 0);
00395 #endif
00396 
00397         cuddSatDec(N->ref);
00398     
00399         if (N->ref == 0) {
00400             table->deadZ++;
00401 #ifdef DD_STATS
00402             table->nodesDropped++;
00403 #endif
00404 #ifdef DD_DEBUG
00405             assert(!cuddIsConstant(N));
00406 #endif
00407             ord = table->permZ[N->index];
00408             stack[SP++] = cuddE(N);
00409             table->subtableZ[ord].dead++;
00410             N = cuddT(N);
00411         } else {
00412             N = stack[--SP];
00413         }
00414     } while (SP != 0);
00415 
00416 } /* end of Cudd_RecursiveDerefZdd */

int Cudd_ReduceHeap ( DdManager table,
Cudd_ReorderingType  heuristic,
int  minsize 
)

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

Synopsis [Main dynamic reordering routine.]

Description [Main dynamic reordering routine. Calls one of the possible reordering procedures:

  • Swapping
  • Sifting
  • Symmetric Sifting
  • Group Sifting
  • Window Permutation
  • Simulated Annealing
  • Genetic Algorithm
  • Dynamic Programming (exact)

For sifting, symmetric sifting, group sifting, and window permutation it is possible to request reordering to convergence.

The core of all methods is the reordering procedure cuddSwapInPlace() which swaps two adjacent variables and is based on Rudell's paper. Returns 1 in case of success; 0 otherwise. In the case of symmetric sifting (with and without convergence) returns 1 plus the number of symmetric variables, in case of success.]

SideEffects [Changes the variable order for all diagrams and clears the cache.]

Definition at line 172 of file cuddReorder.c.

00176 {
00177     DdHook *hook;
00178     int result;
00179     unsigned int nextDyn;
00180 #ifdef DD_STATS
00181     unsigned int initialSize;
00182     unsigned int finalSize;
00183 #endif
00184     long localTime;
00185 
00186     /* Don't reorder if there are too many dead nodes. */
00187     if (table->keys - table->dead < (unsigned) minsize)
00188         return(1);
00189 
00190     if (heuristic == CUDD_REORDER_SAME) {
00191         heuristic = table->autoMethod;
00192     }
00193     if (heuristic == CUDD_REORDER_NONE) {
00194         return(1);
00195     }
00196 
00197     /* This call to Cudd_ReduceHeap does initiate reordering. Therefore
00198     ** we count it.
00199     */
00200     table->reorderings++;
00201 
00202     localTime = util_cpu_time();
00203 
00204     /* Run the hook functions. */
00205     hook = table->preReorderingHook;
00206     while (hook != NULL) {
00207         int res = (hook->f)(table, "BDD", (void *)heuristic);
00208         if (res == 0) return(0);
00209         hook = hook->next;
00210     }
00211 
00212     if (!ddReorderPreprocess(table)) return(0);
00213     ddTotalNumberSwapping = 0;
00214 
00215     if (table->keys > table->peakLiveNodes) {
00216         table->peakLiveNodes = table->keys;
00217     }
00218 #ifdef DD_STATS
00219     initialSize = table->keys - table->isolated;
00220     ddTotalNISwaps = 0;
00221 
00222     switch(heuristic) {
00223     case CUDD_REORDER_RANDOM:
00224     case CUDD_REORDER_RANDOM_PIVOT:
00225         (void) fprintf(table->out,"#:I_RANDOM  ");
00226         break;
00227     case CUDD_REORDER_SIFT:
00228     case CUDD_REORDER_SIFT_CONVERGE:
00229     case CUDD_REORDER_SYMM_SIFT:
00230     case CUDD_REORDER_SYMM_SIFT_CONV:
00231     case CUDD_REORDER_GROUP_SIFT:
00232     case CUDD_REORDER_GROUP_SIFT_CONV:
00233         (void) fprintf(table->out,"#:I_SIFTING ");
00234         break;
00235     case CUDD_REORDER_WINDOW2:
00236     case CUDD_REORDER_WINDOW3:
00237     case CUDD_REORDER_WINDOW4:
00238     case CUDD_REORDER_WINDOW2_CONV:
00239     case CUDD_REORDER_WINDOW3_CONV:
00240     case CUDD_REORDER_WINDOW4_CONV:
00241         (void) fprintf(table->out,"#:I_WINDOW  ");
00242         break;
00243     case CUDD_REORDER_ANNEALING:
00244         (void) fprintf(table->out,"#:I_ANNEAL  ");
00245         break;
00246     case CUDD_REORDER_GENETIC:
00247         (void) fprintf(table->out,"#:I_GENETIC ");
00248         break;
00249     case CUDD_REORDER_LINEAR:
00250     case CUDD_REORDER_LINEAR_CONVERGE:
00251         (void) fprintf(table->out,"#:I_LINSIFT ");
00252         break;
00253     case CUDD_REORDER_EXACT:
00254         (void) fprintf(table->out,"#:I_EXACT   ");
00255         break;
00256     default:
00257         return(0);
00258     }
00259     (void) fprintf(table->out,"%8d: initial size",initialSize);
00260 #endif
00261 
00262     /* See if we should use alternate threshold for maximum growth. */
00263     if (table->reordCycle && table->reorderings % table->reordCycle == 0) {
00264         double saveGrowth = table->maxGrowth;
00265         table->maxGrowth = table->maxGrowthAlt;
00266         result = cuddTreeSifting(table,heuristic);
00267         table->maxGrowth = saveGrowth;
00268     } else {
00269         result = cuddTreeSifting(table,heuristic);
00270     }
00271 
00272 #ifdef DD_STATS
00273     (void) fprintf(table->out,"\n");
00274     finalSize = table->keys - table->isolated;
00275     (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize);
00276     (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n",
00277                    ((double)(util_cpu_time() - localTime)/1000.0));
00278     (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n",
00279                    ddTotalNumberSwapping);
00280     (void) fprintf(table->out,"#:M_REORDER %8d: NI swaps\n",ddTotalNISwaps);
00281 #endif
00282 
00283     if (result == 0)
00284         return(0);
00285 
00286     if (!ddReorderPostprocess(table))
00287         return(0);
00288 
00289     if (table->realign) {
00290         if (!cuddZddAlignToBdd(table))
00291             return(0);
00292     }
00293 
00294     nextDyn = (table->keys - table->constants.keys + 1) *
00295               DD_DYN_RATIO + table->constants.keys;
00296     if (table->reorderings < 20 || nextDyn > table->nextDyn)
00297         table->nextDyn = nextDyn;
00298     else
00299         table->nextDyn += 20;
00300     table->reordered = 1;
00301 
00302     /* Run hook functions. */
00303     hook = table->postReorderingHook;
00304     while (hook != NULL) {
00305         int res = (hook->f)(table, "BDD", (void *)localTime);
00306         if (res == 0) return(0);
00307         hook = hook->next;
00308     }
00309     /* Update cumulative reordering time. */
00310     table->reordTime += util_cpu_time() - localTime;
00311 
00312     return(result);
00313 
00314 } /* end of Cudd_ReduceHeap */

void Cudd_Ref ( DdNode n  ) 

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

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

Description []

SideEffects [None]

SeeAlso [Cudd_RecursiveDeref Cudd_Deref]

Definition at line 125 of file cuddRef.c.

00127 {
00128 
00129     n = Cudd_Regular(n);
00130 
00131     cuddSatInc(n->ref);
00132 
00133 } /* end of Cudd_Ref */

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

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

Synopsis [Extracts a dense superset from a BDD with the remapping underapproximation method.]

Description [Extracts a dense superset from a BDD. The procedure is identical to the underapproximation procedure except for the fact that it works on the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. Returns a pointer to the BDD of the superset if successful. NULL if intermediate result causes the procedure to run out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SupersetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize]

Definition at line 362 of file cuddApprox.c.

00368 {
00369     DdNode *subset, *g;
00370 
00371     g = Cudd_Not(f);    
00372     do {
00373         dd->reordered = 0;
00374         subset = cuddRemapUnderApprox(dd, g, numVars, threshold, quality);
00375     } while (dd->reordered == 1);
00376     
00377     return(Cudd_NotCond(subset, (subset != NULL)));
00378     
00379 } /* end of Cudd_RemapOverApprox */

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

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

Synopsis [Extracts a dense subset from a BDD with the remapping underapproximation method.]

Description [Extracts a dense subset from a BDD. This procedure uses a remapping technique and density as the cost function. Returns a pointer to the BDD of the subset if successful. NULL if the procedure runs out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will cause overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_UnderApprox Cudd_ReadSize]

Definition at line 316 of file cuddApprox.c.

00322 {
00323     DdNode *subset;
00324 
00325     do {
00326         dd->reordered = 0;
00327         subset = cuddRemapUnderApprox(dd, f, numVars, threshold, quality);
00328     } while (dd->reordered == 1);
00329 
00330     return(subset);
00331 
00332 } /* end of Cudd_RemapUnderApprox */

int Cudd_RemoveHook ( DdManager dd,
DD_HFP  f,
Cudd_HookType  where 
)

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

Synopsis [Removes a function from a hook.]

Description [Removes a function from a hook. A hook is a list of application-provided functions called on certain occasions by the package. Returns 1 if successful; 0 the function was not in the list.]

SideEffects [None]

SeeAlso [Cudd_AddHook]

Definition at line 3303 of file cuddAPI.c.

03307 {
03308     DdHook **hook, *nextHook;
03309 
03310     switch (where) {
03311     case CUDD_PRE_GC_HOOK:
03312         hook = &(dd->preGCHook);
03313         break;
03314     case CUDD_POST_GC_HOOK:
03315         hook = &(dd->postGCHook);
03316         break;
03317     case CUDD_PRE_REORDERING_HOOK:
03318         hook = &(dd->preReorderingHook);
03319         break;
03320     case CUDD_POST_REORDERING_HOOK:
03321         hook = &(dd->postReorderingHook);
03322         break;
03323     default:
03324         return(0);
03325     }
03326     nextHook = *hook;
03327     while (nextHook != NULL) {
03328         if (nextHook->f == f) {
03329             *hook = nextHook->next;
03330             FREE(nextHook);
03331             return(1);
03332         }
03333         hook = &(nextHook->next);
03334         nextHook = nextHook->next;
03335     }
03336 
03337     return(0);
03338 
03339 } /* end of Cudd_RemoveHook */

int Cudd_ReorderingReporting ( DdManager dd  ) 

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

Synopsis [Returns 1 if reporting of reordering stats is enabled.]

Description [Returns 1 if reporting of reordering stats is enabled; 0 otherwise.]

SideEffects [none]

SeeAlso [Cudd_EnableReorderingReporting Cudd_DisableReorderingReporting]

Definition at line 3588 of file cuddAPI.c.

03590 {
03591     return(Cudd_IsInHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK));
03592 
03593 } /* end of Cudd_ReorderingReporting */

int Cudd_ReorderingStatus ( DdManager unique,
Cudd_ReorderingType method 
)

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

Synopsis [Reports the status of automatic dynamic reordering of BDDs and ADDs.]

Description [Reports the status of automatic dynamic reordering of BDDs and ADDs. Parameter method is set to the reordering method currently selected. Returns 1 if automatic reordering is enabled; 0 otherwise.]

SideEffects [Parameter method is set to the reordering method currently selected.]

SeeAlso [Cudd_AutodynEnable Cudd_AutodynDisable Cudd_ReorderingStatusZdd]

Definition at line 731 of file cuddAPI.c.

00734 {
00735     *method = unique->autoMethod;
00736     return(unique->autoDyn);
00737 
00738 } /* end of Cudd_ReorderingStatus */

int Cudd_ReorderingStatusZdd ( DdManager unique,
Cudd_ReorderingType method 
)

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

Synopsis [Reports the status of automatic dynamic reordering of ZDDs.]

Description [Reports the status of automatic dynamic reordering of ZDDs. Parameter method is set to the ZDD reordering method currently selected. Returns 1 if automatic reordering is enabled; 0 otherwise.]

SideEffects [Parameter method is set to the ZDD reordering method currently selected.]

SeeAlso [Cudd_AutodynEnableZdd Cudd_AutodynDisableZdd Cudd_ReorderingStatus]

Definition at line 808 of file cuddAPI.c.

00811 {
00812     *method = unique->autoMethodZ;
00813     return(unique->autoDynZ);
00814 
00815 } /* end of Cudd_ReorderingStatusZdd */

void Cudd_SetArcviolation ( DdManager dd,
int  arcviolation 
)

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

Synopsis [Sets the value of the arcviolation parameter used in group sifting.]

Description [Sets the value of the arcviolation parameter. This parameter is used in group sifting to decide how many arcs into y not coming from x are tolerable when checking for aggregation due to extended symmetry. The value should be between 0 and 100. A small value causes fewer variables to be aggregated. The default value is 0.]

SideEffects [None]

SeeAlso [Cudd_ReadArcviolation]

Definition at line 2786 of file cuddAPI.c.

02789 {
02790     dd->arcviolation = arcviolation;
02791 
02792 } /* end of Cudd_SetArcviolation */

void Cudd_SetBackground ( DdManager dd,
DdNode bck 
)

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

Synopsis [Sets the background constant of the manager.]

Description [Sets the background constant of the manager. It assumes that the DdNode pointer bck is already referenced.]

SideEffects [None]

Definition at line 1127 of file cuddAPI.c.

01130 {
01131     dd->background = bck;
01132 
01133 } /* end of Cudd_SetBackground */

void Cudd_SetEpsilon ( DdManager dd,
CUDD_VALUE_TYPE  ep 
)

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

Synopsis [Sets the epsilon parameter of the manager to ep.]

Description [Sets the epsilon parameter of the manager to ep. The epsilon parameter control the comparison between floating point numbers.]

SideEffects [None]

SeeAlso [Cudd_ReadEpsilon]

Definition at line 2447 of file cuddAPI.c.

02450 {
02451     dd->epsilon = ep;
02452 
02453 } /* end of Cudd_SetEpsilon */

void Cudd_SetGroupcheck ( DdManager dd,
Cudd_AggregationType  gc 
)

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

Synopsis [Sets the parameter groupcheck of the manager to gc.]

Description [Sets the parameter groupcheck of the manager to gc. The groupcheck parameter determines the aggregation criterion in group sifting.]

SideEffects [None]

SeeAlso [Cudd_ReadGroupCheck]

Definition at line 2492 of file cuddAPI.c.

02495 {
02496     dd->groupcheck = gc;
02497 
02498 } /* end of Cudd_SetGroupcheck */

void Cudd_SetLooseUpTo ( DdManager dd,
unsigned int  lut 
)

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

Synopsis [Sets the looseUpTo parameter of the manager.]

Description [Sets the looseUpTo parameter of the manager. This parameter of the manager controls the threshold beyond which no fast growth of the unique table is allowed. The threshold is given as a number of slots. If the value passed to this function is 0, the function determines a suitable value based on the available memory.]

SideEffects [None]

SeeAlso [Cudd_ReadLooseUpTo Cudd_SetMinHit]

Definition at line 1341 of file cuddAPI.c.

01344 {
01345     if (lut == 0) {
01346         unsigned long datalimit = getSoftDataLimit();
01347         lut = (unsigned int) (datalimit / (sizeof(DdNode) *
01348                                            DD_MAX_LOOSE_FRACTION));
01349     }
01350     dd->looseUpTo = lut;
01351 
01352 } /* end of Cudd_SetLooseUpTo */

void Cudd_SetMaxCacheHard ( DdManager dd,
unsigned int  mc 
)

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

Synopsis [Sets the maxCacheHard parameter of the manager.]

Description [Sets the maxCacheHard parameter of the manager. The cache cannot grow larger than maxCacheHard entries. This parameter allows an application to control the trade-off of memory versus speed. If the value passed to this function is 0, the function determines a suitable maximum cache size based on the available memory.]

SideEffects [None]

SeeAlso [Cudd_ReadMaxCacheHard Cudd_SetMaxCache]

Definition at line 1411 of file cuddAPI.c.

01414 {
01415     if (mc == 0) {
01416         unsigned long datalimit = getSoftDataLimit();
01417         mc = (unsigned int) (datalimit / (sizeof(DdCache) *
01418                                           DD_MAX_CACHE_FRACTION));
01419     }
01420     dd->maxCacheHard = mc;
01421 
01422 } /* end of Cudd_SetMaxCacheHard */

void Cudd_SetMaxGrowth ( DdManager dd,
double  mg 
)

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

Synopsis [Sets the maxGrowth parameter of the manager.]

Description [Sets the maxGrowth parameter of the manager. This parameter determines how much the number of nodes can grow during sifting of a variable. Overall, sifting never increases the size of the decision diagrams. This parameter only refers to intermediate results. A lower value will speed up sifting, possibly at the expense of quality.]

SideEffects [None]

SeeAlso [Cudd_ReadMaxGrowth Cudd_SetMaxGrowthAlternate]

Definition at line 2009 of file cuddAPI.c.

02012 {
02013     dd->maxGrowth = mg;
02014 
02015 } /* end of Cudd_SetMaxGrowth */

void Cudd_SetMaxGrowthAlternate ( DdManager dd,
double  mg 
)

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

Synopsis [Sets the maxGrowthAlt parameter of the manager.]

Description [Sets the maxGrowthAlt parameter of the manager. This parameter is analogous to the maxGrowth paramter, and is used every given number of reorderings instead of maxGrowth. The number of reorderings is set with Cudd_SetReorderingCycle. If the number of reorderings is 0 (default) maxGrowthAlt is never used.]

SideEffects [None]

SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowth Cudd_SetReorderingCycle Cudd_ReadReorderingCycle]

Definition at line 2060 of file cuddAPI.c.

02063 {
02064     dd->maxGrowthAlt = mg;
02065 
02066 } /* end of Cudd_SetMaxGrowthAlternate */

void Cudd_SetMaxLive ( DdManager dd,
unsigned int  maxLive 
)

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

Synopsis [Sets the maximum allowed number of live nodes.]

Description [Sets the maximum allowed number of live nodes. When this number is exceeded, the package returns NULL.]

SideEffects [none]

SeeAlso [Cudd_ReadMaxLive]

Definition at line 3830 of file cuddAPI.c.

03833 {
03834     dd->maxLive = maxLive;
03835 
03836 } /* end of Cudd_SetMaxLive */

void Cudd_SetMaxMemory ( DdManager dd,
unsigned long  maxMemory 
)

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

Synopsis [Sets the maximum allowed memory.]

Description [Sets the maximum allowed memory. When this number is exceeded, the package returns NULL.]

SideEffects [none]

SeeAlso [Cudd_ReadMaxMemory]

Definition at line 3873 of file cuddAPI.c.

03876 {
03877     dd->maxmemhard = maxMemory;
03878 
03879 } /* end of Cudd_SetMaxMemory */

void Cudd_SetMinHit ( DdManager dd,
unsigned int  hr 
)

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

Synopsis [Sets the hit rate that causes resizinig of the computed table.]

Description [Sets the minHit parameter of the manager. This parameter controls the resizing of the computed table. If the hit rate is larger than the specified value, and the cache is not already too large, then its size is doubled.]

SideEffects [None]

SeeAlso [Cudd_ReadMinHit]

Definition at line 1294 of file cuddAPI.c.

01297 {
01298     /* Internally, the package manipulates the ratio of hits to
01299     ** misses instead of the ratio of hits to accesses. */
01300     dd->minHit = (double) hr / (100.0 - (double) hr);
01301 
01302 } /* end of Cudd_SetMinHit */

void Cudd_SetNextReordering ( DdManager dd,
unsigned int  next 
)

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

Synopsis [Sets the threshold for the next dynamic reordering.]

Description [Sets the threshold for the next dynamic reordering. The threshold is in terms of number of nodes and is in effect only if reordering is enabled. The count does not include the dead nodes, unless the countDead parameter of the manager has been changed from its default setting.]

SideEffects [None]

SeeAlso [Cudd_ReadNextReordering]

Definition at line 3763 of file cuddAPI.c.

03766 {
03767     dd->nextDyn = next;
03768 
03769 } /* end of Cudd_SetNextReordering */

void Cudd_SetNumberXovers ( DdManager dd,
int  numberXovers 
)

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

Synopsis [Sets the number of crossovers used by the genetic algorithm for reordering.]

Description [Sets the number of crossovers used by the genetic algorithm for variable reordering. A larger number of crossovers will cause the genetic algorithm to take more time, but will generally produce better results. The default value is 0, in which case the package uses three times the number of variables as number of crossovers, with a maximum of 60.]

SideEffects [None]

SeeAlso [Cudd_ReadNumberXovers]

Definition at line 2892 of file cuddAPI.c.

02895 {
02896     dd->numberXovers = numberXovers;
02897 
02898 } /* end of Cudd_SetNumberXovers */

void Cudd_SetPopulationSize ( DdManager dd,
int  populationSize 
)

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

Synopsis [Sets the size of the population used by the genetic algorithm for reordering.]

Description [Sets the size of the population used by the genetic algorithm for variable reordering. A larger population size will cause the genetic algorithm to take more time, but will generally produce better results. The default value is 0, in which case the package uses three times the number of variables as population size, with a maximum of 120.]

SideEffects [Changes the manager.]

SeeAlso [Cudd_ReadPopulationSize]

Definition at line 2839 of file cuddAPI.c.

02842 {
02843     dd->populationSize = populationSize;
02844 
02845 } /* end of Cudd_SetPopulationSize */

void Cudd_SetRecomb ( DdManager dd,
int  recomb 
)

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

Synopsis [Sets the value of the recombination parameter used in group sifting.]

Description [Sets the value of the recombination parameter used in group sifting. A larger (positive) value makes the aggregation of variables due to the second difference criterion more likely. A smaller (negative) value makes aggregation less likely. The default value is 0.]

SideEffects [Changes the manager.]

SeeAlso [Cudd_ReadRecomb]

Definition at line 2678 of file cuddAPI.c.

02681 {
02682     dd->recomb = recomb;
02683 
02684 } /* end of Cudd_SetRecomb */

void Cudd_SetReorderingCycle ( DdManager dd,
int  cycle 
)

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

Synopsis [Sets the reordCycle parameter of the manager.]

Description [Sets the reordCycle parameter of the manager. This parameter determines how often the alternate threshold on maximum growth is used in reordering.]

SideEffects [None]

SeeAlso [Cudd_ReadMaxGrowthAlternate Cudd_SetMaxGrowthAlternate Cudd_ReadReorderingCycle]

Definition at line 2107 of file cuddAPI.c.

02110 {
02111     dd->reordCycle = cycle;
02112 
02113 } /* end of Cudd_SetReorderingCycle */

void Cudd_SetSiftMaxSwap ( DdManager dd,
int  sms 
)

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

Synopsis [Sets the siftMaxSwap parameter of the manager.]

Description [Sets the siftMaxSwap parameter of the manager. This parameter gives the maximum number of swaps that will be attempted for each invocation of sifting. The real number of swaps may exceed the set limit because the package will always complete the sifting of the variable that causes the limit to be reached.]

SideEffects [None]

SeeAlso [Cudd_SetSiftMaxVar Cudd_ReadSiftMaxSwap]

Definition at line 1958 of file cuddAPI.c.

01961 {
01962     dd->siftMaxSwap = sms;
01963 
01964 } /* end of Cudd_SetSiftMaxSwap */

void Cudd_SetSiftMaxVar ( DdManager dd,
int  smv 
)

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

Synopsis [Sets the siftMaxVar parameter of the manager.]

Description [Sets the siftMaxVar parameter of the manager. This parameter gives the maximum number of variables that will be sifted for each invocation of sifting.]

SideEffects [None]

SeeAlso [Cudd_SetSiftMaxSwap Cudd_ReadSiftMaxVar]

Definition at line 1909 of file cuddAPI.c.

01912 {
01913     dd->siftMaxVar = smv;
01914 
01915 } /* end of Cudd_SetSiftMaxVar */

void Cudd_SetStderr ( DdManager dd,
FILE *  fp 
)

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

Synopsis [Sets the stderr of a manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_ReadStderr Cudd_SetStdout]

Definition at line 3714 of file cuddAPI.c.

03717 {
03718     dd->err = fp;
03719 
03720 } /* end of Cudd_SetStderr */

void Cudd_SetStdout ( DdManager dd,
FILE *  fp 
)

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

Synopsis [Sets the stdout of a manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_ReadStdout Cudd_SetStderr]

Definition at line 3671 of file cuddAPI.c.

03674 {
03675     dd->out = fp;
03676 
03677 } /* end of Cudd_SetStdout */

void Cudd_SetSymmviolation ( DdManager dd,
int  symmviolation 
)

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

Synopsis [Sets the value of the symmviolation parameter used in group sifting.]

Description [Sets the value of the symmviolation parameter. This parameter is used in group sifting to decide how many violations to the symmetry conditions f10 = f01 or f11 = f00 are tolerable when checking for aggregation due to extended symmetry. The value should be between 0 and 100. A small value causes fewer variables to be aggregated. The default value is 0.]

SideEffects [Changes the manager.]

SeeAlso [Cudd_ReadSymmviolation]

Definition at line 2733 of file cuddAPI.c.

02736 {
02737     dd->symmviolation = symmviolation;
02738 
02739 } /* end of Cudd_SetSymmviolation */

void Cudd_SetTree ( DdManager dd,
MtrNode tree 
)

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

Synopsis [Sets the variable group tree of the manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_FreeTree Cudd_ReadTree Cudd_SetZddTree]

Definition at line 2148 of file cuddAPI.c.

02151 {
02152     if (dd->tree != NULL) {
02153         Mtr_FreeTree(dd->tree);
02154     }
02155     dd->tree = tree;
02156     if (tree == NULL) return;
02157 
02158     fixVarTree(tree, dd->perm, dd->size);
02159     return;
02160 
02161 } /* end of Cudd_SetTree */

int Cudd_SetVarMap ( DdManager manager,
DdNode **  x,
DdNode **  y,
int  n 
)

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

Synopsis [Registers a variable mapping with the manager.]

Description [Registers with the manager a variable mapping described by two sets of variables. This variable mapping is then used by functions like Cudd_bddVarMap. This function is convenient for those applications that perform the same mapping several times. However, if several different permutations are used, it may be more efficient not to rely on the registered mapping, because changing mapping causes the cache to be cleared. (The initial setting, however, does not clear the cache.) The two sets of variables (x and y) must have the same size (x and y). The size is given by n. The two sets of variables are normally disjoint, but this restriction is not imposeded by the function. When new variables are created, the map is automatically extended (each new variable maps to itself). The typical use, however, is to wait until all variables are created, and then create the map. Returns 1 if the mapping is successfully registered with the manager; 0 otherwise.]

SideEffects [Modifies the manager. May clear the cache.]

SeeAlso [Cudd_bddVarMap Cudd_bddPermute Cudd_bddSwapVariables]

Definition at line 412 of file cuddCompose.c.

00417 {
00418     int i;
00419 
00420     if (manager->map != NULL) {
00421         cuddCacheFlush(manager);
00422     } else {
00423         manager->map = ALLOC(int,manager->maxSize);
00424         if (manager->map == NULL) {
00425             manager->errorCode = CUDD_MEMORY_OUT;
00426             return(0);
00427         }
00428         manager->memused += sizeof(int) * manager->maxSize;
00429     }
00430     /* Initialize the map to the identity. */
00431     for (i = 0; i < manager->size; i++) {
00432         manager->map[i] = i;
00433     }
00434     /* Create the map. */
00435     for (i = 0; i < n; i++) {
00436         manager->map[x[i]->index] = y[i]->index;
00437         manager->map[y[i]->index] = x[i]->index;
00438     }
00439     return(1);
00440 
00441 } /* end of Cudd_SetVarMap */

void Cudd_SetZddTree ( DdManager dd,
MtrNode tree 
)

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

Synopsis [Sets the ZDD variable group tree of the manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_FreeZddTree Cudd_ReadZddTree Cudd_SetTree]

Definition at line 2220 of file cuddAPI.c.

02223 {
02224     if (dd->treeZ != NULL) {
02225         Mtr_FreeTree(dd->treeZ);
02226     }
02227     dd->treeZ = tree;
02228     if (tree == NULL) return;
02229 
02230     fixVarTree(tree, dd->permZ, dd->sizeZ);
02231     return;
02232 
02233 } /* end of Cudd_SetZddTree */

int Cudd_SharingSize ( DdNode **  nodeArray,
int  n 
)

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

Synopsis [Counts the number of nodes in an array of DDs.]

Description [Counts the number of nodes in an array of DDs. Shared nodes are counted only once. Returns the total number of nodes.]

SideEffects [None]

SeeAlso [Cudd_DagSize]

Definition at line 540 of file cuddUtil.c.

00543 {
00544     int i,j;
00545 
00546     i = 0;
00547     for (j = 0; j < n; j++) {
00548         i += ddDagInt(Cudd_Regular(nodeArray[j]));
00549     }
00550     for (j = 0; j < n; j++) {
00551         ddClearFlag(Cudd_Regular(nodeArray[j]));
00552     }
00553     return(i);
00554 
00555 } /* end of Cudd_SharingSize */

int Cudd_ShortestLength ( DdManager manager,
DdNode f,
int *  weight 
)

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

Synopsis [Find the length of the shortest path(s) in a DD.]

Description [Find the length of the shortest path(s) in a DD. f is the DD we want to get the shortest path for; weight\[i\] is the weight of the THEN edge coming from the node whose index is i. All ELSE edges have 0 weight. Returns the length of the shortest path(s) if such a path is found; a large number if the function is identically 0, and CUDD_OUT_OF_MEM in case of failure.]

SideEffects [None]

SeeAlso [Cudd_ShortestPath]

Definition at line 353 of file cuddSat.c.

00357 {
00358     register    DdNode  *F;
00359     st_table    *visited;
00360     cuddPathPair *my_pair;
00361     int         complement, cost;
00362 
00363     one = DD_ONE(manager);
00364     zero = DD_ZERO(manager);
00365 
00366     if (f == Cudd_Not(one) || f == zero) {
00367         return(DD_BIGGY);
00368     }
00369 
00370     /* From this point on, a path exists. */
00371     /* Initialize visited table and support. */
00372     visited = st_init_table(st_ptrcmp, st_ptrhash);
00373 
00374     /* Now get the length of the shortest path(s) from f to 1. */
00375     (void) getShortest(f, weight, NULL, visited);
00376 
00377     complement = Cudd_IsComplement(f);
00378 
00379     F = Cudd_Regular(f);
00380 
00381     if (!st_lookup(visited, F, &my_pair)) return(CUDD_OUT_OF_MEM);
00382     
00383     if (complement) {
00384         cost = my_pair->neg;
00385     } else {
00386         cost = my_pair->pos;
00387     }
00388 
00389     st_foreach(visited, freePathPair, NULL);
00390     st_free_table(visited);
00391 
00392     return(cost);
00393 
00394 } /* end of Cudd_ShortestLength */

DdNode* Cudd_ShortestPath ( DdManager manager,
DdNode f,
int *  weight,
int *  support,
int *  length 
)

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

Synopsis [Finds a shortest path in a DD.]

Description [Finds a shortest path in a DD. f is the DD we want to get the shortest path for; weight\[i\] is the weight of the THEN arc coming from the node whose index is i. If weight is NULL, then unit weights are assumed for all THEN arcs. All ELSE arcs have 0 weight. If non-NULL, both weight and support should point to arrays with at least as many entries as there are variables in the manager. Returns the shortest path as the BDD of a cube.]

SideEffects [support contains on return the true support of f. If support is NULL on entry, then Cudd_ShortestPath does not compute the true support info. length contains the length of the path.]

SeeAlso [Cudd_ShortestLength Cudd_LargestCube]

Definition at line 197 of file cuddSat.c.

00203 {
00204     DdNode      *F;
00205     st_table    *visited;
00206     DdNode      *sol;
00207     cuddPathPair *rootPair;
00208     int         complement, cost;
00209     int         i;
00210 
00211     one = DD_ONE(manager);
00212     zero = DD_ZERO(manager);
00213 
00214     /* Initialize support. Support does not depend on variable order.
00215     ** Hence, it does not need to be reinitialized if reordering occurs.
00216     */
00217     if (support) {
00218       for (i = 0; i < manager->size; i++) {
00219         support[i] = 0;
00220       }
00221     }
00222 
00223     if (f == Cudd_Not(one) || f == zero) {
00224       *length = DD_BIGGY;
00225       return(Cudd_Not(one));
00226     }
00227     /* From this point on, a path exists. */
00228 
00229     do {
00230         manager->reordered = 0;
00231 
00232         /* Initialize visited table. */
00233         visited = st_init_table(st_ptrcmp, st_ptrhash);
00234 
00235         /* Now get the length of the shortest path(s) from f to 1. */
00236         (void) getShortest(f, weight, support, visited);
00237 
00238         complement = Cudd_IsComplement(f);
00239 
00240         F = Cudd_Regular(f);
00241 
00242         if (!st_lookup(visited, F, &rootPair)) return(NULL);
00243 
00244         if (complement) {
00245           cost = rootPair->neg;
00246         } else {
00247           cost = rootPair->pos;
00248         }
00249 
00250         /* Recover an actual shortest path. */
00251         sol = getPath(manager,visited,f,weight,cost);
00252 
00253         st_foreach(visited, freePathPair, NULL);
00254         st_free_table(visited);
00255 
00256     } while (manager->reordered == 1);
00257 
00258     *length = cost;
00259     return(sol);
00260 
00261 } /* end of Cudd_ShortestPath */

int Cudd_ShuffleHeap ( DdManager table,
int *  permutation 
)

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

Synopsis [Reorders variables according to given permutation.]

Description [Reorders variables according to given permutation. The i-th entry of the permutation array contains the index of the variable that should be brought to the i-th level. The size of the array should be equal or greater to the number of variables currently in use. Returns 1 in case of success; 0 otherwise.]

SideEffects [Changes the variable order for all diagrams and clears the cache.]

SeeAlso [Cudd_ReduceHeap]

Definition at line 334 of file cuddReorder.c.

00337 {
00338 
00339     int result;
00340     int i;
00341     int identity = 1;
00342     int *perm;
00343 
00344     /* Don't waste time in case of identity permutation. */
00345     for (i = 0; i < table->size; i++) {
00346         if (permutation[i] != table->invperm[i]) {
00347             identity = 0;
00348             break;
00349         }
00350     }
00351     if (identity == 1) {
00352         return(1);
00353     }
00354     if (!ddReorderPreprocess(table)) return(0);
00355     if (table->keys > table->peakLiveNodes) {
00356         table->peakLiveNodes = table->keys;
00357     }
00358 
00359     perm = ALLOC(int, table->size);
00360     for (i = 0; i < table->size; i++)
00361         perm[permutation[i]] = i;
00362     if (!ddCheckPermuation(table,table->tree,perm,permutation)) {
00363         FREE(perm);
00364         return(0);
00365     }
00366     if (!ddUpdateMtrTree(table,table->tree,perm,permutation)) {
00367         FREE(perm);
00368         return(0);
00369     }
00370     FREE(perm);
00371 
00372     result = ddShuffle(table,permutation);
00373 
00374     if (!ddReorderPostprocess(table)) return(0);
00375 
00376     return(result);
00377 
00378 } /* end of Cudd_ShuffleHeap */

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

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

Synopsis [Implements the solution of F(x,y) = 0.]

Description [Implements the solution for F(x,y) = 0. The return value is the consistency condition. The y variables are the unknowns and the remaining variables are the parameters. Returns the consistency condition if successful; NULL otherwise. Cudd_SolveEqn allocates an array and fills it with the indices of the unknowns. This array is used by Cudd_VerifySol.]

SideEffects [The solution is returned in G; the indices of the y variables are returned in yIndex.]

SeeAlso [Cudd_VerifySol]

Definition at line 122 of file cuddSolve.c.

00129 {
00130     DdNode *res;
00131     int *temp;
00132 
00133     *yIndex = temp = ALLOC(int, n);
00134     if (temp == NULL) {
00135         bdd->errorCode = CUDD_MEMORY_OUT;
00136         (void) fprintf(bdd->out,
00137                        "Cudd_SolveEqn: Out of memory for yIndex\n");
00138         return(NULL);
00139     }
00140 
00141     do {
00142         bdd->reordered = 0;
00143         res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0);
00144     } while (bdd->reordered == 1);
00145 
00146     return(res);
00147 
00148 } /* end of Cudd_SolveEqn */

DdNode* Cudd_SplitSet ( DdManager manager,
DdNode S,
DdNode **  xVars,
int  n,
double  m 
)

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

Synopsis [Returns m minterms from a BDD.]

Description [Returns m minterms from a BDD whose support has n variables at most. The procedure tries to create as few extra nodes as possible. The function represented by S depends on at most n of the variables in xVars. Returns a BDD with m minterms of the on-set of S if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 124 of file cuddSplit.c.

00130 {
00131     DdNode *result;
00132     DdNode *zero, *one;
00133     double  max, num;
00134     st_table *mtable;
00135     int *varSeen;
00136     int i,index, size;
00137 
00138     size = manager->size;
00139     one = DD_ONE(manager);
00140     zero = Cudd_Not(one);
00141 
00142     /* Trivial cases. */
00143     if (m == 0.0) {
00144         return(zero);
00145     }
00146     if (S == zero) {
00147         return(NULL);
00148     }
00149 
00150     max = pow(2.0,(double)n);
00151     if (m > max)
00152         return(NULL);
00153 
00154     do {
00155         manager->reordered = 0;
00156         /* varSeen is used to mark the variables that are encountered
00157         ** while traversing the BDD S.
00158         */
00159         varSeen = ALLOC(int, size);
00160         if (varSeen == NULL) {
00161             manager->errorCode = CUDD_MEMORY_OUT;
00162             return(NULL);
00163         }
00164         for (i = 0; i < size; i++) {
00165             varSeen[i] = -1;
00166         }
00167         for (i = 0; i < n; i++) {
00168             index = (xVars[i])->index;
00169             varSeen[manager->invperm[index]] = 0;
00170         }
00171 
00172         if (S == one) {
00173             if (m == max) {
00174                 FREE(varSeen);
00175                 return(S);
00176             }
00177             result = selectMintermsFromUniverse(manager,varSeen,m);
00178             if (result)
00179                 cuddRef(result);
00180             FREE(varSeen);
00181         } else {
00182             mtable = st_init_table(st_ptrcmp,st_ptrhash);
00183             if (mtable == NULL) {
00184                 (void) fprintf(manager->out,
00185                                "Cudd_SplitSet: out-of-memory.\n");
00186                 FREE(varSeen);
00187                 manager->errorCode = CUDD_MEMORY_OUT;
00188                 return(NULL);
00189             }
00190             /* The nodes of BDD S are annotated by the number of minterms
00191             ** in their onset. The node and the number of minterms in its
00192             ** onset are stored in mtable.
00193             */
00194             num = bddAnnotateMintermCount(manager,S,max,mtable);
00195             if (m == num) {
00196                 st_foreach(mtable,cuddStCountfree,NIL(char));
00197                 st_free_table(mtable);
00198                 FREE(varSeen);
00199                 return(S);
00200             }
00201             
00202             result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0);
00203             if (result)
00204                 cuddRef(result);
00205             st_foreach(mtable,cuddStCountfree,NULL);
00206             st_free_table(mtable);
00207             FREE(varSeen);
00208         }
00209     } while (manager->reordered == 1);
00210 
00211     cuddDeref(result);
00212     return(result);
00213 
00214 } /* end of Cudd_SplitSet */

void Cudd_Srandom ( long  seed  ) 

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

Synopsis [Initializer for the portable random number generator.]

Description [Initializer for the portable number generator based on ran2 in "Numerical Recipes in C." The input is the seed for the generator. If it is negative, its absolute value is taken as seed. If it is 0, then 1 is taken as seed. The initialized sets up the two recurrences used to generate a long-period stream, and sets up the shuffle table.]

SideEffects [None]

SeeAlso [Cudd_Random]

Definition at line 2760 of file cuddUtil.c.

02762 {
02763     int i;
02764 
02765     if (seed < 0)       cuddRand = -seed;
02766     else if (seed == 0) cuddRand = 1;
02767     else                cuddRand = seed;
02768     cuddRand2 = cuddRand;
02769     /* Load the shuffle table (after 11 warm-ups). */
02770     for (i = 0; i < STAB_SIZE + 11; i++) {
02771         long int w;
02772         w = cuddRand / LEQQ1;
02773         cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1;
02774         cuddRand += (cuddRand < 0) * MODULUS1;
02775         shuffleTable[i % STAB_SIZE] = cuddRand;
02776     }
02777     shuffleSelect = shuffleTable[1 % STAB_SIZE];
02778 
02779 } /* end of Cudd_Srandom */

int Cudd_StdPostReordHook ( DdManager dd,
const char *  str,
void *  data 
)

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

Synopsis [Sample hook function to call after reordering.]

Description [Sample hook function to call after reordering. Prints on the manager's stdout final size and reordering time. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_StdPreReordHook]

Definition at line 3498 of file cuddAPI.c.

03502 {
03503     long initialTime = (long) data;
03504     int retval;
03505     long finalTime = util_cpu_time();
03506     double totalTimeSec = (double)(finalTime - initialTime) / 1000.0;
03507 
03508     retval = fprintf(dd->out,"%ld nodes in %g sec\n", strcmp(str, "BDD") == 0 ?
03509                      Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd),
03510                      totalTimeSec);
03511     if (retval == EOF) return(0);
03512     retval = fflush(dd->out);
03513     if (retval == EOF) return(0);
03514     return(1);
03515 
03516 } /* end of Cudd_StdPostReordHook */

int Cudd_StdPreReordHook ( DdManager dd,
const char *  str,
void *  data 
)

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

Synopsis [Sample hook function to call before reordering.]

Description [Sample hook function to call before reordering. Prints on the manager's stdout reordering method and initial size. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_StdPostReordHook]

Definition at line 3405 of file cuddAPI.c.

03409 {
03410     Cudd_ReorderingType method = (Cudd_ReorderingType) (ptruint) data;
03411     int retval;
03412 
03413     retval = fprintf(dd->out,"%s reordering with ", str);
03414     if (retval == EOF) return(0);
03415     switch (method) {
03416     case CUDD_REORDER_SIFT_CONVERGE:
03417     case CUDD_REORDER_SYMM_SIFT_CONV:
03418     case CUDD_REORDER_GROUP_SIFT_CONV:
03419     case CUDD_REORDER_WINDOW2_CONV:
03420     case CUDD_REORDER_WINDOW3_CONV:
03421     case CUDD_REORDER_WINDOW4_CONV:
03422     case CUDD_REORDER_LINEAR_CONVERGE:
03423         retval = fprintf(dd->out,"converging ");
03424         if (retval == EOF) return(0);
03425         break;
03426     default:
03427         break;
03428     }
03429     switch (method) {
03430     case CUDD_REORDER_RANDOM:
03431     case CUDD_REORDER_RANDOM_PIVOT:
03432         retval = fprintf(dd->out,"random");
03433         break;
03434     case CUDD_REORDER_SIFT:
03435     case CUDD_REORDER_SIFT_CONVERGE:
03436         retval = fprintf(dd->out,"sifting");
03437         break;
03438     case CUDD_REORDER_SYMM_SIFT:
03439     case CUDD_REORDER_SYMM_SIFT_CONV:
03440         retval = fprintf(dd->out,"symmetric sifting");
03441         break;
03442     case CUDD_REORDER_LAZY_SIFT:
03443         retval = fprintf(dd->out,"lazy sifting");
03444         break;
03445     case CUDD_REORDER_GROUP_SIFT:
03446     case CUDD_REORDER_GROUP_SIFT_CONV:
03447         retval = fprintf(dd->out,"group sifting");
03448         break;
03449     case CUDD_REORDER_WINDOW2:
03450     case CUDD_REORDER_WINDOW3:
03451     case CUDD_REORDER_WINDOW4:
03452     case CUDD_REORDER_WINDOW2_CONV:
03453     case CUDD_REORDER_WINDOW3_CONV:
03454     case CUDD_REORDER_WINDOW4_CONV:
03455         retval = fprintf(dd->out,"window");
03456         break;
03457     case CUDD_REORDER_ANNEALING:
03458         retval = fprintf(dd->out,"annealing");
03459         break;
03460     case CUDD_REORDER_GENETIC:
03461         retval = fprintf(dd->out,"genetic");
03462         break;
03463     case CUDD_REORDER_LINEAR:
03464     case CUDD_REORDER_LINEAR_CONVERGE:
03465         retval = fprintf(dd->out,"linear sifting");
03466         break;
03467     case CUDD_REORDER_EXACT:
03468         retval = fprintf(dd->out,"exact");
03469         break;
03470     default:
03471         return(0);
03472     }
03473     if (retval == EOF) return(0);
03474 
03475     retval = fprintf(dd->out,": from %ld to ... ", strcmp(str, "BDD") == 0 ?
03476                      Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd));
03477     if (retval == EOF) return(0);
03478     fflush(dd->out);
03479     return(1);
03480 
03481 } /* end of Cudd_StdPreReordHook */

DdNode* Cudd_SubsetCompress ( DdManager dd,
DdNode f,
int  nvars,
int  threshold 
)

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

Synopsis [Find a dense subset of BDD f.]

Description [Finds a dense subset of BDD f. Density is the ratio of number of minterms to number of nodes. Uses several techniques in series. It is more expensive than other subsetting procedures, but often produces better results. See Cudd_SubsetShortPaths for a description of the threshold and nvars parameters. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_SubsetRemap Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_bddSqueeze]

Definition at line 696 of file cuddGenCof.c.

00701 {
00702     DdNode *res, *tmp1, *tmp2;
00703 
00704     tmp1 = Cudd_SubsetShortPaths(dd, f, nvars, threshold, 0);
00705     if (tmp1 == NULL) return(NULL);
00706     cuddRef(tmp1);
00707     tmp2 = Cudd_RemapUnderApprox(dd,tmp1,nvars,0,1.0);
00708     if (tmp2 == NULL) {
00709         Cudd_IterDerefBdd(dd,tmp1);
00710         return(NULL);
00711     }
00712     cuddRef(tmp2);
00713     Cudd_IterDerefBdd(dd,tmp1);
00714     res = Cudd_bddSqueeze(dd,tmp2,f);
00715     if (res == NULL) {
00716         Cudd_IterDerefBdd(dd,tmp2);
00717         return(NULL);
00718     }
00719     cuddRef(res);
00720     Cudd_IterDerefBdd(dd,tmp2);
00721     cuddDeref(res);
00722     return(res);
00723 
00724 } /* end of Cudd_SubsetCompress */

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

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

Synopsis [Extracts a dense subset from a BDD with the heavy branch heuristic.]

Description [Extracts a dense subset from a BDD. This procedure builds a subset by throwing away one of the children of each node, starting from the root, until the result is small enough. The child that is eliminated from the result is the one that contributes the fewer minterms. Returns a pointer to the BDD of the subset if successful. NULL if the procedure runs out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation and node count calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize]

Definition at line 205 of file cuddSubsetHB.c.

00210 {
00211     DdNode *subset;
00212 
00213     memOut = 0;
00214     do {
00215         dd->reordered = 0;
00216         subset = cuddSubsetHeavyBranch(dd, f, numVars, threshold);
00217     } while ((dd->reordered == 1) && (!memOut));
00218 
00219     return(subset);
00220 
00221 } /* end of Cudd_SubsetHeavyBranch */

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

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

Synopsis [Extracts a dense subset from a BDD with the shortest paths heuristic.]

Description [Extracts a dense subset from a BDD. This procedure tries to preserve the shortest paths of the input BDD, because they give many minterms and contribute few nodes. This procedure may increase the number of nodes in trying to create the subset or reduce the number of nodes due to recombination as compared to the original BDD. Hence the threshold may not be strictly adhered to. In practice, recombination overshadows the increase in the number of nodes and results in small BDDs as compared to the threshold. The hardlimit specifies whether threshold needs to be strictly adhered to. If it is set to 1, the procedure ensures that result is never larger than the specified limit but may be considerably less than the threshold. Returns a pointer to the BDD for the subset if successful; NULL otherwise. The value for numVars should be as close as possible to the size of the support of f for better efficiency. However, it is safe to pass the value returned by Cudd_ReadSize for numVars. If 0 is passed, then the value returned by Cudd_ReadSize is used.]

SideEffects [None]

SeeAlso [Cudd_SupersetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize]

Definition at line 216 of file cuddSubsetSP.c.

00221                         : 1 if threshold is a hard limit */)
00222 {
00223     DdNode *subset;
00224 
00225     memOut = 0;
00226     do {
00227         dd->reordered = 0;
00228         subset = cuddSubsetShortPaths(dd, f, numVars, threshold, hardlimit);
00229     } while((dd->reordered ==1) && (!memOut));
00230 
00231     return(subset);
00232 
00233 } /* end of Cudd_SubsetShortPaths */

DdNode* Cudd_SubsetWithMaskVars ( DdManager dd,
DdNode f,
DdNode **  vars,
int  nvars,
DdNode **  maskVars,
int  mvars 
)

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

Synopsis [Extracts a subset from a BDD.]

Description [Extracts a subset from a BDD in the following procedure. 1. Compute the weight for each mask variable by counting the number of minterms for both positive and negative cofactors of the BDD with respect to each mask variable. (weight = positive - negative) 2. Find a representative cube of the BDD by using the weight. From the top variable of the BDD, for each variable, if the weight is greater than 0.0, choose THEN branch, othereise ELSE branch, until meeting the constant 1. 3. Quantify out the variables not in maskVars from the representative cube and if a variable in maskVars is don't care, replace the variable with a constant(1 or 0) depending on the weight. 4. Make a subset of the BDD by multiplying with the modified cube.]

SideEffects [None]

SeeAlso []

Definition at line 1598 of file cuddUtil.c.

01605 {
01606     double      *weight;
01607     char        *string;
01608     int         i, size;
01609     int         *indices, *mask;
01610     int         result;
01611     DdNode      *zero, *cube, *newCube, *subset;
01612     DdNode      *cof;
01613 
01614     DdNode      *support;
01615     support = Cudd_Support(dd,f);
01616     cuddRef(support);
01617     Cudd_RecursiveDeref(dd,support);
01618 
01619     zero = Cudd_Not(dd->one);
01620     size = dd->size;
01621 
01622     weight = ALLOC(double,size);
01623     if (weight == NULL) {
01624         dd->errorCode = CUDD_MEMORY_OUT;
01625         return(NULL);
01626     }
01627     for (i = 0; i < size; i++) {
01628         weight[i] = 0.0;
01629     }
01630     for (i = 0; i < mvars; i++) {
01631         cof = Cudd_Cofactor(dd, f, maskVars[i]);
01632         cuddRef(cof);
01633         weight[i] = Cudd_CountMinterm(dd, cof, nvars);
01634         Cudd_RecursiveDeref(dd,cof);
01635 
01636         cof = Cudd_Cofactor(dd, f, Cudd_Not(maskVars[i]));
01637         cuddRef(cof);
01638         weight[i] -= Cudd_CountMinterm(dd, cof, nvars);
01639         Cudd_RecursiveDeref(dd,cof);
01640     }
01641 
01642     string = ALLOC(char, size + 1);
01643     if (string == NULL) {
01644         dd->errorCode = CUDD_MEMORY_OUT;
01645         FREE(weight);
01646         return(NULL);
01647     }
01648     mask = ALLOC(int, size);
01649     if (mask == NULL) {
01650         dd->errorCode = CUDD_MEMORY_OUT;
01651         FREE(weight);
01652         FREE(string);
01653         return(NULL);
01654     }
01655     for (i = 0; i < size; i++) {
01656         string[i] = '2';
01657         mask[i] = 0;
01658     }
01659     string[size] = '\0';
01660     indices = ALLOC(int,nvars);
01661     if (indices == NULL) {
01662         dd->errorCode = CUDD_MEMORY_OUT;
01663         FREE(weight);
01664         FREE(string);
01665         FREE(mask);
01666         return(NULL);
01667     }
01668     for (i = 0; i < nvars; i++) {
01669         indices[i] = vars[i]->index;
01670     }
01671 
01672     result = ddPickRepresentativeCube(dd,f,weight,string);
01673     if (result == 0) {
01674         FREE(weight);
01675         FREE(string);
01676         FREE(mask);
01677         FREE(indices);
01678         return(NULL);
01679     }
01680 
01681     cube = Cudd_ReadOne(dd);
01682     cuddRef(cube);
01683     zero = Cudd_Not(Cudd_ReadOne(dd));
01684     for (i = 0; i < nvars; i++) {
01685         if (string[indices[i]] == '0') {
01686             newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero);
01687         } else if (string[indices[i]] == '1') {
01688             newCube = Cudd_bddIte(dd,cube,vars[i],zero);
01689         } else
01690             continue;
01691         if (newCube == NULL) {
01692             FREE(weight);
01693             FREE(string);
01694             FREE(mask);
01695             FREE(indices);
01696             Cudd_RecursiveDeref(dd,cube);
01697             return(NULL);
01698         }
01699         cuddRef(newCube);
01700         Cudd_RecursiveDeref(dd,cube);
01701         cube = newCube;
01702     }
01703     Cudd_RecursiveDeref(dd,cube);
01704 
01705     for (i = 0; i < mvars; i++) {
01706         mask[maskVars[i]->index] = 1;
01707     }
01708     for (i = 0; i < nvars; i++) {
01709         if (mask[indices[i]]) {
01710             if (string[indices[i]] == '2') {
01711                 if (weight[indices[i]] >= 0.0)
01712                     string[indices[i]] = '1';
01713                 else
01714                     string[indices[i]] = '0';
01715             }
01716         } else {
01717             string[indices[i]] = '2';
01718         }
01719     }
01720 
01721     cube = Cudd_ReadOne(dd);
01722     cuddRef(cube);
01723     zero = Cudd_Not(Cudd_ReadOne(dd));
01724 
01725     /* Build result BDD. */
01726     for (i = 0; i < nvars; i++) {
01727         if (string[indices[i]] == '0') {
01728             newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero);
01729         } else if (string[indices[i]] == '1') {
01730             newCube = Cudd_bddIte(dd,cube,vars[i],zero);
01731         } else
01732             continue;
01733         if (newCube == NULL) {
01734             FREE(weight);
01735             FREE(string);
01736             FREE(mask);
01737             FREE(indices);
01738             Cudd_RecursiveDeref(dd,cube);
01739             return(NULL);
01740         }
01741         cuddRef(newCube);
01742         Cudd_RecursiveDeref(dd,cube);
01743         cube = newCube;
01744     }
01745 
01746     subset = Cudd_bddAnd(dd,f,cube);
01747     cuddRef(subset);
01748     Cudd_RecursiveDeref(dd,cube);
01749 
01750     /* Test. */
01751     if (Cudd_bddLeq(dd,subset,f)) {
01752         cuddDeref(subset);
01753     } else {
01754         Cudd_RecursiveDeref(dd,subset);
01755         subset = NULL;
01756     }
01757 
01758     FREE(weight);
01759     FREE(string);
01760     FREE(mask);
01761     FREE(indices);
01762     return(subset);
01763 
01764 } /* end of Cudd_SubsetWithMaskVars */

DdNode* Cudd_SupersetCompress ( DdManager dd,
DdNode f,
int  nvars,
int  threshold 
)

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

Synopsis [Find a dense superset of BDD f.]

Description [Finds a dense superset of BDD f. Density is the ratio of number of minterms to number of nodes. Uses several techniques in series. It is more expensive than other supersetting procedures, but often produces better results. See Cudd_SupersetShortPaths for a description of the threshold and nvars parameters. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_SubsetCompress Cudd_SupersetRemap Cudd_SupersetShortPaths Cudd_SupersetHeavyBranch Cudd_bddSqueeze]

Definition at line 746 of file cuddGenCof.c.

00751 {
00752     DdNode *subset;
00753 
00754     subset = Cudd_SubsetCompress(dd, Cudd_Not(f),nvars,threshold);
00755 
00756     return(Cudd_NotCond(subset, (subset != NULL)));
00757 
00758 } /* end of Cudd_SupersetCompress */

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

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

Synopsis [Extracts a dense superset from a BDD with the heavy branch heuristic.]

Description [Extracts a dense superset from a BDD. The procedure is identical to the subset procedure except for the fact that it receives the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. This procedure builds a superset by throwing away one of the children of each node starting from the root of the complement function, until the result is small enough. The child that is eliminated from the result is the one that contributes the fewer minterms. Returns a pointer to the BDD of the superset if successful. NULL if intermediate result causes the procedure to run out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation and node count calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SubsetHeavyBranch Cudd_SupersetShortPaths Cudd_ReadSize]

Definition at line 255 of file cuddSubsetHB.c.

00260 {
00261     DdNode *subset, *g;
00262 
00263     g = Cudd_Not(f);
00264     memOut = 0;
00265     do {
00266         dd->reordered = 0;
00267         subset = cuddSubsetHeavyBranch(dd, g, numVars, threshold);
00268     } while ((dd->reordered == 1) && (!memOut));
00269 
00270     return(Cudd_NotCond(subset, (subset != NULL)));
00271 
00272 } /* end of Cudd_SupersetHeavyBranch */

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

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

Synopsis [Extracts a dense superset from a BDD with the shortest paths heuristic.]

Description [Extracts a dense superset from a BDD. The procedure is identical to the subset procedure except for the fact that it receives the complement of the given function. Extracting the subset of the complement function is equivalent to extracting the superset of the function. This procedure tries to preserve the shortest paths of the complement BDD, because they give many minterms and contribute few nodes. This procedure may increase the number of nodes in trying to create the superset or reduce the number of nodes due to recombination as compared to the original BDD. Hence the threshold may not be strictly adhered to. In practice, recombination overshadows the increase in the number of nodes and results in small BDDs as compared to the threshold. The hardlimit specifies whether threshold needs to be strictly adhered to. If it is set to 1, the procedure ensures that result is never larger than the specified limit but may be considerably less than the threshold. Returns a pointer to the BDD for the superset if successful; NULL otherwise. The value for numVars should be as close as possible to the size of the support of f for better efficiency. However, it is safe to pass the value returned by Cudd_ReadSize for numVar. If 0 is passed, then the value returned by Cudd_ReadSize is used.]

SideEffects [None]

SeeAlso [Cudd_SubsetShortPaths Cudd_SupersetHeavyBranch Cudd_ReadSize]

Definition at line 268 of file cuddSubsetSP.c.

00273                         : 1 if threshold is a hard limit */)
00274 {
00275     DdNode *subset, *g;
00276 
00277     g = Cudd_Not(f);
00278     memOut = 0;
00279     do {
00280         dd->reordered = 0;
00281         subset = cuddSubsetShortPaths(dd, g, numVars, threshold, hardlimit);
00282     } while((dd->reordered ==1) && (!memOut));
00283 
00284     return(Cudd_NotCond(subset, (subset != NULL)));
00285 
00286 } /* end of Cudd_SupersetShortPaths */

DdNode* Cudd_Support ( DdManager dd,
DdNode f 
)

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

Synopsis [Finds the variables on which a DD depends.]

Description [Finds the variables on which a DD depends. Returns a BDD consisting of the product of the variables if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_VectorSupport Cudd_ClassifySupport]

Definition at line 736 of file cuddUtil.c.

00739 {
00740     int *support;
00741     DdNode *res, *tmp, *var;
00742     int i,j;
00743     int size;
00744 
00745     /* Allocate and initialize support array for ddSupportStep. */
00746     size = ddMax(dd->size, dd->sizeZ);
00747     support = ALLOC(int,size);
00748     if (support == NULL) {
00749         dd->errorCode = CUDD_MEMORY_OUT;
00750         return(NULL);
00751     }
00752     for (i = 0; i < size; i++) {
00753         support[i] = 0;
00754     }
00755 
00756     /* Compute support and clean up markers. */
00757     ddSupportStep(Cudd_Regular(f),support);
00758     ddClearFlag(Cudd_Regular(f));
00759 
00760     /* Transform support from array to cube. */
00761     do {
00762         dd->reordered = 0;
00763         res = DD_ONE(dd);
00764         cuddRef(res);
00765         for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */
00766             i = (j >= dd->size) ? j : dd->invperm[j];
00767             if (support[i] == 1) {
00768                 /* The following call to cuddUniqueInter is guaranteed
00769                 ** not to trigger reordering because the node we look up
00770                 ** already exists. */
00771                 var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one));
00772                 cuddRef(var);
00773                 tmp = cuddBddAndRecur(dd,res,var);
00774                 if (tmp == NULL) {
00775                     Cudd_RecursiveDeref(dd,res);
00776                     Cudd_RecursiveDeref(dd,var);
00777                     res = NULL;
00778                     break;
00779                 }
00780                 cuddRef(tmp);
00781                 Cudd_RecursiveDeref(dd,res);
00782                 Cudd_RecursiveDeref(dd,var);
00783                 res = tmp;
00784             }
00785         }
00786     } while (dd->reordered == 1);
00787 
00788     FREE(support);
00789     if (res != NULL) cuddDeref(res);
00790     return(res);
00791 
00792 } /* end of Cudd_Support */

int* Cudd_SupportIndex ( DdManager dd,
DdNode f 
)

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

Synopsis [Finds the variables on which a DD depends.]

Description [Finds the variables on which a DD depends. Returns an index array of the variables if successful; NULL otherwise. The size of the array equals the number of variables in the manager. Each entry of the array is 1 if the corresponding variable is in the support of the DD and 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_Support Cudd_VectorSupport Cudd_ClassifySupport]

Definition at line 811 of file cuddUtil.c.

00814 {
00815     int *support;
00816     int i;
00817     int size;
00818 
00819     /* Allocate and initialize support array for ddSupportStep. */
00820     size = ddMax(dd->size, dd->sizeZ);
00821     support = ALLOC(int,size);
00822     if (support == NULL) {
00823         dd->errorCode = CUDD_MEMORY_OUT;
00824         return(NULL);
00825     }
00826     for (i = 0; i < size; i++) {
00827         support[i] = 0;
00828     }
00829 
00830     /* Compute support and clean up markers. */
00831     ddSupportStep(Cudd_Regular(f),support);
00832     ddClearFlag(Cudd_Regular(f));
00833 
00834     return(support);
00835 
00836 } /* end of Cudd_SupportIndex */

int Cudd_SupportSize ( DdManager dd,
DdNode f 
)

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

Synopsis [Counts the variables on which a DD depends.]

Description [Counts the variables on which a DD depends. Returns the number of the variables if successful; CUDD_OUT_OF_MEM otherwise.]

SideEffects [None]

SeeAlso [Cudd_Support]

Definition at line 853 of file cuddUtil.c.

00856 {
00857     int *support;
00858     int i;
00859     int size;
00860     int count;
00861 
00862     /* Allocate and initialize support array for ddSupportStep. */
00863     size = ddMax(dd->size, dd->sizeZ);
00864     support = ALLOC(int,size);
00865     if (support == NULL) {
00866         dd->errorCode = CUDD_MEMORY_OUT;
00867         return(CUDD_OUT_OF_MEM);
00868     }
00869     for (i = 0; i < size; i++) {
00870         support[i] = 0;
00871     }
00872 
00873     /* Compute support and clean up markers. */
00874     ddSupportStep(Cudd_Regular(f),support);
00875     ddClearFlag(Cudd_Regular(f));
00876 
00877     /* Count support variables. */
00878     count = 0;
00879     for (i = 0; i < size; i++) {
00880         if (support[i] == 1) count++;
00881     }
00882 
00883     FREE(support);
00884     return(count);
00885 
00886 } /* end of Cudd_SupportSize */

void Cudd_SymmProfile ( DdManager table,
int  lower,
int  upper 
)

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

Synopsis [Prints statistics on symmetric variables.]

Description []

SideEffects [None]

Definition at line 138 of file cuddSymmetry.c.

00142 {
00143     int i,x,gbot;
00144     int TotalSymm = 0;
00145     int TotalSymmGroups = 0;
00146 
00147     for (i = lower; i <= upper; i++) {
00148         if (table->subtables[i].next != (unsigned) i) {
00149             x = i;
00150             (void) fprintf(table->out,"Group:");
00151             do {
00152                 (void) fprintf(table->out,"  %d",table->invperm[x]);
00153                 TotalSymm++;
00154                 gbot = x;
00155                 x = table->subtables[x].next;
00156             } while (x != i);
00157             TotalSymmGroups++;
00158 #ifdef DD_DEBUG
00159             assert(table->subtables[gbot].next == (unsigned) i);
00160 #endif
00161             i = gbot;
00162             (void) fprintf(table->out,"\n");
00163         }
00164     }
00165     (void) fprintf(table->out,"Total Symmetric = %d\n",TotalSymm);
00166     (void) fprintf(table->out,"Total Groups = %d\n",TotalSymmGroups);
00167 
00168 } /* end of Cudd_SymmProfile */

void Cudd_tlcInfoFree ( DdTlcInfo t  ) 

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

Synopsis [Frees a DdTlcInfo Structure.]

Description [Frees a DdTlcInfo Structure as well as the memory pointed by it.]

SideEffects [None]

SeeAlso []

Definition at line 451 of file cuddEssent.c.

00453 {
00454     if (t->vars != NULL) FREE(t->vars);
00455     if (t->phases != NULL) FREE(t->phases);
00456     FREE(t);
00457 
00458 } /* end of Cudd_tlcInfoFree */

void Cudd_TurnOffCountDead ( DdManager dd  ) 

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

Synopsis [Causes the dead nodes not to be counted towards triggering reordering.]

Description [Causes the dead nodes not to be counted towards triggering reordering. This causes less frequent reorderings. By default dead nodes are not counted. Therefore there is no need to call this function unless Cudd_TurnOnCountDead has been previously called.]

SideEffects [Changes the manager.]

SeeAlso [Cudd_TurnOnCountDead Cudd_DeadAreCounted]

Definition at line 2629 of file cuddAPI.c.

02631 {
02632     dd->countDead = ~0;
02633 
02634 } /* end of Cudd_TurnOffCountDead */

void Cudd_TurnOnCountDead ( DdManager dd  ) 

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

Synopsis [Causes the dead nodes to be counted towards triggering reordering.]

Description [Causes the dead nodes to be counted towards triggering reordering. This causes more frequent reorderings. By default dead nodes are not counted.]

SideEffects [Changes the manager.]

SeeAlso [Cudd_TurnOffCountDead Cudd_DeadAreCounted]

Definition at line 2604 of file cuddAPI.c.

02606 {
02607     dd->countDead = 0;
02608 
02609 } /* end of Cudd_TurnOnCountDead */

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

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

Synopsis [Extracts a dense subset from a BDD with Shiple's underapproximation method.]

Description [Extracts a dense subset from a BDD. This procedure uses a variant of Tom Shiple's underapproximation method. The main difference from the original method is that density is used as cost function. Returns a pointer to the BDD of the subset if successful. NULL if the procedure runs out of memory. The parameter numVars is the maximum number of variables to be used in minterm calculation. The optimal number should be as close as possible to the size of the support of f. However, it is safe to pass the value returned by Cudd_ReadSize for numVars when the number of variables is under 1023. If numVars is larger than 1023, it will cause overflow. If a 0 parameter is passed then the procedure will compute a value which will avoid overflow but will cause underflow with 2046 variables or more.]

SideEffects [None]

SeeAlso [Cudd_SubsetShortPaths Cudd_SubsetHeavyBranch Cudd_ReadSize]

Definition at line 224 of file cuddApprox.c.

00231 {
00232     DdNode *subset;
00233 
00234     do {
00235         dd->reordered = 0;
00236         subset = cuddUnderApprox(dd, f, numVars, threshold, safe, quality);
00237     } while (dd->reordered == 1);
00238 
00239     return(subset);
00240 
00241 } /* end of Cudd_UnderApprox */

DdNode* Cudd_VectorSupport ( DdManager dd,
DdNode **  F,
int  n 
)

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

Synopsis [Finds the variables on which a set of DDs depends.]

Description [Finds the variables on which a set of DDs depends. The set must contain either BDDs and ADDs, or ZDDs. Returns a BDD consisting of the product of the variables if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_Support Cudd_ClassifySupport]

Definition at line 904 of file cuddUtil.c.

00908 {
00909     int *support;
00910     DdNode *res, *tmp, *var;
00911     int i,j;
00912     int size;
00913 
00914     /* Allocate and initialize support array for ddSupportStep. */
00915     size = ddMax(dd->size, dd->sizeZ);
00916     support = ALLOC(int,size);
00917     if (support == NULL) {
00918         dd->errorCode = CUDD_MEMORY_OUT;
00919         return(NULL);
00920     }
00921     for (i = 0; i < size; i++) {
00922         support[i] = 0;
00923     }
00924 
00925     /* Compute support and clean up markers. */
00926     for (i = 0; i < n; i++) {
00927         ddSupportStep(Cudd_Regular(F[i]),support);
00928     }
00929     for (i = 0; i < n; i++) {
00930         ddClearFlag(Cudd_Regular(F[i]));
00931     }
00932 
00933     /* Transform support from array to cube. */
00934     res = DD_ONE(dd);
00935     cuddRef(res);
00936     for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */
00937         i = (j >= dd->size) ? j : dd->invperm[j];
00938         if (support[i] == 1) {
00939             var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one));
00940             cuddRef(var);
00941             tmp = Cudd_bddAnd(dd,res,var);
00942             if (tmp == NULL) {
00943                 Cudd_RecursiveDeref(dd,res);
00944                 Cudd_RecursiveDeref(dd,var);
00945                 FREE(support);
00946                 return(NULL);
00947             }
00948             cuddRef(tmp);
00949             Cudd_RecursiveDeref(dd,res);
00950             Cudd_RecursiveDeref(dd,var);
00951             res = tmp;
00952         }
00953     }
00954 
00955     FREE(support);
00956     cuddDeref(res);
00957     return(res);
00958 
00959 } /* end of Cudd_VectorSupport */

int* Cudd_VectorSupportIndex ( DdManager dd,
DdNode **  F,
int  n 
)

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

Synopsis [Finds the variables on which a set of DDs depends.]

Description [Finds the variables on which a set of DDs depends. The set must contain either BDDs and ADDs, or ZDDs. Returns an index array of the variables if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_SupportIndex Cudd_VectorSupport Cudd_ClassifySupport]

Definition at line 976 of file cuddUtil.c.

00980 {
00981     int *support;
00982     int i;
00983     int size;
00984 
00985     /* Allocate and initialize support array for ddSupportStep. */
00986     size = ddMax(dd->size, dd->sizeZ);
00987     support = ALLOC(int,size);
00988     if (support == NULL) {
00989         dd->errorCode = CUDD_MEMORY_OUT;
00990         return(NULL);
00991     }
00992     for (i = 0; i < size; i++) {
00993         support[i] = 0;
00994     }
00995 
00996     /* Compute support and clean up markers. */
00997     for (i = 0; i < n; i++) {
00998         ddSupportStep(Cudd_Regular(F[i]),support);
00999     }
01000     for (i = 0; i < n; i++) {
01001         ddClearFlag(Cudd_Regular(F[i]));
01002     }
01003 
01004     return(support);
01005 
01006 } /* end of Cudd_VectorSupportIndex */

int Cudd_VectorSupportSize ( DdManager dd,
DdNode **  F,
int  n 
)

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

Synopsis [Counts the variables on which a set of DDs depends.]

Description [Counts the variables on which a set of DDs depends. The set must contain either BDDs and ADDs, or ZDDs. Returns the number of the variables if successful; CUDD_OUT_OF_MEM otherwise.]

SideEffects [None]

SeeAlso [Cudd_VectorSupport Cudd_SupportSize]

Definition at line 1024 of file cuddUtil.c.

01028 {
01029     int *support;
01030     int i;
01031     int size;
01032     int count;
01033 
01034     /* Allocate and initialize support array for ddSupportStep. */
01035     size = ddMax(dd->size, dd->sizeZ);
01036     support = ALLOC(int,size);
01037     if (support == NULL) {
01038         dd->errorCode = CUDD_MEMORY_OUT;
01039         return(CUDD_OUT_OF_MEM);
01040     }
01041     for (i = 0; i < size; i++) {
01042         support[i] = 0;
01043     }
01044 
01045     /* Compute support and clean up markers. */
01046     for (i = 0; i < n; i++) {
01047         ddSupportStep(Cudd_Regular(F[i]),support);
01048     }
01049     for (i = 0; i < n; i++) {
01050         ddClearFlag(Cudd_Regular(F[i]));
01051     }
01052 
01053     /* Count vriables in support. */
01054     count = 0;
01055     for (i = 0; i < size; i++) {
01056         if (support[i] == 1) count++;
01057     }
01058 
01059     FREE(support);
01060     return(count);
01061 
01062 } /* end of Cudd_VectorSupportSize */

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

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

Synopsis [Checks the solution of F(x,y) = 0.]

Description [Checks the solution of F(x,y) = 0. This procedure substitutes the solution components for the unknowns of F and returns the resulting BDD for F.]

SideEffects [Frees the memory pointed by yIndex.]

SeeAlso [Cudd_SolveEqn]

Definition at line 165 of file cuddSolve.c.

00171 {
00172     DdNode *res;
00173 
00174     do {
00175         bdd->reordered = 0;
00176         res = cuddVerifySol(bdd, F, G, yIndex, n);
00177     } while (bdd->reordered == 1);
00178 
00179     FREE(yIndex);
00180 
00181     return(res);
00182 
00183 } /* end of Cudd_VerifySol */

DdNode* Cudd_Xeqy ( DdManager dd,
int  N,
DdNode **  x,
DdNode **  y 
)

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

Synopsis [Generates a BDD for the function x==y.]

Description [This function generates a BDD for the function x==y. Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. The BDD is built bottom-up. It has 3*N-1 internal nodes, if the variables are ordered as follows: x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. ]

SideEffects [None]

SeeAlso [Cudd_addXeqy]

Definition at line 341 of file cuddPriority.c.

00346 {
00347     DdNode *u, *v, *w;
00348     int     i;
00349 
00350     /* Build bottom part of BDD outside loop. */
00351     u = Cudd_bddIte(dd, x[N-1], y[N-1], Cudd_Not(y[N-1]));
00352     if (u == NULL) return(NULL);
00353     cuddRef(u);
00354 
00355     /* Loop to build the rest of the BDD. */
00356     for (i = N-2; i >= 0; i--) {
00357         v = Cudd_bddAnd(dd, y[i], u);
00358         if (v == NULL) {
00359             Cudd_RecursiveDeref(dd, u);
00360             return(NULL);
00361         }
00362         cuddRef(v);
00363         w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u);
00364         if (w == NULL) {
00365             Cudd_RecursiveDeref(dd, u);
00366             Cudd_RecursiveDeref(dd, v);
00367             return(NULL);
00368         }
00369         cuddRef(w);
00370         Cudd_RecursiveDeref(dd, u);
00371         u = Cudd_bddIte(dd, x[i], v, w);
00372         if (u == NULL) {
00373             Cudd_RecursiveDeref(dd, v);
00374             Cudd_RecursiveDeref(dd, w);
00375             return(NULL);
00376         }
00377         cuddRef(u);
00378         Cudd_RecursiveDeref(dd, v);
00379         Cudd_RecursiveDeref(dd, w);
00380     }
00381     cuddDeref(u);
00382     return(u);
00383 
00384 } /* end of Cudd_Xeqy */

DdNode* Cudd_Xgty ( DdManager dd,
int  N,
DdNode **  z,
DdNode **  x,
DdNode **  y 
)

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

Synopsis [Generates a BDD for the function x > y.]

Description [This function generates a BDD for the function x > y. Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. The BDD is built bottom-up. It has 3*N-1 internal nodes, if the variables are ordered as follows: x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\]. Argument z is not used by Cudd_Xgty: it is included to make it call-compatible to Cudd_Dxygtdxz and Cudd_Dxygtdyz.]

SideEffects [None]

SeeAlso [Cudd_PrioritySelect Cudd_Dxygtdxz Cudd_Dxygtdyz]

Definition at line 276 of file cuddPriority.c.

00279                                      : unused */,
00280   DdNode ** x /* array of x variables */,
00281   DdNode ** y /* array of y variables */)
00282 {
00283     DdNode *u, *v, *w;
00284     int     i;
00285 
00286     /* Build bottom part of BDD outside loop. */
00287     u = Cudd_bddAnd(dd, x[N-1], Cudd_Not(y[N-1]));
00288     if (u == NULL) return(NULL);
00289     cuddRef(u);
00290 
00291     /* Loop to build the rest of the BDD. */
00292     for (i = N-2; i >= 0; i--) {
00293         v = Cudd_bddAnd(dd, y[i], Cudd_Not(u));
00294         if (v == NULL) {
00295             Cudd_RecursiveDeref(dd, u);
00296             return(NULL);
00297         }
00298         cuddRef(v);
00299         w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u);
00300         if (w == NULL) {
00301             Cudd_RecursiveDeref(dd, u);
00302             Cudd_RecursiveDeref(dd, v);
00303             return(NULL);
00304         }
00305         cuddRef(w);
00306         Cudd_RecursiveDeref(dd, u);
00307         u = Cudd_bddIte(dd, x[i], Cudd_Not(v), w);
00308         if (u == NULL) {
00309             Cudd_RecursiveDeref(dd, v);
00310             Cudd_RecursiveDeref(dd, w);
00311             return(NULL);
00312         }
00313         cuddRef(u);
00314         Cudd_RecursiveDeref(dd, v);
00315         Cudd_RecursiveDeref(dd, w);
00316 
00317     }
00318     cuddDeref(u);
00319     return(u);
00320 
00321 } /* end of Cudd_Xgty */

DdNode* Cudd_zddChange ( 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.]

SideEffects [None]

SeeAlso []

Definition at line 388 of file cuddZddSetop.c.

00392 {
00393     DdNode      *res;
00394 
00395     if ((unsigned int) var >= CUDD_MAXINDEX - 1) return(NULL);
00396     
00397     do {
00398         dd->reordered = 0;
00399         res = cuddZddChange(dd, P, var);
00400     } while (dd->reordered == 1);
00401     return(res);
00402 
00403 } /* end of Cudd_zddChange */

DdNode* Cudd_zddComplement ( DdManager dd,
DdNode node 
)

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

Synopsis [Computes a complement cover for a ZDD node.]

Description [Computes a complement cover for a ZDD node. For lack of a better method, we first extract the function BDD from the ZDD cover, then make the complement of the ZDD cover from the complement of the BDD node by using ISOP. Returns a pointer to the resulting cover if successful; NULL otherwise. The result depends on current variable order.]

SideEffects [The result depends on current variable order.]

SeeAlso []

Definition at line 328 of file cuddZddFuncs.c.

00331 {
00332     DdNode      *b, *isop, *zdd_I;
00333 
00334     /* Check cache */
00335     zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node);
00336     if (zdd_I)
00337         return(zdd_I);
00338 
00339     b = Cudd_MakeBddFromZddCover(dd, node);
00340     if (!b)
00341         return(NULL);
00342     Cudd_Ref(b);
00343     isop = Cudd_zddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I);
00344     if (!isop) {
00345         Cudd_RecursiveDeref(dd, b);
00346         return(NULL);
00347     }
00348     Cudd_Ref(isop);
00349     Cudd_Ref(zdd_I);
00350     Cudd_RecursiveDeref(dd, b);
00351     Cudd_RecursiveDeref(dd, isop);
00352 
00353     cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I);
00354     Cudd_Deref(zdd_I);
00355     return(zdd_I);
00356 } /* end of Cudd_zddComplement */

int Cudd_zddCount ( DdManager zdd,
DdNode P 
)

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

Synopsis [Counts the number of minterms in a ZDD.]

Description [Returns an integer representing the number of minterms in a ZDD.]

SideEffects [None]

SeeAlso [Cudd_zddCountDouble]

Definition at line 133 of file cuddZddCount.c.

00136 {
00137     st_table    *table;
00138     int         res;
00139     DdNode      *base, *empty;
00140 
00141     base  = DD_ONE(zdd);
00142     empty = DD_ZERO(zdd);
00143     table = st_init_table(st_ptrcmp, st_ptrhash);
00144     if (table == NULL) return(CUDD_OUT_OF_MEM);
00145     res = cuddZddCountStep(P, table, base, empty);
00146     if (res == CUDD_OUT_OF_MEM) {
00147         zdd->errorCode = CUDD_MEMORY_OUT;
00148     }
00149     st_foreach(table, st_zdd_countfree, NIL(char));
00150     st_free_table(table);
00151 
00152     return(res);
00153 
00154 } /* end of Cudd_zddCount */

double Cudd_zddCountDouble ( DdManager zdd,
DdNode P 
)

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

Synopsis [Counts the number of minterms of a ZDD.]

Description [Counts the number of minterms of a ZDD. The result is returned as a double. If the procedure runs out of memory, it returns (double) CUDD_OUT_OF_MEM. This procedure is used in Cudd_zddCountMinterm.]

SideEffects [None]

SeeAlso [Cudd_zddCountMinterm Cudd_zddCount]

Definition at line 172 of file cuddZddCount.c.

00175 {
00176     st_table    *table;
00177     double      res;
00178     DdNode      *base, *empty;
00179 
00180     base  = DD_ONE(zdd);
00181     empty = DD_ZERO(zdd);
00182     table = st_init_table(st_ptrcmp, st_ptrhash);
00183     if (table == NULL) return((double)CUDD_OUT_OF_MEM);
00184     res = cuddZddCountDoubleStep(P, table, base, empty);
00185     if (res == (double)CUDD_OUT_OF_MEM) {
00186         zdd->errorCode = CUDD_MEMORY_OUT;
00187     }
00188     st_foreach(table, st_zdd_count_dbl_free, NIL(char));
00189     st_free_table(table);
00190 
00191     return(res);
00192 
00193 } /* end of Cudd_zddCountDouble */

double Cudd_zddCountMinterm ( DdManager zdd,
DdNode node,
int  path 
)

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

Synopsis [Counts the number of minterms of a ZDD.]

Description [Counts the number of minterms of the ZDD rooted at node. This procedure takes a parameter path that specifies how many variables are in the support of the function. If the procedure runs out of memory, it returns (double) CUDD_OUT_OF_MEM.]

SideEffects [None]

SeeAlso [Cudd_zddCountDouble]

Definition at line 154 of file cuddZddMisc.c.

00158 {
00159     double      dc_var, minterms;
00160 
00161     dc_var = (double)((double)(zdd->sizeZ) - (double)path);
00162     minterms = Cudd_zddCountDouble(zdd, node) / pow(2.0, dc_var);
00163     return(minterms);
00164 
00165 } /* end of Cudd_zddCountMinterm */

char* Cudd_zddCoverPathToString ( DdManager zdd,
int *  path,
char *  str 
)

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

Synopsis [Converts a path of a ZDD representing a cover to a string.]

Description [Converts a path of a ZDD representing a cover to a string. The string represents an implicant of the cover. The path is typically produced by Cudd_zddForeachPath. Returns a pointer to the string if successful; NULL otherwise. If the str input is NULL, it allocates a new string. The string passed to this function must have enough room for all variables and for the terminator.]

SideEffects [None]

SeeAlso [Cudd_zddForeachPath]

Definition at line 471 of file cuddZddUtil.c.

00476 {
00477     int nvars = zdd->sizeZ;
00478     int i;
00479     char *res;
00480 
00481     if (nvars & 1) return(NULL);
00482     nvars >>= 1;
00483     if (str == NULL) {
00484         res = ALLOC(char, nvars+1);
00485         if (res == NULL) return(NULL);
00486     } else {
00487         res = str;
00488     }
00489     for (i = 0; i < nvars; i++) {
00490         int v = (path[2*i] << 2) | path[2*i+1];
00491         switch (v) {
00492         case 0:
00493         case 2:
00494         case 8:
00495         case 10:
00496             res[i] = '-';
00497             break;
00498         case 1:
00499         case 9:
00500             res[i] = '0';
00501             break;
00502         case 4:
00503         case 6:
00504             res[i] = '1';
00505             break;
00506         default:
00507             res[i] = '?';
00508         }
00509     }
00510     res[nvars] = 0;
00511 
00512     return(res);
00513 
00514 } /* end of Cudd_zddCoverPathToString */

int Cudd_zddDagSize ( DdNode p_node  ) 

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

Synopsis [Counts the number of nodes in a ZDD.]

Description [Counts the number of nodes in a ZDD. This function duplicates Cudd_DagSize and is only retained for compatibility.]

SideEffects [None]

SeeAlso [Cudd_DagSize]

Definition at line 123 of file cuddZddMisc.c.

00125 {
00126 
00127     int         i;
00128     st_table    *table;
00129 
00130     table = st_init_table(st_ptrcmp, st_ptrhash);
00131     i = cuddZddDagInt(p_node, table);
00132     st_free_table(table);
00133     return(i);
00134 
00135 } /* end of Cudd_zddDagSize */

DdNode* Cudd_zddDiff ( DdManager dd,
DdNode P,
DdNode Q 
)

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

Synopsis [Computes the difference of two ZDDs.]

Description [Computes the difference of two ZDDs. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_zddDiffConst]

Definition at line 232 of file cuddZddSetop.c.

00236 {
00237     DdNode *res;
00238 
00239     do {
00240         dd->reordered = 0;
00241         res = cuddZddDiff(dd, P, Q);
00242     } while (dd->reordered == 1);
00243     return(res);
00244 
00245 } /* end of Cudd_zddDiff */

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

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

Synopsis [Performs the inclusion test for ZDDs (P implies Q).]

Description [Inclusion test for ZDDs (P implies Q). No new nodes are generated by this procedure. Returns empty if true; a valid pointer different from empty or DD_NON_CONSTANT otherwise.]

SideEffects [None]

SeeAlso [Cudd_zddDiff]

Definition at line 262 of file cuddZddSetop.c.

00266 {
00267     int         p_top, q_top;
00268     DdNode      *empty = DD_ZERO(zdd), *t, *res;
00269     DdManager   *table = zdd;
00270 
00271     statLine(zdd);
00272     if (P == empty)
00273         return(empty);
00274     if (Q == empty)
00275         return(P);
00276     if (P == Q)
00277         return(empty);
00278 
00279     /* Check cache.  The cache is shared by cuddZddDiff(). */
00280     res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q);
00281     if (res != NULL)
00282         return(res);
00283 
00284     if (cuddIsConstant(P))
00285         p_top = P->index;
00286     else
00287         p_top = zdd->permZ[P->index];
00288     if (cuddIsConstant(Q))
00289         q_top = Q->index;
00290     else
00291         q_top = zdd->permZ[Q->index];
00292     if (p_top < q_top) {
00293         res = DD_NON_CONSTANT;
00294     } else if (p_top > q_top) {
00295         res = Cudd_zddDiffConst(zdd, P, cuddE(Q));
00296     } else {
00297         t = Cudd_zddDiffConst(zdd, cuddT(P), cuddT(Q));
00298         if (t != empty)
00299             res = DD_NON_CONSTANT;
00300         else
00301             res = Cudd_zddDiffConst(zdd, cuddE(P), cuddE(Q));
00302     }
00303 
00304     cuddCacheInsert2(table, cuddZddDiff, P, Q, res);
00305 
00306     return(res);
00307 
00308 } /* end of Cudd_zddDiffConst */

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

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

Synopsis [Computes the quotient of two unate covers.]

Description [Computes the quotient of two unate covers represented by ZDDs. Unate covers use one ZDD variable for each BDD variable. Returns a pointer to the resulting ZDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_zddWeakDiv]

Definition at line 237 of file cuddZddFuncs.c.

00241 {
00242     DdNode      *res;
00243 
00244     do {
00245         dd->reordered = 0;
00246         res = cuddZddDivide(dd, f, g);
00247     } while (dd->reordered == 1);
00248     return(res);
00249 
00250 } /* end of Cudd_zddDivide */

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

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

Synopsis [Modified version of Cudd_zddDivide.]

Description [Modified version of Cudd_zddDivide. This function may disappear in future releases.]

SideEffects [None]

SeeAlso []

Definition at line 295 of file cuddZddFuncs.c.

00299 {
00300     DdNode      *res;
00301 
00302     do {
00303         dd->reordered = 0;
00304         res = cuddZddDivideF(dd, f, g);
00305     } while (dd->reordered == 1);
00306     return(res);
00307 
00308 } /* end of Cudd_zddDivideF */

int Cudd_zddDumpDot ( DdManager dd,
int  n,
DdNode **  f,
char **  inames,
char **  onames,
FILE *  fp 
)

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

Synopsis [Writes a dot file representing the argument ZDDs.]

Description [Writes a file representing the argument ZDDs in a format suitable for the graph drawing program dot. It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file system full). Cudd_zddDumpDot does not close the file: This is the caller responsibility. Cudd_zddDumpDot uses a minimal unique subset of the hexadecimal address of a node as name for it. If the argument inames is non-null, it is assumed to hold the pointers to the names of the inputs. Similarly for onames. Cudd_zddDumpDot uses the following convention to draw arcs:

  • solid line: THEN arcs;
  • dashed line: ELSE arcs.

The dot options are chosen so that the drawing fits on a letter-size sheet. ]

SideEffects [None]

SeeAlso [Cudd_DumpDot Cudd_zddPrintDebug]

Definition at line 545 of file cuddZddUtil.c.

00552 {
00553     DdNode      *support = NULL;
00554     DdNode      *scan;
00555     int         *sorted = NULL;
00556     int         nvars = dd->sizeZ;
00557     st_table    *visited = NULL;
00558     st_generator *gen;
00559     int         retval;
00560     int         i, j;
00561     int         slots;
00562     DdNodePtr   *nodelist;
00563     long        refAddr, diff, mask;
00564 
00565     /* Build a bit array with the support of f. */
00566     sorted = ALLOC(int,nvars);
00567     if (sorted == NULL) {
00568         dd->errorCode = CUDD_MEMORY_OUT;
00569         goto failure;
00570     }
00571     for (i = 0; i < nvars; i++) sorted[i] = 0;
00572 
00573     /* Take the union of the supports of each output function. */
00574     for (i = 0; i < n; i++) {
00575         support = Cudd_Support(dd,f[i]);
00576         if (support == NULL) goto failure;
00577         cuddRef(support);
00578         scan = support;
00579         while (!cuddIsConstant(scan)) {
00580             sorted[scan->index] = 1;
00581             scan = cuddT(scan);
00582         }
00583         Cudd_RecursiveDeref(dd,support);
00584     }
00585     support = NULL; /* so that we do not try to free it in case of failure */
00586 
00587     /* Initialize symbol table for visited nodes. */
00588     visited = st_init_table(st_ptrcmp, st_ptrhash);
00589     if (visited == NULL) goto failure;
00590 
00591     /* Collect all the nodes of this DD in the symbol table. */
00592     for (i = 0; i < n; i++) {
00593         retval = cuddCollectNodes(f[i],visited);
00594         if (retval == 0) goto failure;
00595     }
00596 
00597     /* Find how many most significant hex digits are identical
00598     ** in the addresses of all the nodes. Build a mask based
00599     ** on this knowledge, so that digits that carry no information
00600     ** will not be printed. This is done in two steps.
00601     **  1. We scan the symbol table to find the bits that differ
00602     **     in at least 2 addresses.
00603     **  2. We choose one of the possible masks. There are 8 possible
00604     **     masks for 32-bit integer, and 16 possible masks for 64-bit
00605     **     integers.
00606     */
00607 
00608     /* Find the bits that are different. */
00609     refAddr = (long) f[0];
00610     diff = 0;
00611     gen = st_init_gen(visited);
00612     while (st_gen(gen, &scan, NULL)) {
00613         diff |= refAddr ^ (long) scan;
00614     }
00615     st_free_gen(gen);
00616 
00617     /* Choose the mask. */
00618     for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) {
00619         mask = (1 << i) - 1;
00620         if (diff <= mask) break;
00621     }
00622 
00623     /* Write the header and the global attributes. */
00624     retval = fprintf(fp,"digraph \"ZDD\" {\n");
00625     if (retval == EOF) return(0);
00626     retval = fprintf(fp,
00627         "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n");
00628     if (retval == EOF) return(0);
00629 
00630     /* Write the input name subgraph by scanning the support array. */
00631     retval = fprintf(fp,"{ node [shape = plaintext];\n");
00632     if (retval == EOF) goto failure;
00633     retval = fprintf(fp,"  edge [style = invis];\n");
00634     if (retval == EOF) goto failure;
00635     /* We use a name ("CONST NODES") with an embedded blank, because
00636     ** it is unlikely to appear as an input name.
00637     */
00638     retval = fprintf(fp,"  \"CONST NODES\" [style = invis];\n");
00639     if (retval == EOF) goto failure;
00640     for (i = 0; i < nvars; i++) {
00641         if (sorted[dd->invpermZ[i]]) {
00642             if (inames == NULL) {
00643                 retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]);
00644             } else {
00645                 retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]);
00646             }
00647             if (retval == EOF) goto failure;
00648         }
00649     }
00650     retval = fprintf(fp,"\"CONST NODES\"; \n}\n");
00651     if (retval == EOF) goto failure;
00652 
00653     /* Write the output node subgraph. */
00654     retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n");
00655     if (retval == EOF) goto failure;
00656     for (i = 0; i < n; i++) {
00657         if (onames == NULL) {
00658             retval = fprintf(fp,"\"F%d\"", i);
00659         } else {
00660             retval = fprintf(fp,"\"  %s  \"", onames[i]);
00661         }
00662         if (retval == EOF) goto failure;
00663         if (i == n - 1) {
00664             retval = fprintf(fp,"; }\n");
00665         } else {
00666             retval = fprintf(fp," -> ");
00667         }
00668         if (retval == EOF) goto failure;
00669     }
00670 
00671     /* Write rank info: All nodes with the same index have the same rank. */
00672     for (i = 0; i < nvars; i++) {
00673         if (sorted[dd->invpermZ[i]]) {
00674             retval = fprintf(fp,"{ rank = same; ");
00675             if (retval == EOF) goto failure;
00676             if (inames == NULL) {
00677                 retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]);
00678             } else {
00679                 retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]);
00680             }
00681             if (retval == EOF) goto failure;
00682             nodelist = dd->subtableZ[i].nodelist;
00683             slots = dd->subtableZ[i].slots;
00684             for (j = 0; j < slots; j++) {
00685                 scan = nodelist[j];
00686                 while (scan != NULL) {
00687                     if (st_is_member(visited,(char *) scan)) {
00688                         retval = fprintf(fp,"\"%p\";\n", (void *)
00689                                          ((mask & (ptrint) scan) /
00690                                           sizeof(DdNode)));
00691                         if (retval == EOF) goto failure;
00692                     }
00693                     scan = scan->next;
00694                 }
00695             }
00696             retval = fprintf(fp,"}\n");
00697             if (retval == EOF) goto failure;
00698         }
00699     }
00700 
00701     /* All constants have the same rank. */
00702     retval = fprintf(fp,
00703         "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; ");
00704     if (retval == EOF) goto failure;
00705     nodelist = dd->constants.nodelist;
00706     slots = dd->constants.slots;
00707     for (j = 0; j < slots; j++) {
00708         scan = nodelist[j];
00709         while (scan != NULL) {
00710             if (st_is_member(visited,(char *) scan)) {
00711                 retval = fprintf(fp,"\"%p\";\n", (void *)
00712                                  ((mask & (ptrint) scan) / sizeof(DdNode)));
00713                 if (retval == EOF) goto failure;
00714             }
00715             scan = scan->next;
00716         }
00717     }
00718     retval = fprintf(fp,"}\n}\n");
00719     if (retval == EOF) goto failure;
00720 
00721     /* Write edge info. */
00722     /* Edges from the output nodes. */
00723     for (i = 0; i < n; i++) {
00724         if (onames == NULL) {
00725             retval = fprintf(fp,"\"F%d\"", i);
00726         } else {
00727             retval = fprintf(fp,"\"  %s  \"", onames[i]);
00728         }
00729         if (retval == EOF) goto failure;
00730         retval = fprintf(fp," -> \"%p\" [style = solid];\n",
00731                          (void *) ((mask & (ptrint) f[i]) /
00732                                           sizeof(DdNode)));
00733         if (retval == EOF) goto failure;
00734     }
00735 
00736     /* Edges from internal nodes. */
00737     for (i = 0; i < nvars; i++) {
00738         if (sorted[dd->invpermZ[i]]) {
00739             nodelist = dd->subtableZ[i].nodelist;
00740             slots = dd->subtableZ[i].slots;
00741             for (j = 0; j < slots; j++) {
00742                 scan = nodelist[j];
00743                 while (scan != NULL) {
00744                     if (st_is_member(visited,(char *) scan)) {
00745                         retval = fprintf(fp,
00746                             "\"%p\" -> \"%p\";\n",
00747                             (void *) ((mask & (ptrint) scan) / sizeof(DdNode)),
00748                             (void *) ((mask & (ptrint) cuddT(scan)) /
00749                                       sizeof(DdNode)));
00750                         if (retval == EOF) goto failure;
00751                         retval = fprintf(fp,
00752                                          "\"%p\" -> \"%p\" [style = dashed];\n",
00753                                          (void *) ((mask & (ptrint) scan)
00754                                                    / sizeof(DdNode)),
00755                                          (void *) ((mask & (ptrint)
00756                                                     cuddE(scan)) /
00757                                                    sizeof(DdNode)));
00758                         if (retval == EOF) goto failure;
00759                     }
00760                     scan = scan->next;
00761                 }
00762             }
00763         }
00764     }
00765 
00766     /* Write constant labels. */
00767     nodelist = dd->constants.nodelist;
00768     slots = dd->constants.slots;
00769     for (j = 0; j < slots; j++) {
00770         scan = nodelist[j];
00771         while (scan != NULL) {
00772             if (st_is_member(visited,(char *) scan)) {
00773                 retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n",
00774                                  (void *) ((mask & (ptrint) scan) /
00775                                            sizeof(DdNode)),
00776                                  cuddV(scan));
00777                 if (retval == EOF) goto failure;
00778             }
00779             scan = scan->next;
00780         }
00781     }
00782 
00783     /* Write trailer and return. */
00784     retval = fprintf(fp,"}\n");
00785     if (retval == EOF) goto failure;
00786 
00787     st_free_table(visited);
00788     FREE(sorted);
00789     return(1);
00790 
00791 failure:
00792     if (sorted != NULL) FREE(sorted);
00793     if (visited != NULL) st_free_table(visited);
00794     return(0);
00795 
00796 } /* end of Cudd_zddDumpBlif */

DdGen* Cudd_zddFirstPath ( DdManager zdd,
DdNode f,
int **  path 
)

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

Synopsis [Finds the first path of a ZDD.]

Description [Defines an iterator on the paths of a ZDD and finds its first path. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise.

A path is represented as an array of literals, which are integers in {0, 1, 2}; 0 represents an else arc out of a node, 1 represents a then arc out of a node, and 2 stands for the absence of a node. The size of the array equals the number of variables in the manager at the time Cudd_zddFirstCube is called.

The paths that end in the empty terminal are not enumerated.]

SideEffects [The first path is returned as a side effect.]

SeeAlso [Cudd_zddForeachPath Cudd_zddNextPath Cudd_GenFree Cudd_IsGenEmpty]

Definition at line 271 of file cuddZddUtil.c.

00275 {
00276     DdGen *gen;
00277     DdNode *top, *next, *prev;
00278     int i;
00279     int nvars;
00280 
00281     /* Sanity Check. */
00282     if (zdd == NULL || f == NULL) return(NULL);
00283 
00284     /* Allocate generator an initialize it. */
00285     gen = ALLOC(DdGen,1);
00286     if (gen == NULL) {
00287         zdd->errorCode = CUDD_MEMORY_OUT;
00288         return(NULL);
00289     }
00290 
00291     gen->manager = zdd;
00292     gen->type = CUDD_GEN_ZDD_PATHS;
00293     gen->status = CUDD_GEN_EMPTY;
00294     gen->gen.cubes.cube = NULL;
00295     gen->gen.cubes.value = DD_ZERO_VAL;
00296     gen->stack.sp = 0;
00297     gen->stack.stack = NULL;
00298     gen->node = NULL;
00299 
00300     nvars = zdd->sizeZ;
00301     gen->gen.cubes.cube = ALLOC(int,nvars);
00302     if (gen->gen.cubes.cube == NULL) {
00303         zdd->errorCode = CUDD_MEMORY_OUT;
00304         FREE(gen);
00305         return(NULL);
00306     }
00307     for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2;
00308 
00309     /* The maximum stack depth is one plus the number of variables.
00310     ** because a path may have nodes at all levels, including the
00311     ** constant level.
00312     */
00313     gen->stack.stack = ALLOC(DdNodePtr, nvars+1);
00314     if (gen->stack.stack == NULL) {
00315         zdd->errorCode = CUDD_MEMORY_OUT;
00316         FREE(gen->gen.cubes.cube);
00317         FREE(gen);
00318         return(NULL);
00319     }
00320     for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL;
00321 
00322     /* Find the first path of the ZDD. */
00323     gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++;
00324 
00325     while (1) {
00326         top = gen->stack.stack[gen->stack.sp-1];
00327         if (!cuddIsConstant(Cudd_Regular(top))) {
00328             /* Take the else branch first. */
00329             gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0;
00330             next = cuddE(Cudd_Regular(top));
00331             gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++;
00332         } else if (Cudd_Regular(top) == DD_ZERO(zdd)) {
00333             /* Backtrack. */
00334             while (1) {
00335                 if (gen->stack.sp == 1) {
00336                     /* The current node has no predecessor. */
00337                     gen->status = CUDD_GEN_EMPTY;
00338                     gen->stack.sp--;
00339                     goto done;
00340                 }
00341                 prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]);
00342                 next = cuddT(prev);
00343                 if (next != top) { /* follow the then branch next */
00344                     gen->gen.cubes.cube[prev->index] = 1;
00345                     gen->stack.stack[gen->stack.sp-1] = next;
00346                     break;
00347                 }
00348                 /* Pop the stack and try again. */
00349                 gen->gen.cubes.cube[prev->index] = 2;
00350                 gen->stack.sp--;
00351                 top = gen->stack.stack[gen->stack.sp-1];
00352             }
00353         } else {
00354             gen->status = CUDD_GEN_NONEMPTY;
00355             gen->gen.cubes.value = cuddV(Cudd_Regular(top));
00356             goto done;
00357         }
00358     }
00359 
00360 done:
00361     *path = gen->gen.cubes.cube;
00362     return(gen);
00363 
00364 } /* end of Cudd_zddFirstPath */

DdNode* Cudd_zddIntersect ( DdManager dd,
DdNode P,
DdNode Q 
)

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

Synopsis [Computes the intersection of two ZDDs.]

Description [Computes the intersection of two ZDDs. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 203 of file cuddZddSetop.c.

00207 {
00208     DdNode *res;
00209 
00210     do {
00211         dd->reordered = 0;
00212         res = cuddZddIntersect(dd, P, Q);
00213     } while (dd->reordered == 1);
00214     return(res);
00215 
00216 } /* end of Cudd_zddIntersect */

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

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

Synopsis [Computes an ISOP in ZDD form from BDDs.]

Description [Computes an irredundant sum of products (ISOP) in ZDD form from BDDs. The two BDDs L and U represent the lower bound and the upper bound, respectively, of the function. The ISOP uses two ZDD variables for each BDD variable: One for the positive literal, and one for the negative literal. These two variables should be adjacent in the ZDD order. The two ZDD variables corresponding to BDD variable i should have indices 2i and 2i+1. The result of this procedure depends on the variable order. If successful, Cudd_zddIsop returns the BDD for the function chosen from the interval. The ZDD representing the irredundant cover is returned as a side effect in zdd_I. In case of failure, NULL is returned.]

SideEffects [zdd_I holds the pointer to the ZDD for the ISOP on successful return.]

SeeAlso [Cudd_bddIsop Cudd_zddVarsFromBddVars]

Definition at line 132 of file cuddZddIsop.c.

00137 {
00138     DdNode      *res;
00139     int         autoDynZ;
00140 
00141     autoDynZ = dd->autoDynZ;
00142     dd->autoDynZ = 0;
00143 
00144     do {
00145         dd->reordered = 0;
00146         res = cuddZddIsop(dd, L, U, zdd_I);
00147     } while (dd->reordered == 1);
00148     dd->autoDynZ = autoDynZ;
00149     return(res);
00150 
00151 } /* end of Cudd_zddIsop */

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

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

Synopsis [Computes the ITE of three ZDDs.]

Description [Computes the ITE of three ZDDs. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 144 of file cuddZddSetop.c.

00149 {
00150     DdNode *res;
00151 
00152     do {
00153         dd->reordered = 0;
00154         res = cuddZddIte(dd, f, g, h);
00155     } while (dd->reordered == 1);
00156     return(res);
00157 
00158 } /* end of Cudd_zddIte */

DdNode* Cudd_zddIthVar ( DdManager dd,
int  i 
)

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

Synopsis [Returns the ZDD variable with index i.]

Description [Retrieves the ZDD variable with index i if it already exists, or creates a new ZDD variable. Returns a pointer to the variable if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddIthVar Cudd_addIthVar]

Definition at line 444 of file cuddAPI.c.

00447 {
00448     DdNode *res;
00449     DdNode *zvar;
00450     DdNode *lower;
00451     int j;
00452 
00453     if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL);
00454 
00455     /* The i-th variable function has the following structure:
00456     ** at the level corresponding to index i there is a node whose "then"
00457     ** child points to the universe, and whose "else" child points to zero.
00458     ** Above that level there are nodes with identical children.
00459     */
00460 
00461     /* First we build the node at the level of index i. */
00462     lower = (i < dd->sizeZ - 1) ? dd->univ[dd->permZ[i]+1] : DD_ONE(dd);
00463     do {
00464         dd->reordered = 0;
00465         zvar = cuddUniqueInterZdd(dd, i, lower, DD_ZERO(dd));
00466     } while (dd->reordered == 1);
00467 
00468     if (zvar == NULL)
00469         return(NULL);
00470     cuddRef(zvar);
00471 
00472     /* Now we add the "filler" nodes above the level of index i. */
00473     for (j = dd->permZ[i] - 1; j >= 0; j--) {
00474         do {
00475             dd->reordered = 0;
00476             res = cuddUniqueInterZdd(dd, dd->invpermZ[j], zvar, zvar);
00477         } while (dd->reordered == 1);
00478         if (res == NULL) {
00479             Cudd_RecursiveDerefZdd(dd,zvar);
00480             return(NULL);
00481         }
00482         cuddRef(res);
00483         Cudd_RecursiveDerefZdd(dd,zvar);
00484         zvar = res;
00485     }
00486     cuddDeref(zvar);
00487     return(zvar);
00488 
00489 } /* end of Cudd_zddIthVar */

int Cudd_zddNextPath ( DdGen gen,
int **  path 
)

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

Synopsis [Generates the next path of a ZDD.]

Description [Generates the next path of a ZDD onset, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]

SideEffects [The path is returned as a side effect. The generator is modified.]

SeeAlso [Cudd_zddForeachPath Cudd_zddFirstPath Cudd_GenFree Cudd_IsGenEmpty]

Definition at line 383 of file cuddZddUtil.c.

00386 {
00387     DdNode *top, *next, *prev;
00388     DdManager *zdd = gen->manager;
00389 
00390     /* Backtrack from previously reached terminal node. */
00391     while (1) {
00392         if (gen->stack.sp == 1) {
00393             /* The current node has no predecessor. */
00394             gen->status = CUDD_GEN_EMPTY;
00395             gen->stack.sp--;
00396             goto done;
00397         }
00398         top = gen->stack.stack[gen->stack.sp-1];
00399         prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]);
00400         next = cuddT(prev);
00401         if (next != top) { /* follow the then branch next */
00402             gen->gen.cubes.cube[prev->index] = 1;
00403             gen->stack.stack[gen->stack.sp-1] = next;
00404             break;
00405         }
00406         /* Pop the stack and try again. */
00407         gen->gen.cubes.cube[prev->index] = 2;
00408         gen->stack.sp--;
00409     }
00410 
00411     while (1) {
00412         top = gen->stack.stack[gen->stack.sp-1];
00413         if (!cuddIsConstant(Cudd_Regular(top))) {
00414             /* Take the else branch first. */
00415             gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0;
00416             next = cuddE(Cudd_Regular(top));
00417             gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++;
00418         } else if (Cudd_Regular(top) == DD_ZERO(zdd)) {
00419             /* Backtrack. */
00420             while (1) {
00421                 if (gen->stack.sp == 1) {
00422                     /* The current node has no predecessor. */
00423                     gen->status = CUDD_GEN_EMPTY;
00424                     gen->stack.sp--;
00425                     goto done;
00426                 }
00427                 prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]);
00428                 next = cuddT(prev);
00429                 if (next != top) { /* follow the then branch next */
00430                     gen->gen.cubes.cube[prev->index] = 1;
00431                     gen->stack.stack[gen->stack.sp-1] = next;
00432                     break;
00433                 }
00434                 /* Pop the stack and try again. */
00435                 gen->gen.cubes.cube[prev->index] = 2;
00436                 gen->stack.sp--;
00437                 top = gen->stack.stack[gen->stack.sp-1];
00438             }
00439         } else {
00440             gen->status = CUDD_GEN_NONEMPTY;
00441             gen->gen.cubes.value = cuddV(Cudd_Regular(top));
00442             goto done;
00443         }
00444     }
00445 
00446 done:
00447     if (gen->status == CUDD_GEN_EMPTY) return(0);
00448     *path = gen->gen.cubes.cube;
00449     return(1);
00450 
00451 } /* end of Cudd_zddNextPath */

DdNode* Cudd_zddPortFromBdd ( DdManager dd,
DdNode B 
)

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

Synopsis [Converts a BDD into a ZDD.]

Description [Converts a BDD into a ZDD. This function assumes that there is a one-to-one correspondence between the BDD variables and the ZDD variables, and that the variable order is the same for both types of variables. These conditions are established if the ZDD variables are created by one call to Cudd_zddVarsFromBddVars with multiplicity = 1. Returns a pointer to the resulting ZDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_zddVarsFromBddVars]

Definition at line 127 of file cuddZddPort.c.

00130 {
00131     DdNode *res;
00132 
00133     do {
00134         dd->reordered = 0;
00135         res = zddPortFromBddStep(dd,B,0);
00136     } while (dd->reordered == 1);
00137 
00138     return(res);
00139 
00140 } /* end of Cudd_zddPortFromBdd */

DdNode* Cudd_zddPortToBdd ( DdManager dd,
DdNode f 
)

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

Synopsis [Converts a ZDD into a BDD.]

Description [Converts a ZDD into a BDD. Returns a pointer to the resulting ZDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_zddPortFromBdd]

Definition at line 156 of file cuddZddPort.c.

00159 {
00160     DdNode *res;
00161 
00162     do {
00163         dd->reordered = 0;
00164         res = zddPortToBddStep(dd,f,0);
00165     } while (dd->reordered == 1);
00166 
00167     return(res);
00168 
00169 } /* end of Cudd_zddPortToBdd */

int Cudd_zddPrintCover ( DdManager zdd,
DdNode node 
)

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

Synopsis [Prints a sum of products from a ZDD representing a cover.]

Description [Prints a sum of products from a ZDD representing a cover. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_zddPrintMinterm]

Definition at line 165 of file cuddZddUtil.c.

00168 {
00169     int         i, size;
00170     int         *list;
00171 
00172     size = (int)zdd->sizeZ;
00173     if (size % 2 != 0) return(0); /* number of variables should be even */
00174     list = ALLOC(int, size);
00175     if (list == NULL) {
00176         zdd->errorCode = CUDD_MEMORY_OUT;
00177         return(0);
00178     }
00179     for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */
00180     zddPrintCoverAux(zdd, node, 0, list);
00181     FREE(list);
00182     return(1);
00183 
00184 } /* end of Cudd_zddPrintCover */

int Cudd_zddPrintDebug ( DdManager zdd,
DdNode f,
int  n,
int  pr 
)

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

Synopsis [Prints to the standard output a ZDD and its statistics.]

Description [Prints to the standard output a DD and its statistics. The statistics include the number of nodes and the number of minterms. (The number of minterms is also the number of combinations in the set.) The statistics are printed if pr > 0. Specifically:

  • pr = 0 : prints nothing
  • pr = 1 : prints counts of nodes and minterms
  • pr = 2 : prints counts + disjoint sum of products
  • pr = 3 : prints counts + list of nodes
  • pr > 3 : prints counts + disjoint sum of products + list of nodes

Returns 1 if successful; 0 otherwise. ]

SideEffects [None]

SeeAlso []

Definition at line 211 of file cuddZddUtil.c.

00216 {
00217     DdNode      *empty = DD_ZERO(zdd);
00218     int         nodes;
00219     double      minterms;
00220     int         retval = 1;
00221 
00222     if (f == empty && pr > 0) {
00223         (void) fprintf(zdd->out,": is the empty ZDD\n");
00224         (void) fflush(zdd->out);
00225         return(1);
00226     }
00227 
00228     if (pr > 0) {
00229         nodes = Cudd_zddDagSize(f);
00230         if (nodes == CUDD_OUT_OF_MEM) retval = 0;
00231         minterms = Cudd_zddCountMinterm(zdd, f, n);
00232         if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0;
00233         (void) fprintf(zdd->out,": %d nodes %g minterms\n",
00234                        nodes, minterms);
00235         if (pr > 2)
00236             if (!cuddZddP(zdd, f)) retval = 0;
00237         if (pr == 2 || pr > 3) {
00238             if (!Cudd_zddPrintMinterm(zdd, f)) retval = 0;
00239             (void) fprintf(zdd->out,"\n");
00240         }
00241         (void) fflush(zdd->out);
00242     }
00243     return(retval);
00244 
00245 } /* end of Cudd_zddPrintDebug */

int Cudd_zddPrintMinterm ( DdManager zdd,
DdNode node 
)

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

Synopsis [Prints a disjoint sum of product form for a ZDD.]

Description [Prints a disjoint sum of product form for a ZDD. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_zddPrintDebug Cudd_zddPrintCover]

Definition at line 131 of file cuddZddUtil.c.

00134 {
00135     int         i, size;
00136     int         *list;
00137 
00138     size = (int)zdd->sizeZ;
00139     list = ALLOC(int, size);
00140     if (list == NULL) {
00141         zdd->errorCode = CUDD_MEMORY_OUT;
00142         return(0);
00143     }
00144     for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */
00145     zdd_print_minterm_aux(zdd, node, 0, list);
00146     FREE(list);
00147     return(1);
00148 
00149 } /* end of Cudd_zddPrintMinterm */

void Cudd_zddPrintSubtable ( DdManager table  ) 

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

Synopsis [Prints the ZDD table.]

Description [Prints the ZDD table for debugging purposes.]

SideEffects [None]

SeeAlso []

Definition at line 180 of file cuddZddMisc.c.

00182 {
00183     int         i, j;
00184     DdNode      *z1, *z1_next, *base;
00185     DdSubtable  *ZSubTable;
00186 
00187     base = table->one;
00188     for (i = table->sizeZ - 1; i >= 0; i--) {
00189         ZSubTable = &(table->subtableZ[i]);
00190         printf("subtable[%d]:\n", i);
00191         for (j = ZSubTable->slots - 1; j >= 0; j--) {
00192             z1 = ZSubTable->nodelist[j];
00193             while (z1 != NIL(DdNode)) {
00194                 (void) fprintf(table->out,
00195 #if SIZEOF_VOID_P == 8
00196                     "ID = 0x%lx\tindex = %u\tr = %u\t",
00197                     (ptruint) z1 / (ptruint) sizeof(DdNode),
00198                     z1->index, z1->ref);
00199 #else
00200                     "ID = 0x%x\tindex = %hu\tr = %hu\t",
00201                     (ptruint) z1 / (ptruint) sizeof(DdNode),
00202                     z1->index, z1->ref);
00203 #endif
00204                 z1_next = cuddT(z1);
00205                 if (Cudd_IsConstant(z1_next)) {
00206                     (void) fprintf(table->out, "T = %d\t\t",
00207                         (z1_next == base));
00208                 }
00209                 else {
00210 #if SIZEOF_VOID_P == 8
00211                     (void) fprintf(table->out, "T = 0x%lx\t",
00212                         (ptruint) z1_next / (ptruint) sizeof(DdNode));
00213 #else
00214                     (void) fprintf(table->out, "T = 0x%x\t",
00215                         (ptruint) z1_next / (ptruint) sizeof(DdNode));
00216 #endif
00217                 }
00218                 z1_next = cuddE(z1);
00219                 if (Cudd_IsConstant(z1_next)) {
00220                     (void) fprintf(table->out, "E = %d\n",
00221                         (z1_next == base));
00222                 }
00223                 else {
00224 #if SIZEOF_VOID_P == 8
00225                     (void) fprintf(table->out, "E = 0x%lx\n",
00226                         (ptruint) z1_next / (ptruint) sizeof(DdNode));
00227 #else
00228                     (void) fprintf(table->out, "E = 0x%x\n",
00229                         (ptruint) z1_next / (ptruint) sizeof(DdNode));
00230 #endif
00231                 }
00232 
00233                 z1_next = z1->next;
00234                 z1 = z1_next;
00235             }
00236         }
00237     }
00238     putchar('\n');
00239 
00240 } /* Cudd_zddPrintSubtable */

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

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

Synopsis [Computes the product of two covers represented by ZDDs.]

Description [Computes the product of two covers represented by ZDDs. The result is also a ZDD. Returns a pointer to the result if successful; NULL otherwise. The covers on which Cudd_zddProduct operates use two ZDD variables for each function variable (one ZDD variable for each literal of the variable). Those two ZDD variables should be adjacent in the order.]

SideEffects [None]

SeeAlso [Cudd_zddUnateProduct]

Definition at line 141 of file cuddZddFuncs.c.

00145 {
00146     DdNode      *res;
00147 
00148     do {
00149         dd->reordered = 0;
00150         res = cuddZddProduct(dd, f, g);
00151     } while (dd->reordered == 1);
00152     return(res);
00153 
00154 } /* end of Cudd_zddProduct */

long Cudd_zddReadNodeCount ( DdManager dd  ) 

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

Synopsis [Reports the number of nodes in ZDDs.]

Description [Reports the number of nodes in ZDDs. This number always includes the two constants 1 and 0.]

SideEffects [None]

SeeAlso [Cudd_ReadPeakNodeCount Cudd_ReadNodeCount]

Definition at line 3218 of file cuddAPI.c.

03220 {
03221     return((long)(dd->keysZ - dd->deadZ + 2));
03222 
03223 } /* end of Cudd_zddReadNodeCount */

void Cudd_zddRealignDisable ( DdManager unique  ) 

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

Synopsis [Disables realignment of ZDD order to BDD order.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddRealignEnable Cudd_zddRealignmentEnabled Cudd_bddRealignEnable Cudd_bddRealignmentEnabled]

Definition at line 885 of file cuddAPI.c.

00887 {
00888     unique->realign = 0;
00889     return;
00890 
00891 } /* end of Cudd_zddRealignDisable */

void Cudd_zddRealignEnable ( DdManager unique  ) 

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

Synopsis [Enables realignment of ZDD order to BDD order.]

Description [Enables realignment of the ZDD variable order to the BDD variable order after the BDDs and ADDs have been reordered. The number of ZDD variables must be a multiple of the number of BDD variables for realignment to make sense. If this condition is not met, Cudd_ReduceHeap will return 0. Let M be the ratio of the two numbers. For the purpose of realignment, the ZDD variables from M*i to (M+1)*i-1 are reagarded as corresponding to BDD variable i. Realignment is initially disabled.]

SideEffects [None]

SeeAlso [Cudd_ReduceHeap Cudd_zddRealignDisable Cudd_zddRealignmentEnabled Cudd_bddRealignDisable Cudd_bddRealignmentEnabled]

Definition at line 863 of file cuddAPI.c.

00865 {
00866     unique->realign = 1;
00867     return;
00868 
00869 } /* end of Cudd_zddRealignEnable */

int Cudd_zddRealignmentEnabled ( DdManager unique  ) 

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

Synopsis [Tells whether the realignment of ZDD order to BDD order is enabled.]

Description [Returns 1 if the realignment of ZDD order to BDD order is enabled; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_zddRealignEnable Cudd_zddRealignDisable Cudd_bddRealignEnable Cudd_bddRealignDisable]

Definition at line 833 of file cuddAPI.c.

00835 {
00836     return(unique->realign);
00837 
00838 } /* end of Cudd_zddRealignmentEnabled */

int Cudd_zddReduceHeap ( DdManager table,
Cudd_ReorderingType  heuristic,
int  minsize 
)

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

Synopsis [Main dynamic reordering routine for ZDDs.]

Description [Main dynamic reordering routine for ZDDs. Calls one of the possible reordering procedures:

  • Swapping
  • Sifting
  • Symmetric Sifting

For sifting and symmetric sifting it is possible to request reordering to convergence.

The core of all methods is the reordering procedure cuddZddSwapInPlace() which swaps two adjacent variables. Returns 1 in case of success; 0 otherwise. In the case of symmetric sifting (with and without convergence) returns 1 plus the number of symmetric variables, in case of success.]

SideEffects [Changes the variable order for all ZDDs and clears the cache.]

Definition at line 167 of file cuddZddReord.c.

00171 {
00172     DdHook       *hook;
00173     int          result;
00174     unsigned int nextDyn;
00175 #ifdef DD_STATS
00176     unsigned int initialSize;
00177     unsigned int finalSize;
00178 #endif
00179     long         localTime;
00180 
00181     /* Don't reorder if there are too many dead nodes. */
00182     if (table->keysZ - table->deadZ < (unsigned) minsize)
00183         return(1);
00184 
00185     if (heuristic == CUDD_REORDER_SAME) {
00186         heuristic = table->autoMethodZ;
00187     }
00188     if (heuristic == CUDD_REORDER_NONE) {
00189         return(1);
00190     }
00191 
00192     /* This call to Cudd_zddReduceHeap does initiate reordering. Therefore
00193     ** we count it.
00194     */
00195     table->reorderings++;
00196     empty = table->zero;
00197 
00198     localTime = util_cpu_time();
00199 
00200     /* Run the hook functions. */
00201     hook = table->preReorderingHook;
00202     while (hook != NULL) {
00203         int res = (hook->f)(table, "ZDD", (void *)heuristic);
00204         if (res == 0) return(0);
00205         hook = hook->next;
00206     }
00207 
00208     /* Clear the cache and collect garbage. */
00209     zddReorderPreprocess(table);
00210     zddTotalNumberSwapping = 0;
00211 
00212 #ifdef DD_STATS
00213     initialSize = table->keysZ;
00214 
00215     switch(heuristic) {
00216     case CUDD_REORDER_RANDOM:
00217     case CUDD_REORDER_RANDOM_PIVOT:
00218         (void) fprintf(table->out,"#:I_RANDOM  ");
00219         break;
00220     case CUDD_REORDER_SIFT:
00221     case CUDD_REORDER_SIFT_CONVERGE:
00222     case CUDD_REORDER_SYMM_SIFT:
00223     case CUDD_REORDER_SYMM_SIFT_CONV:
00224         (void) fprintf(table->out,"#:I_SIFTING ");
00225         break;
00226     case CUDD_REORDER_LINEAR:
00227     case CUDD_REORDER_LINEAR_CONVERGE:
00228         (void) fprintf(table->out,"#:I_LINSIFT ");
00229         break;
00230     default:
00231         (void) fprintf(table->err,"Unsupported ZDD reordering method\n");
00232         return(0);
00233     }
00234     (void) fprintf(table->out,"%8d: initial size",initialSize); 
00235 #endif
00236 
00237     result = cuddZddTreeSifting(table,heuristic);
00238 
00239 #ifdef DD_STATS
00240     (void) fprintf(table->out,"\n");
00241     finalSize = table->keysZ;
00242     (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); 
00243     (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n",
00244                    ((double)(util_cpu_time() - localTime)/1000.0)); 
00245     (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n",
00246                    zddTotalNumberSwapping);
00247 #endif
00248 
00249     if (result == 0)
00250         return(0);
00251 
00252     if (!zddReorderPostprocess(table))
00253         return(0);
00254 
00255     if (table->realignZ) {
00256         if (!cuddBddAlignToZdd(table))
00257             return(0);
00258     }
00259 
00260     nextDyn = table->keysZ * DD_DYN_RATIO;
00261     if (table->reorderings < 20 || nextDyn > table->nextDyn)
00262         table->nextDyn = nextDyn;
00263     else
00264         table->nextDyn += 20;
00265 
00266     table->reordered = 1;
00267 
00268     /* Run hook functions. */
00269     hook = table->postReorderingHook;
00270     while (hook != NULL) {
00271         int res = (hook->f)(table, "ZDD", (void *)localTime);
00272         if (res == 0) return(0);
00273         hook = hook->next;
00274     }
00275     /* Update cumulative reordering time. */
00276     table->reordTime += util_cpu_time() - localTime;
00277 
00278     return(result);
00279 
00280 } /* end of Cudd_zddReduceHeap */

int Cudd_zddShuffleHeap ( DdManager table,
int *  permutation 
)

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

Synopsis [Reorders ZDD variables according to given permutation.]

Description [Reorders ZDD variables according to given permutation. The i-th entry of the permutation array contains the index of the variable that should be brought to the i-th level. The size of the array should be equal or greater to the number of variables currently in use. Returns 1 in case of success; 0 otherwise.]

SideEffects [Changes the ZDD variable order for all diagrams and clears the cache.]

SeeAlso [Cudd_zddReduceHeap]

Definition at line 300 of file cuddZddReord.c.

00303 {
00304 
00305     int result;
00306 
00307     empty = table->zero;
00308     zddReorderPreprocess(table);
00309 
00310     result = zddShuffle(table,permutation);
00311 
00312     if (!zddReorderPostprocess(table)) return(0);
00313 
00314     return(result);
00315 
00316 } /* end of Cudd_zddShuffleHeap */

DdNode* Cudd_zddSubset0 ( 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.]

SideEffects [None]

SeeAlso [Cudd_zddSubset1]

Definition at line 358 of file cuddZddSetop.c.

00362 {
00363     DdNode      *r;
00364 
00365     do {
00366         dd->reordered = 0;
00367         r = cuddZddSubset0(dd, P, var);
00368     } while (dd->reordered == 1);
00369 
00370     return(r);
00371 
00372 } /* end of Cudd_zddSubset0 */

DdNode* Cudd_zddSubset1 ( 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.]

SideEffects [None]

SeeAlso [Cudd_zddSubset0]

Definition at line 326 of file cuddZddSetop.c.

00330 {
00331     DdNode      *r;
00332 
00333     do {
00334         dd->reordered = 0;
00335         r = cuddZddSubset1(dd, P, var);
00336     } while (dd->reordered == 1);
00337 
00338     return(r);
00339 
00340 } /* end of Cudd_zddSubset1 */

void Cudd_zddSymmProfile ( DdManager table,
int  lower,
int  upper 
)

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

Synopsis [Prints statistics on symmetric ZDD variables.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 141 of file cuddZddSymm.c.

00145 {
00146     int         i, x, gbot;
00147     int         TotalSymm = 0;
00148     int         TotalSymmGroups = 0;
00149 
00150     for (i = lower; i < upper; i++) {
00151         if (table->subtableZ[i].next != (unsigned) i) {
00152             x = i;
00153             (void) fprintf(table->out,"Group:");
00154             do {
00155                 (void) fprintf(table->out,"  %d", table->invpermZ[x]);
00156                 TotalSymm++;
00157                 gbot = x;
00158                 x = table->subtableZ[x].next;
00159             } while (x != i);
00160             TotalSymmGroups++;
00161 #ifdef DD_DEBUG
00162             assert(table->subtableZ[gbot].next == (unsigned) i);
00163 #endif
00164             i = gbot;
00165             (void) fprintf(table->out,"\n");
00166         }
00167     }
00168     (void) fprintf(table->out,"Total Symmetric = %d\n", TotalSymm);
00169     (void) fprintf(table->out,"Total Groups = %d\n", TotalSymmGroups);
00170 
00171 } /* end of Cudd_zddSymmProfile */

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

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

Synopsis [Computes the product of two unate covers.]

Description [Computes the product of two unate covers represented as ZDDs. Unate covers use one ZDD variable for each BDD variable. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_zddProduct]

Definition at line 172 of file cuddZddFuncs.c.

00176 {
00177     DdNode      *res;
00178 
00179     do {
00180         dd->reordered = 0;
00181         res = cuddZddUnateProduct(dd, f, g);
00182     } while (dd->reordered == 1);
00183     return(res);
00184 
00185 } /* end of Cudd_zddUnateProduct */

DdNode* Cudd_zddUnion ( DdManager dd,
DdNode P,
DdNode Q 
)

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

Synopsis [Computes the union of two ZDDs.]

Description [Computes the union of two ZDDs. Returns a pointer to the result if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 174 of file cuddZddSetop.c.

00178 {
00179     DdNode *res;
00180 
00181     do {
00182         dd->reordered = 0;
00183         res = cuddZddUnion(dd, P, Q);
00184     } while (dd->reordered == 1);
00185     return(res);
00186 
00187 } /* end of Cudd_zddUnion */

int Cudd_zddVarsFromBddVars ( DdManager dd,
int  multiplicity 
)

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

Synopsis [Creates one or more ZDD variables for each BDD variable.]

Description [Creates one or more ZDD variables for each BDD variable. If some ZDD variables already exist, only the missing variables are created. Parameter multiplicity allows the caller to control how many variables are created for each BDD variable in existence. For instance, if ZDDs are used to represent covers, two ZDD variables are required for each BDD variable. The order of the BDD variables is transferred to the ZDD variables. If a variable group tree exists for the BDD variables, a corresponding ZDD variable group tree is created by expanding the BDD variable tree. In any case, the ZDD variables derived from the same BDD variable are merged in a ZDD variable group. If a ZDD variable group tree exists, it is freed. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddNewVar Cudd_bddIthVar Cudd_bddNewVarAtLevel]

Definition at line 515 of file cuddAPI.c.

00518 {
00519     int res;
00520     int i, j;
00521     int allnew;
00522     int *permutation;
00523 
00524     if (multiplicity < 1) return(0);
00525     allnew = dd->sizeZ == 0;
00526     if (dd->size * multiplicity > dd->sizeZ) {
00527         res = cuddResizeTableZdd(dd,dd->size * multiplicity - 1);
00528         if (res == 0) return(0);
00529     }
00530     /* Impose the order of the BDD variables to the ZDD variables. */
00531     if (allnew) {
00532         for (i = 0; i < dd->size; i++) {
00533             for (j = 0; j < multiplicity; j++) {
00534                 dd->permZ[i * multiplicity + j] =
00535                     dd->perm[i] * multiplicity + j;
00536                 dd->invpermZ[dd->permZ[i * multiplicity + j]] =
00537                     i * multiplicity + j;
00538             }
00539         }
00540         for (i = 0; i < dd->sizeZ; i++) {
00541             dd->univ[i]->index = dd->invpermZ[i];
00542         }
00543     } else {
00544         permutation = ALLOC(int,dd->sizeZ);
00545         if (permutation == NULL) {
00546             dd->errorCode = CUDD_MEMORY_OUT;
00547             return(0);
00548         }
00549         for (i = 0; i < dd->size; i++) {
00550             for (j = 0; j < multiplicity; j++) {
00551                 permutation[i * multiplicity + j] =
00552                     dd->invperm[i] * multiplicity + j;
00553             }
00554         }
00555         for (i = dd->size * multiplicity; i < dd->sizeZ; i++) {
00556             permutation[i] = i;
00557         }
00558         res = Cudd_zddShuffleHeap(dd, permutation);
00559         FREE(permutation);
00560         if (res == 0) return(0);
00561     }
00562     /* Copy and expand the variable group tree if it exists. */
00563     if (dd->treeZ != NULL) {
00564         Cudd_FreeZddTree(dd);
00565     }
00566     if (dd->tree != NULL) {
00567         dd->treeZ = Mtr_CopyTree(dd->tree, multiplicity);
00568         if (dd->treeZ == NULL) return(0);
00569     } else if (multiplicity > 1) {
00570         dd->treeZ = Mtr_InitGroupTree(0, dd->sizeZ);
00571         if (dd->treeZ == NULL) return(0);
00572         dd->treeZ->index = dd->invpermZ[0];
00573     }
00574     /* Create groups for the ZDD variables derived from the same BDD variable.
00575     */
00576     if (multiplicity > 1) {
00577         char *vmask, *lmask;
00578 
00579         vmask = ALLOC(char, dd->size);
00580         if (vmask == NULL) {
00581             dd->errorCode = CUDD_MEMORY_OUT;
00582             return(0);
00583         }
00584         lmask =  ALLOC(char, dd->size);
00585         if (lmask == NULL) {
00586             dd->errorCode = CUDD_MEMORY_OUT;
00587             return(0);
00588         }
00589         for (i = 0; i < dd->size; i++) {
00590             vmask[i] = lmask[i] = 0;
00591         }
00592         res = addMultiplicityGroups(dd,dd->treeZ,multiplicity,vmask,lmask);
00593         FREE(vmask);
00594         FREE(lmask);
00595         if (res == 0) return(0);
00596     }
00597     return(1);
00598 
00599 } /* end of Cudd_zddVarsFromBddVars */

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

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

Synopsis [Applies weak division to two covers.]

Description [Applies weak division to two ZDDs representing two covers. Returns a pointer to the ZDD representing the result if successful; NULL otherwise. The result of weak division depends on the variable order. The covers on which Cudd_zddWeakDiv operates use two ZDD variables for each function variable (one ZDD variable for each literal of the variable). Those two ZDD variables should be adjacent in the order.]

SideEffects [None]

SeeAlso [Cudd_zddDivide]

Definition at line 206 of file cuddZddFuncs.c.

00210 {
00211     DdNode      *res;
00212 
00213     do {
00214         dd->reordered = 0;
00215         res = cuddZddWeakDiv(dd, f, g);
00216     } while (dd->reordered == 1);
00217     return(res);
00218 
00219 } /* end of Cudd_zddWeakDiv */

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

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

Synopsis [Modified version of Cudd_zddWeakDiv.]

Description [Modified version of Cudd_zddWeakDiv. This function may disappear in future releases.]

SideEffects [None]

SeeAlso [Cudd_zddWeakDiv]

Definition at line 266 of file cuddZddFuncs.c.

00270 {
00271     DdNode      *res;
00272 
00273     do {
00274         dd->reordered = 0;
00275         res = cuddZddWeakDivF(dd, f, g);
00276     } while (dd->reordered == 1);
00277     return(res);
00278 
00279 } /* end of Cudd_zddWeakDivF */


Generated on Tue Jan 12 13:57:17 2010 for glu-2.2 by  doxygen 1.6.1