diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2011-02-13 13:42:25 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2011-02-13 13:42:25 -0800 |
commit | e7b544f11151f09a4a3fbe39b4a176795a82f677 (patch) | |
tree | a6cbbeb138c9bfe5b2554a5838124ffc3a6c0a5b /src | |
parent | d99de60e6c88e5f6157b1d5c9b25cfd5d08a1c9a (diff) | |
download | abc-e7b544f11151f09a4a3fbe39b4a176795a82f677.tar.gz abc-e7b544f11151f09a4a3fbe39b4a176795a82f677.tar.bz2 abc-e7b544f11151f09a4a3fbe39b4a176795a82f677.zip |
Upgrade to the latest CUDD 2.4.2.
Diffstat (limited to 'src')
66 files changed, 26981 insertions, 22151 deletions
diff --git a/src/bdd/cudd/Makefile b/src/bdd/cudd/Makefile new file mode 100644 index 00000000..d7695474 --- /dev/null +++ b/src/bdd/cudd/Makefile @@ -0,0 +1,124 @@ +# $Id$ +# +# Cudd - DD package +#--------------------------- +.SUFFIXES: .o .c .u + +CC = gcc +RANLIB = ranlib +PURE = +# Define EXE as .exe for MS-DOS and derivatives. +EXE = +#EXE = .exe + +MFLAG = +ICFLAGS = -g +XCFLAGS = -DDD_STATS +CFLAGS = $(ICFLAGS) $(MFLAG) $(XCFLAGS) +#DDDEBUG = -DDD_DEBUG -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_UNIQUE_PROFILE +DDDEBUG = + +LINTFLAGS = -u -n -DDD_STATS -DDD_CACHE_PROFILE -DDD_VERBOSE -DDD_DEBUG -DDD_UNIQUE_PROFILE + +# this is to create the lint library +LINTSWITCH = -o + +WHERE = .. + +INCLUDE = $(WHERE)/include + +LIBS = ./libcudd.a $(WHERE)/mtr/libmtr.a \ + $(WHERE)/st/libst.a $(WHERE)/util/libutil.a $(WHERE)/epd/libepd.a + +MNEMLIB = + +BLIBS = -kL. -klcudd -kL$(WHERE)/mtr -klmtr \ + -kL$(WHERE)/st -klst -kL$(WHERE)/util -klutil -kL$(WHERE)/epd -klepd + +LINTLIBS = ./llib-lcudd.ln $(WHERE)/mtr/llib-lmtr.ln \ + $(WHERE)/st/llib-lst.ln $(WHERE)/util/llib-lutil.ln \ + $(WHERE)/epd/llib-lepd.ln + +LDFLAGS = + +# files for the package +P = cudd +PSRC = cuddAPI.c cuddAddAbs.c cuddAddApply.c cuddAddFind.c cuddAddIte.c \ + cuddAddInv.c cuddAddNeg.c cuddAddWalsh.c cuddAndAbs.c \ + cuddAnneal.c cuddApa.c cuddApprox.c cuddBddAbs.c cuddBddCorr.c \ + cuddBddIte.c cuddBridge.c cuddCache.c cuddCheck.c cuddClip.c \ + cuddCof.c cuddCompose.c cuddDecomp.c cuddEssent.c \ + cuddExact.c cuddExport.c cuddGenCof.c cuddGenetic.c \ + cuddGroup.c cuddHarwell.c cuddInit.c cuddInteract.c \ + cuddLCache.c cuddLevelQ.c \ + cuddLinear.c cuddLiteral.c cuddMatMult.c cuddPriority.c \ + cuddRead.c cuddRef.c cuddReorder.c cuddSat.c cuddSign.c \ + cuddSolve.c cuddSplit.c cuddSubsetHB.c cuddSubsetSP.c cuddSymmetry.c \ + cuddTable.c cuddUtil.c cuddWindow.c cuddZddCount.c cuddZddFuncs.c \ + cuddZddGroup.c cuddZddIsop.c cuddZddLin.c cuddZddMisc.c \ + cuddZddPort.c cuddZddReord.c cuddZddSetop.c cuddZddSymm.c \ + cuddZddUtil.c +PHDR = cudd.h cuddInt.h +POBJ = $(PSRC:.c=.o) +PUBJ = $(PSRC:.c=.u) +TARGET = test$(P)$(EXE) +TARGETu = test$(P)-u + +# files for the test program +SRC = test$(P).c +OBJ = $(SRC:.c=.o) +UBJ = $(SRC:.c=.u) + +#------------------------------------------------------ + +lib$(P).a: $(POBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.o: $(PSRC) $(PHDR) + $(CC) -c $< -I$(INCLUDE) $(CFLAGS) $(DDDEBUG) + +optimize_dec: lib$(P).b + +lib$(P).b: $(PUBJ) + ar rv $@ $? + $(RANLIB) $@ + +.c.u: $(PSRC) $(PHDR) + cc -j $< -I$(INCLUDE) $(XCFLAGS) + +# if the header files change, recompile +$(POBJ): $(PHDR) +$(PUBJ): $(PHDR) +$(OBJ): $(PHDR) +$(UBJ): $(PHDR) + +$(TARGET): $(SRC) $(OBJ) $(HDR) $(LIBS) $(MNEMLIB) + $(PURE) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) $(MNEMLIB) -lm + +# optimize (DECstations and Alphas only: uses u-code) +$(TARGETu): $(SRC) $(UBJ) $(HDR) $(LIBS:.a=.b) + $(CC) -O3 -Olimit 1000 $(XCFLAGS) $(LDFLAGS) -o $@ $(UBJ) $(BLIBS) -lm + +lint: llib-l$(P).ln + +llib-l$(P).ln: $(PSRC) $(PHDR) + lint $(LINTFLAGS) $(LINTSWITCH)$(P) -I$(INCLUDE) $(PSRC) + +lintpgm: lint + lint $(LINTFLAGS) -I$(INCLUDE) $(SRC) $(LINTLIBS) + +tags: $(PSRC) $(PHDR) + ctags $(PSRC) $(PHDR) + +all: lib$(P).a lib$(P).b llib-l$(P).ln tags + +programs: $(TARGET) $(TARGETu) lintpgm + +clean: + rm -f *.o *.u mon.out gmon.out *.pixie *.Addrs *.Counts mnem.* \ + .pure core *.warnings + +distclean: clean + rm -f $(TARGET) $(TARGETu) lib*.a lib$(P).b llib-l$(P).ln \ + *.bak *~ tags .gdb_history *.qv *.qx diff --git a/src/bdd/cudd/cudd.h b/src/bdd/cudd/cudd.h index 658e4eaf..c72edbb0 100644 --- a/src/bdd/cudd/cudd.h +++ b/src/bdd/cudd/cudd.h @@ -7,23 +7,50 @@ Synopsis [The University of Colorado decision diagram package.] Description [External functions and data strucures of the CUDD package. - <ul> - <li> To turn on the gathering of statistics, define DD_STATS. - <li> To link with mis, define DD_MIS. - </ul> - Modified by Abelardo Pardo to interface it to VIS. + <ul> + <li> To turn on the gathering of statistics, define DD_STATS. + <li> To link with mis, define DD_MIS. + </ul> + Modified by Abelardo Pardo to interface it to VIS. ] SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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. - Revision [$Id: cudd.h,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $] + 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 $] ******************************************************************************/ @@ -45,7 +72,7 @@ ABC_NAMESPACE_HEADER_START /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define CUDD_VERSION "2.3.1" +#define CUDD_VERSION "2.4.2" #ifndef SIZEOF_VOID_P #define SIZEOF_VOID_P 4 @@ -64,40 +91,46 @@ ABC_NAMESPACE_HEADER_START #define FALSE 0 #endif -#define CUDD_VALUE_TYPE double -#define CUDD_OUT_OF_MEM -1 +#define CUDD_VALUE_TYPE double +#define CUDD_OUT_OF_MEM -1 /* The sizes of the subtables and the cache must be powers of two. */ -#define CUDD_UNIQUE_SLOTS 256 /* initial size of subtables */ -#define CUDD_CACHE_SLOTS 262144 /* default size of the cache */ +#define CUDD_UNIQUE_SLOTS 256 /* initial size of subtables */ +#define CUDD_CACHE_SLOTS 262144 /* default size of the cache */ /* Constants for residue functions. */ #define CUDD_RESIDUE_DEFAULT 0 -#define CUDD_RESIDUE_MSB 1 -#define CUDD_RESIDUE_TC 2 +#define CUDD_RESIDUE_MSB 1 +#define CUDD_RESIDUE_TC 2 /* CUDD_MAXINDEX is defined in such a way that on 32-bit and 64-bit ** machines one can cast an index to (int) without generating a negative ** number. */ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 -#define CUDD_MAXINDEX (((DdHalfWord) ~0) >> 1) +#define CUDD_MAXINDEX (((DdHalfWord) ~0) >> 1) #else -#define CUDD_MAXINDEX ((DdHalfWord) ~0) +#define CUDD_MAXINDEX ((DdHalfWord) ~0) #endif /* CUDD_CONST_INDEX is the index of constant nodes. Currently this ** is a synonim for CUDD_MAXINDEX. */ -#define CUDD_CONST_INDEX CUDD_MAXINDEX +#define CUDD_CONST_INDEX CUDD_MAXINDEX /* These constants define the digits used in the representation of -** arbitrary precision integers. The two configurations tested use 8 -** and 16 bits for each digit. The typedefs should be in agreement +** arbitrary precision integers. The configurations tested use 8, 16, +** and 32 bits for each digit. The typedefs should be in agreement ** with these definitions. */ -#define DD_APA_BITS 16 -#define DD_APA_BASE (1 << DD_APA_BITS) -#define DD_APA_MASK (DD_APA_BASE - 1) -#define DD_APA_HEXPRINT "%04x" +#if SIZEOF_LONG == 8 +#define DD_APA_BITS 32 +#define DD_APA_BASE (1L << DD_APA_BITS) +#define DD_APA_HEXPRINT "%08x" +#else +#define DD_APA_BITS 16 +#define DD_APA_BASE (1 << DD_APA_BITS) +#define DD_APA_HEXPRINT "%04x" +#endif +#define DD_APA_MASK (DD_APA_BASE - 1) /*---------------------------------------------------------------------------*/ /* Stucture declarations */ @@ -244,11 +277,11 @@ typedef struct DdChildren { /* The DdNode structure is the only one exported out of the package */ struct DdNode { DdHalfWord index; - DdHalfWord ref; /* reference count */ - DdNode *next; /* next pointer for unique table */ + DdHalfWord ref; /* reference count */ + DdNode *next; /* next pointer for unique table */ union { - CUDD_VALUE_TYPE value; /* for constant nodes */ - DdChildren kids; /* for internal nodes */ + CUDD_VALUE_TYPE value; /* for constant nodes */ + DdChildren kids; /* for internal nodes */ } type; }; @@ -262,10 +295,35 @@ typedef struct DdGen DdGen; /* These typedefs for arbitrary precision arithmetic should agree with ** the corresponding constant definitions above. */ -typedef unsigned short int DdApaDigit; +#if SIZEOF_LONG == 8 +typedef unsigned int DdApaDigit; typedef unsigned long int DdApaDoubleDigit; +#else +typedef unsigned short int DdApaDigit; +typedef unsigned int DdApaDoubleDigit; +#endif typedef DdApaDigit * DdApaNumber; +/* Return type for function computing two-literal clauses. */ +typedef struct DdTlcInfo DdTlcInfo; + +/* Type of hook function. */ +typedef int (*DD_HFP)(DdManager *, const char *, void *); +/* Type of priority function */ +typedef DdNode * (*DD_PRFP)(DdManager * , int, DdNode **, DdNode **, + DdNode **); +/* Type of apply operator. */ +typedef DdNode * (*DD_AOP)(DdManager *, DdNode **, DdNode **); +/* Type of monadic apply operator. */ +typedef DdNode * (*DD_MAOP)(DdManager *, DdNode *); +/* Types of cache tag functions. */ +typedef DdNode * (*DD_CTFP)(DdManager *, DdNode *, DdNode *); +typedef DdNode * (*DD_CTFP1)(DdManager *, DdNode *); +/* Type of memory-out function. */ +typedef void (*DD_OOMFP)(long); +/* Type of comparison function for qsort. */ +typedef int (*DD_QSFP)(const void *, const void *); + /*---------------------------------------------------------------------------*/ /* Variable declarations */ /*---------------------------------------------------------------------------*/ @@ -363,7 +421,7 @@ typedef DdApaDigit * DdApaNumber; SeeAlso [Cudd_Regular Cudd_Complement] ******************************************************************************/ -#define Cudd_IsComplement(node) ((int) ((long) (node) & 01)) +#define Cudd_IsComplement(node) ((int) ((long) (node) & 01)) /**Macro*********************************************************************** @@ -459,8 +517,40 @@ typedef DdApaDigit * DdApaNumber; ******************************************************************************/ #define Cudd_ForeachCube(manager, f, gen, cube, value)\ for((gen) = Cudd_FirstCube(manager, f, &cube, &value);\ - Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ - (void) Cudd_NextCube(gen, &cube, &value)) + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ + (void) Cudd_NextCube(gen, &cube, &value)) + + +/**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. + <ul> + <li> DdManager *manager; + <li> DdNode *l; + <li> DdNode *u; + <li> DdGen *gen; + <li> int *cube; + </ul> + 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.<p> + CAUTION: It is a mistake to change a diagram on which generation is ongoing.] + + SideEffects [none] + + SeeAlso [Cudd_ForeachCube Cudd_FirstPrime Cudd_NextPrime Cudd_GenFree + Cudd_IsGenEmpty] + +******************************************************************************/ +#define Cudd_ForeachPrime(manager, l, u, gen, cube)\ + for((gen) = Cudd_FirstPrime(manager, l, u, &cube);\ + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ + (void) Cudd_NextPrime(gen, &cube)) /**Macro*********************************************************************** @@ -493,8 +583,8 @@ typedef DdApaDigit * DdApaNumber; ******************************************************************************/ #define Cudd_ForeachNode(manager, f, gen, node)\ for((gen) = Cudd_FirstNode(manager, f, &node);\ - Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ - (void) Cudd_NextNode(gen, &node)) + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ + (void) Cudd_NextNode(gen, &node)) /**Macro*********************************************************************** @@ -527,26 +617,10 @@ typedef DdApaDigit * DdApaNumber; ******************************************************************************/ #define Cudd_zddForeachPath(manager, f, gen, path)\ for((gen) = Cudd_zddFirstPath(manager, f, &path);\ - Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ - (void) Cudd_zddNextPath(gen, &path)) - - -/* These are potential duplicates. */ -#ifndef EXTERN -# ifdef __cplusplus -# ifdef ABC_NAMESPACE -# define EXTERN extern -# else -# define EXTERN extern "C" -# endif -# else -# define EXTERN extern -# endif -#endif + Cudd_IsGenEmpty(gen) ? Cudd_GenFree(gen) : TRUE;\ + (void) Cudd_zddNextPath(gen, &path)) + -#ifndef ARGS -#define ARGS(protos) protos -#endif /**AutomaticStart*************************************************************/ @@ -554,410 +628,421 @@ typedef DdApaDigit * DdApaNumber; /* Function prototypes */ /*---------------------------------------------------------------------------*/ -EXTERN DdNode * Cudd_addNewVar ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_addNewVarAtLevel ARGS((DdManager *dd, int level)); -EXTERN DdNode * Cudd_bddNewVar ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_bddNewVarAtLevel ARGS((DdManager *dd, int level)); -EXTERN DdNode * Cudd_addIthVar ARGS((DdManager *dd, int i)); -EXTERN DdNode * Cudd_bddIthVar ARGS((DdManager *dd, int i)); -EXTERN DdNode * Cudd_zddIthVar ARGS((DdManager *dd, int i)); -EXTERN int Cudd_zddVarsFromBddVars ARGS((DdManager *dd, int multiplicity)); -EXTERN DdNode * Cudd_addConst ARGS((DdManager *dd, CUDD_VALUE_TYPE c)); -EXTERN int Cudd_IsNonConstant ARGS((DdNode *f)); -EXTERN void Cudd_AutodynEnable ARGS((DdManager *unique, Cudd_ReorderingType method)); -EXTERN void Cudd_AutodynDisable ARGS((DdManager *unique)); -EXTERN int Cudd_ReorderingStatus ARGS((DdManager *unique, Cudd_ReorderingType *method)); -EXTERN void Cudd_AutodynEnableZdd ARGS((DdManager *unique, Cudd_ReorderingType method)); -EXTERN void Cudd_AutodynDisableZdd ARGS((DdManager *unique)); -EXTERN int Cudd_ReorderingStatusZdd ARGS((DdManager *unique, Cudd_ReorderingType *method)); -EXTERN int Cudd_zddRealignmentEnabled ARGS((DdManager *unique)); -EXTERN void Cudd_zddRealignEnable ARGS((DdManager *unique)); -EXTERN void Cudd_zddRealignDisable ARGS((DdManager *unique)); -EXTERN int Cudd_bddRealignmentEnabled ARGS((DdManager *unique)); -EXTERN void Cudd_bddRealignEnable ARGS((DdManager *unique)); -EXTERN void Cudd_bddRealignDisable ARGS((DdManager *unique)); -EXTERN DdNode * Cudd_ReadOne ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_ReadZddOne ARGS((DdManager *dd, int i)); -EXTERN DdNode * Cudd_ReadZero ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_ReadLogicZero ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_ReadPlusInfinity ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_ReadMinusInfinity ARGS((DdManager *dd)); -EXTERN DdNode * Cudd_ReadBackground ARGS((DdManager *dd)); -EXTERN void Cudd_SetBackground ARGS((DdManager *dd, DdNode *bck)); -EXTERN unsigned int Cudd_ReadCacheSlots ARGS((DdManager *dd)); -EXTERN double Cudd_ReadCacheUsedSlots ARGS((DdManager * dd)); -EXTERN double Cudd_ReadCacheLookUps ARGS((DdManager *dd)); -EXTERN double Cudd_ReadCacheHits ARGS((DdManager *dd)); -EXTERN double Cudd_ReadRecursiveCalls ARGS ((DdManager * dd)); -EXTERN unsigned int Cudd_ReadMinHit ARGS((DdManager *dd)); -EXTERN void Cudd_SetMinHit ARGS((DdManager *dd, unsigned int hr)); -EXTERN unsigned int Cudd_ReadLooseUpTo ARGS((DdManager *dd)); -EXTERN void Cudd_SetLooseUpTo ARGS((DdManager *dd, unsigned int lut)); -EXTERN unsigned int Cudd_ReadMaxCache ARGS((DdManager *dd)); -EXTERN unsigned int Cudd_ReadMaxCacheHard ARGS((DdManager *dd)); -EXTERN void Cudd_SetMaxCacheHard ARGS((DdManager *dd, unsigned int mc)); -EXTERN int Cudd_ReadSize ARGS((DdManager *dd)); -EXTERN int Cudd_ReadZddSize ARGS((DdManager *dd)); -EXTERN unsigned int Cudd_ReadSlots ARGS((DdManager *dd)); -EXTERN double Cudd_ReadUsedSlots ARGS((DdManager * dd)); -EXTERN double Cudd_ExpectedUsedSlots ARGS((DdManager * dd)); -EXTERN unsigned int Cudd_ReadKeys ARGS((DdManager *dd)); -EXTERN unsigned int Cudd_ReadDead ARGS((DdManager *dd)); -EXTERN unsigned int Cudd_ReadMinDead ARGS((DdManager *dd)); -EXTERN int Cudd_ReadReorderings ARGS((DdManager *dd)); -EXTERN long Cudd_ReadReorderingTime ARGS((DdManager * dd)); -EXTERN int Cudd_ReadGarbageCollections ARGS((DdManager * dd)); -EXTERN long Cudd_ReadGarbageCollectionTime ARGS((DdManager * dd)); -EXTERN double Cudd_ReadNodesFreed ARGS((DdManager * dd)); -EXTERN double Cudd_ReadNodesDropped ARGS((DdManager * dd)); -EXTERN double Cudd_ReadUniqueLookUps ARGS((DdManager * dd)); -EXTERN double Cudd_ReadUniqueLinks ARGS((DdManager * dd)); -EXTERN int Cudd_ReadSiftMaxVar ARGS((DdManager *dd)); -EXTERN void Cudd_SetSiftMaxVar ARGS((DdManager *dd, int smv)); -EXTERN int Cudd_ReadSiftMaxSwap ARGS((DdManager *dd)); -EXTERN void Cudd_SetSiftMaxSwap ARGS((DdManager *dd, int sms)); -EXTERN double Cudd_ReadMaxGrowth ARGS((DdManager *dd)); -EXTERN void Cudd_SetMaxGrowth ARGS((DdManager *dd, double mg)); -EXTERN double Cudd_ReadMaxGrowthAlternate ARGS((DdManager * dd)); -EXTERN void Cudd_SetMaxGrowthAlternate ARGS((DdManager * dd, double mg)); -EXTERN int Cudd_ReadReorderingCycle ARGS((DdManager * dd)); -EXTERN void Cudd_SetReorderingCycle ARGS((DdManager * dd, int cycle)); -EXTERN MtrNode * Cudd_ReadTree ARGS((DdManager *dd)); -EXTERN void Cudd_SetTree ARGS((DdManager *dd, MtrNode *tree)); -EXTERN void Cudd_FreeTree ARGS((DdManager *dd)); -EXTERN MtrNode * Cudd_ReadZddTree ARGS((DdManager *dd)); -EXTERN void Cudd_SetZddTree ARGS((DdManager *dd, MtrNode *tree)); -EXTERN void Cudd_FreeZddTree ARGS((DdManager *dd)); -EXTERN unsigned int Cudd_NodeReadIndex ARGS((DdNode *node)); -EXTERN int Cudd_ReadPerm ARGS((DdManager *dd, int i)); -EXTERN int Cudd_ReadPermZdd ARGS((DdManager *dd, int i)); -EXTERN int Cudd_ReadInvPerm ARGS((DdManager *dd, int i)); -EXTERN int Cudd_ReadInvPermZdd ARGS((DdManager *dd, int i)); -EXTERN DdNode * Cudd_ReadVars ARGS((DdManager *dd, int i)); -EXTERN CUDD_VALUE_TYPE Cudd_ReadEpsilon ARGS((DdManager *dd)); -EXTERN void Cudd_SetEpsilon ARGS((DdManager *dd, CUDD_VALUE_TYPE ep)); -EXTERN Cudd_AggregationType Cudd_ReadGroupcheck ARGS((DdManager *dd)); -EXTERN void Cudd_SetGroupcheck ARGS((DdManager *dd, Cudd_AggregationType gc)); -EXTERN int Cudd_GarbageCollectionEnabled ARGS((DdManager *dd)); -EXTERN void Cudd_EnableGarbageCollection ARGS((DdManager *dd)); -EXTERN void Cudd_DisableGarbageCollection ARGS((DdManager *dd)); -EXTERN int Cudd_DeadAreCounted ARGS((DdManager *dd)); -EXTERN void Cudd_TurnOnCountDead ARGS((DdManager *dd)); -EXTERN void Cudd_TurnOffCountDead ARGS((DdManager *dd)); -EXTERN int Cudd_ReadRecomb ARGS((DdManager *dd)); -EXTERN void Cudd_SetRecomb ARGS((DdManager *dd, int recomb)); -EXTERN int Cudd_ReadSymmviolation ARGS((DdManager *dd)); -EXTERN void Cudd_SetSymmviolation ARGS((DdManager *dd, int symmviolation)); -EXTERN int Cudd_ReadArcviolation ARGS((DdManager *dd)); -EXTERN void Cudd_SetArcviolation ARGS((DdManager *dd, int arcviolation)); -EXTERN int Cudd_ReadPopulationSize ARGS((DdManager *dd)); -EXTERN void Cudd_SetPopulationSize ARGS((DdManager *dd, int populationSize)); -EXTERN int Cudd_ReadNumberXovers ARGS((DdManager *dd)); -EXTERN void Cudd_SetNumberXovers ARGS((DdManager *dd, int numberXovers)); -EXTERN long Cudd_ReadMemoryInUse ARGS((DdManager *dd)); -EXTERN int Cudd_PrintInfo ARGS((DdManager *dd, FILE *fp)); -EXTERN long Cudd_ReadPeakNodeCount ARGS((DdManager *dd)); -EXTERN int Cudd_ReadPeakLiveNodeCount ARGS((DdManager * dd)); -EXTERN long Cudd_ReadNodeCount ARGS((DdManager *dd)); -EXTERN long Cudd_zddReadNodeCount ARGS((DdManager *dd)); -EXTERN int Cudd_AddHook ARGS((DdManager *dd, int (*f)(DdManager *, char *, void *), Cudd_HookType where)); -EXTERN int Cudd_RemoveHook ARGS((DdManager *dd, int (*f)(DdManager *, char *, void *), Cudd_HookType where)); -EXTERN int Cudd_IsInHook ARGS((DdManager * dd, int (*f)(DdManager *, char *, void *), Cudd_HookType where)); -EXTERN int Cudd_StdPreReordHook ARGS((DdManager *dd, char *str, void *data)); -EXTERN int Cudd_StdPostReordHook ARGS((DdManager *dd, char *str, void *data)); -EXTERN int Cudd_EnableReorderingReporting ARGS((DdManager *dd)); -EXTERN int Cudd_DisableReorderingReporting ARGS((DdManager *dd)); -EXTERN int Cudd_ReorderingReporting ARGS((DdManager *dd)); -EXTERN Cudd_ErrorType Cudd_ReadErrorCode ARGS((DdManager *dd)); -EXTERN void Cudd_ClearErrorCode ARGS((DdManager *dd)); -EXTERN FILE * Cudd_ReadStdout ARGS((DdManager *dd)); -EXTERN void Cudd_SetStdout ARGS((DdManager *dd, FILE *fp)); -EXTERN FILE * Cudd_ReadStderr ARGS((DdManager *dd)); -EXTERN void Cudd_SetStderr ARGS((DdManager *dd, FILE *fp)); -EXTERN unsigned int Cudd_ReadNextReordering ARGS((DdManager *dd)); -EXTERN void Cudd_SetNextReordering ARGS((DdManager *dd, unsigned int next)); -EXTERN double Cudd_ReadSwapSteps ARGS((DdManager *dd)); -EXTERN unsigned int Cudd_ReadMaxLive ARGS((DdManager *dd)); -EXTERN void Cudd_SetMaxLive ARGS((DdManager *dd, unsigned int maxLive)); -EXTERN long Cudd_ReadMaxMemory ARGS((DdManager *dd)); -EXTERN void Cudd_SetMaxMemory ARGS((DdManager *dd, long maxMemory)); -EXTERN int Cudd_bddBindVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddUnbindVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddVarIsBound ARGS((DdManager *dd, int index)); -EXTERN DdNode * Cudd_addExistAbstract ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * Cudd_addUnivAbstract ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * Cudd_addOrAbstract ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * Cudd_addApply ARGS((DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_addPlus ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addTimes ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addThreshold ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addSetNZ ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addDivide ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addMinus ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addMinimum ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addMaximum ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addOneZeroMaximum ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addDiff ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addAgreement ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addOr ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addNand ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addNor ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addXor ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addXnor ARGS((DdManager *dd, DdNode **f, DdNode **g)); -EXTERN DdNode * Cudd_addMonadicApply ARGS((DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f)); -EXTERN DdNode * Cudd_addLog ARGS((DdManager * dd, DdNode * f)); -EXTERN DdNode * Cudd_addFindMax ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_addFindMin ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_addIthBit ARGS((DdManager *dd, DdNode *f, int bit)); -EXTERN DdNode * Cudd_addScalarInverse ARGS((DdManager *dd, DdNode *f, DdNode *epsilon)); -EXTERN DdNode * Cudd_addIte ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * Cudd_addIteConstant ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * Cudd_addEvalConst ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN int Cudd_addLeq ARGS((DdManager * dd, DdNode * f, DdNode * g)); -EXTERN DdNode * Cudd_addCmpl ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_addNegate ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_addRoundOff ARGS((DdManager *dd, DdNode *f, int N)); -EXTERN DdNode * Cudd_addWalsh ARGS((DdManager *dd, DdNode **x, DdNode **y, int n)); -EXTERN DdNode * Cudd_addResidue ARGS((DdManager *dd, int n, int m, int options, int top)); -EXTERN DdNode * Cudd_bddAndAbstract ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)); -EXTERN DdNode * Cudd_bddAndAbstractLimit ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, unsigned int limit)); -EXTERN int Cudd_ApaNumberOfDigits ARGS((int binaryDigits)); -EXTERN DdApaNumber Cudd_NewApaNumber ARGS((int digits)); -EXTERN void Cudd_ApaCopy ARGS((int digits, DdApaNumber source, DdApaNumber dest)); -EXTERN DdApaDigit Cudd_ApaAdd ARGS((int digits, DdApaNumber a, DdApaNumber b, DdApaNumber sum)); -EXTERN DdApaDigit Cudd_ApaSubtract ARGS((int digits, DdApaNumber a, DdApaNumber b, DdApaNumber diff)); -EXTERN DdApaDigit Cudd_ApaShortDivision ARGS((int digits, DdApaNumber dividend, DdApaDigit divisor, DdApaNumber quotient)); -EXTERN unsigned int Cudd_ApaIntDivision ARGS((int digits, DdApaNumber dividend, unsigned int divisor, DdApaNumber quotient)); -EXTERN void Cudd_ApaShiftRight ARGS((int digits, DdApaDigit in, DdApaNumber a, DdApaNumber b)); -EXTERN void Cudd_ApaSetToLiteral ARGS((int digits, DdApaNumber number, DdApaDigit literal)); -EXTERN void Cudd_ApaPowerOfTwo ARGS((int digits, DdApaNumber number, int power)); -EXTERN int Cudd_ApaCompare ARGS((int digitsFirst, DdApaNumber first, int digitsSecond, DdApaNumber second)); -EXTERN int Cudd_ApaCompareRatios ARGS ((int digitsFirst, DdApaNumber firstNum, unsigned int firstDen, int digitsSecond, DdApaNumber secondNum, unsigned int secondDen)); -EXTERN int Cudd_ApaPrintHex ARGS((FILE *fp, int digits, DdApaNumber number)); -EXTERN int Cudd_ApaPrintDecimal ARGS((FILE *fp, int digits, DdApaNumber number)); -EXTERN int Cudd_ApaPrintExponential ARGS((FILE * fp, int digits, DdApaNumber number, int precision)); -EXTERN DdApaNumber Cudd_ApaCountMinterm ARGS((DdManager *manager, DdNode *node, int nvars, int *digits)); -EXTERN int Cudd_ApaPrintMinterm ARGS((FILE *fp, DdManager *dd, DdNode *node, int nvars)); -EXTERN int Cudd_ApaPrintMintermExp ARGS((FILE * fp, DdManager * dd, DdNode * node, int nvars, int precision)); -EXTERN int Cudd_ApaPrintDensity ARGS((FILE * fp, DdManager * dd, DdNode * node, int nvars)); -EXTERN DdNode * Cudd_UnderApprox ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality)); -EXTERN DdNode * Cudd_OverApprox ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality)); -EXTERN DdNode * Cudd_RemapUnderApprox ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, double quality)); -EXTERN DdNode * Cudd_RemapOverApprox ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, double quality)); -EXTERN DdNode * Cudd_BiasedUnderApprox ARGS((DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0)); -EXTERN DdNode * Cudd_BiasedOverApprox ARGS((DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0)); -EXTERN DdNode * Cudd_bddExistAbstract ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * Cudd_bddXorExistAbstract ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)); -EXTERN DdNode * Cudd_bddUnivAbstract ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * Cudd_bddBooleanDiff ARGS((DdManager *manager, DdNode *f, int x)); -EXTERN int Cudd_bddVarIsDependent ARGS((DdManager *dd, DdNode *f, DdNode *var)); -EXTERN double Cudd_bddCorrelation ARGS((DdManager *manager, DdNode *f, DdNode *g)); -EXTERN double Cudd_bddCorrelationWeights ARGS((DdManager *manager, DdNode *f, DdNode *g, double *prob)); -EXTERN DdNode * Cudd_bddIte ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * Cudd_bddIteConstant ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * Cudd_bddIntersect ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddAnd ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddOr ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddNand ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddNor ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddXor ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddXnor ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN int Cudd_bddLeq ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_addBddThreshold ARGS((DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value)); -EXTERN DdNode * Cudd_addBddStrictThreshold ARGS((DdManager *dd, DdNode *f, CUDD_VALUE_TYPE value)); -EXTERN DdNode * Cudd_addBddInterval ARGS((DdManager *dd, DdNode *f, CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper)); -EXTERN DdNode * Cudd_addBddIthBit ARGS((DdManager *dd, DdNode *f, int bit)); -EXTERN DdNode * Cudd_BddToAdd ARGS((DdManager *dd, DdNode *B)); -EXTERN DdNode * Cudd_addBddPattern ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_bddTransfer ARGS((DdManager *ddSource, DdManager *ddDestination, DdNode *f)); -EXTERN int Cudd_DebugCheck ARGS((DdManager *table)); -EXTERN int Cudd_CheckKeys ARGS((DdManager *table)); -EXTERN DdNode * Cudd_bddClippingAnd ARGS((DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction)); -EXTERN DdNode * Cudd_bddClippingAndAbstract ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction)); -EXTERN DdNode * Cudd_Cofactor ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_bddCompose ARGS((DdManager *dd, DdNode *f, DdNode *g, int v)); -EXTERN DdNode * Cudd_addCompose ARGS((DdManager *dd, DdNode *f, DdNode *g, int v)); -EXTERN DdNode * Cudd_addPermute ARGS((DdManager *manager, DdNode *node, int *permut)); -EXTERN DdNode * Cudd_addSwapVariables ARGS((DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n)); -EXTERN DdNode * Cudd_bddPermute ARGS((DdManager *manager, DdNode *node, int *permut)); -EXTERN DdNode * Cudd_bddVarMap ARGS((DdManager *manager, DdNode *f)); -EXTERN int Cudd_SetVarMap ARGS((DdManager *manager, DdNode **x, DdNode **y, int n)); -EXTERN DdNode * Cudd_bddSwapVariables ARGS((DdManager *dd, DdNode *f, DdNode **x, DdNode **y, int n)); -EXTERN DdNode * Cudd_bddAdjPermuteX ARGS((DdManager *dd, DdNode *B, DdNode **x, int n)); -EXTERN DdNode * Cudd_addVectorCompose ARGS((DdManager *dd, DdNode *f, DdNode **vector)); -EXTERN DdNode * Cudd_addGeneralVectorCompose ARGS((DdManager *dd, DdNode *f, DdNode **vectorOn, DdNode **vectorOff)); -EXTERN DdNode * Cudd_addNonSimCompose ARGS((DdManager *dd, DdNode *f, DdNode **vector)); -EXTERN DdNode * Cudd_bddVectorCompose ARGS((DdManager *dd, DdNode *f, DdNode **vector)); -EXTERN int Cudd_bddApproxConjDecomp ARGS((DdManager *dd, DdNode *f, DdNode ***conjuncts)); -EXTERN int Cudd_bddApproxDisjDecomp ARGS((DdManager *dd, DdNode *f, DdNode ***disjuncts)); -EXTERN int Cudd_bddIterConjDecomp ARGS((DdManager *dd, DdNode *f, DdNode ***conjuncts)); -EXTERN int Cudd_bddIterDisjDecomp ARGS((DdManager *dd, DdNode *f, DdNode ***disjuncts)); -EXTERN int Cudd_bddGenConjDecomp ARGS((DdManager *dd, DdNode *f, DdNode ***conjuncts)); -EXTERN int Cudd_bddGenDisjDecomp ARGS((DdManager *dd, DdNode *f, DdNode ***disjuncts)); -EXTERN int Cudd_bddVarConjDecomp ARGS((DdManager *dd, DdNode * f, DdNode ***conjuncts)); -EXTERN int Cudd_bddVarDisjDecomp ARGS((DdManager *dd, DdNode * f, DdNode ***disjuncts)); -EXTERN DdNode * Cudd_FindEssential ARGS((DdManager *dd, DdNode *f)); -EXTERN int Cudd_bddIsVarEssential ARGS((DdManager *manager, DdNode *f, int id, int phase)); -EXTERN int Cudd_DumpBlif ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, char *mname, FILE *fp)); -EXTERN int Cudd_DumpBlifBody ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)); -EXTERN int Cudd_DumpDot ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)); -EXTERN int Cudd_DumpDaVinci ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)); -EXTERN int Cudd_DumpDDcal ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)); -EXTERN int Cudd_DumpFactoredForm ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)); -EXTERN DdNode * Cudd_bddConstrain ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * Cudd_bddRestrict ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * Cudd_addConstrain ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode ** Cudd_bddConstrainDecomp ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_addRestrict ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode ** Cudd_bddCharToVect ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_bddLICompaction ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * Cudd_bddSqueeze ARGS((DdManager *dd, DdNode *l, DdNode *u)); -EXTERN DdNode * Cudd_bddMinimize ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * Cudd_SubsetCompress ARGS((DdManager *dd, DdNode *f, int nvars, int threshold)); -EXTERN DdNode * Cudd_SupersetCompress ARGS((DdManager *dd, DdNode *f, int nvars, int threshold)); -EXTERN MtrNode * Cudd_MakeTreeNode ARGS((DdManager *dd, unsigned int low, unsigned int size, unsigned int type)); -EXTERN int Cudd_addHarwell ARGS((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)); -EXTERN DdManager * Cudd_Init ARGS((unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory)); -EXTERN void Cudd_Quit ARGS((DdManager *unique)); -EXTERN int Cudd_PrintLinear ARGS((DdManager *table)); -EXTERN int Cudd_ReadLinear ARGS((DdManager *table, int x, int y)); -EXTERN DdNode * Cudd_bddLiteralSetIntersection ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_addMatrixMultiply ARGS((DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz)); -EXTERN DdNode * Cudd_addTimesPlus ARGS((DdManager *dd, DdNode *A, DdNode *B, DdNode **z, int nz)); -EXTERN DdNode * Cudd_addTriangle ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode **z, int nz)); -EXTERN DdNode * Cudd_addOuterSum ARGS((DdManager *dd, DdNode *M, DdNode *r, DdNode *c)); -EXTERN DdNode * Cudd_PrioritySelect ARGS((DdManager *dd, DdNode *R, DdNode **x, DdNode **y, DdNode **z, DdNode *Pi, int n, DdNode * (*)(DdManager *, int, DdNode **, DdNode **, DdNode **))); -EXTERN DdNode * Cudd_Xgty ARGS((DdManager *dd, int N, DdNode **z, DdNode **x, DdNode **y)); -EXTERN DdNode * Cudd_Xeqy ARGS((DdManager *dd, int N, DdNode **x, DdNode **y)); -EXTERN DdNode * Cudd_addXeqy ARGS((DdManager *dd, int N, DdNode **x, DdNode **y)); -EXTERN DdNode * Cudd_Dxygtdxz ARGS((DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z)); -EXTERN DdNode * Cudd_Dxygtdyz ARGS((DdManager *dd, int N, DdNode **x, DdNode **y, DdNode **z)); -EXTERN DdNode * Cudd_CProjection ARGS((DdManager *dd, DdNode *R, DdNode *Y)); -EXTERN DdNode * Cudd_addHamming ARGS((DdManager *dd, DdNode **xVars, DdNode **yVars, int nVars)); -EXTERN int Cudd_MinHammingDist ARGS((DdManager *dd, DdNode *f, int *minterm, int upperBound)); -EXTERN DdNode * Cudd_bddClosestCube ARGS((DdManager *dd, DdNode * f, DdNode *g, int *distance)); -EXTERN int Cudd_addRead ARGS((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)); -EXTERN int Cudd_bddRead ARGS((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)); -EXTERN void Cudd_Ref ARGS((DdNode *n)); -EXTERN void Cudd_RecursiveDeref ARGS((DdManager *table, DdNode *n)); -EXTERN void Cudd_IterDerefBdd ARGS((DdManager *table, DdNode *n)); -EXTERN void Cudd_DelayedDerefBdd ARGS((DdManager * table, DdNode * n)); -EXTERN void Cudd_RecursiveDerefZdd ARGS((DdManager *table, DdNode *n)); -EXTERN void Cudd_Deref ARGS((DdNode *node)); -EXTERN int Cudd_CheckZeroRef ARGS((DdManager *manager)); -EXTERN int Cudd_ReduceHeap ARGS((DdManager *table, Cudd_ReorderingType heuristic, int minsize)); -EXTERN int Cudd_ShuffleHeap ARGS((DdManager *table, int *permutation)); -EXTERN DdNode * Cudd_Eval ARGS((DdManager *dd, DdNode *f, int *inputs)); -EXTERN DdNode * Cudd_ShortestPath ARGS((DdManager *manager, DdNode *f, int *weight, int *support, int *length)); -EXTERN DdNode * Cudd_LargestCube ARGS((DdManager *manager, DdNode *f, int *length)); -EXTERN int Cudd_ShortestLength ARGS((DdManager *manager, DdNode *f, int *weight)); -EXTERN DdNode * Cudd_Decreasing ARGS((DdManager *dd, DdNode *f, int i)); -EXTERN DdNode * Cudd_Increasing ARGS((DdManager *dd, DdNode *f, int i)); -EXTERN int Cudd_EquivDC ARGS((DdManager *dd, DdNode *F, DdNode *G, DdNode *D)); -EXTERN int Cudd_bddLeqUnless ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *D)); -EXTERN int Cudd_EqualSupNorm ARGS((DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr)); -EXTERN DdNode * Cudd_bddMakePrime ARGS ((DdManager *dd, DdNode *cube, DdNode *f)); -EXTERN double * Cudd_CofMinterm ARGS((DdManager *dd, DdNode *node)); -EXTERN DdNode * Cudd_SolveEqn ARGS((DdManager * bdd, DdNode *F, DdNode *Y, DdNode **G, int **yIndex, int n)); -EXTERN DdNode * Cudd_VerifySol ARGS((DdManager * bdd, DdNode *F, DdNode **G, int *yIndex, int n)); -EXTERN DdNode * Cudd_SplitSet ARGS((DdManager *manager, DdNode *S, DdNode **xVars, int n, double m)); -EXTERN DdNode * Cudd_SubsetHeavyBranch ARGS((DdManager *dd, DdNode *f, int numVars, int threshold)); -EXTERN DdNode * Cudd_SupersetHeavyBranch ARGS((DdManager *dd, DdNode *f, int numVars, int threshold)); -EXTERN DdNode * Cudd_SubsetShortPaths ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)); -EXTERN DdNode * Cudd_SupersetShortPaths ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)); -EXTERN void Cudd_SymmProfile ARGS((DdManager *table, int lower, int upper)); -EXTERN unsigned int Cudd_Prime ARGS((unsigned int p)); -EXTERN int Cudd_PrintMinterm ARGS((DdManager *manager, DdNode *node)); -EXTERN int Cudd_bddPrintCover ARGS((DdManager *dd, DdNode *l, DdNode *u)); -EXTERN int Cudd_PrintDebug ARGS((DdManager *dd, DdNode *f, int n, int pr)); -EXTERN int Cudd_DagSize ARGS((DdNode *node)); -EXTERN int Cudd_EstimateCofactor ARGS((DdManager *dd, DdNode * node, int i, int phase)); -EXTERN int Cudd_EstimateCofactorSimple ARGS((DdNode * node, int i)); -EXTERN int Cudd_SharingSize ARGS((DdNode **nodeArray, int n)); -EXTERN double Cudd_CountMinterm ARGS((DdManager *manager, DdNode *node, int nvars)); -EXTERN int Cudd_EpdCountMinterm ARGS((DdManager *manager, DdNode *node, int nvars, EpDouble *epd)); -EXTERN double Cudd_CountPath ARGS((DdNode *node)); -EXTERN double Cudd_CountPathsToNonZero ARGS((DdNode *node)); -EXTERN DdNode * Cudd_Support ARGS((DdManager *dd, DdNode *f)); -EXTERN int * Cudd_SupportIndex ARGS((DdManager *dd, DdNode *f)); -EXTERN int Cudd_SupportSize ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * Cudd_VectorSupport ARGS((DdManager *dd, DdNode **F, int n)); -EXTERN int * Cudd_VectorSupportIndex ARGS((DdManager *dd, DdNode **F, int n)); -EXTERN int Cudd_VectorSupportSize ARGS((DdManager *dd, DdNode **F, int n)); -EXTERN int Cudd_ClassifySupport ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode **common, DdNode **onlyF, DdNode **onlyG)); -EXTERN int Cudd_CountLeaves ARGS((DdNode *node)); -EXTERN int Cudd_bddPickOneCube ARGS((DdManager *ddm, DdNode *node, char *string)); -EXTERN DdNode * Cudd_bddPickOneMinterm ARGS((DdManager *dd, DdNode *f, DdNode **vars, int n)); -EXTERN DdNode ** Cudd_bddPickArbitraryMinterms ARGS((DdManager *dd, DdNode *f, DdNode **vars, int n, int k)); -EXTERN DdNode * Cudd_SubsetWithMaskVars ARGS((DdManager *dd, DdNode *f, DdNode **vars, int nvars, DdNode **maskVars, int mvars)); -EXTERN DdGen * Cudd_FirstCube ARGS((DdManager *dd, DdNode *f, int **cube, CUDD_VALUE_TYPE *value)); -EXTERN int Cudd_NextCube ARGS((DdGen *gen, int **cube, CUDD_VALUE_TYPE *value)); -EXTERN DdNode * Cudd_bddComputeCube ARGS((DdManager *dd, DdNode **vars, int *phase, int n)); -EXTERN DdNode * Cudd_addComputeCube ARGS((DdManager *dd, DdNode **vars, int *phase, int n)); -EXTERN DdNode * Cudd_CubeArrayToBdd ARGS((DdManager *dd, int *array)); -EXTERN int Cudd_BddToCubeArray ARGS((DdManager *dd, DdNode *cube, int *array)); -EXTERN DdGen * Cudd_FirstNode ARGS((DdManager *dd, DdNode *f, DdNode **node)); -EXTERN int Cudd_NextNode ARGS((DdGen *gen, DdNode **node)); -EXTERN int Cudd_GenFree ARGS((DdGen *gen)); -EXTERN int Cudd_IsGenEmpty ARGS((DdGen *gen)); -EXTERN DdNode * Cudd_IndicesToCube ARGS((DdManager *dd, int *array, int n)); -EXTERN void Cudd_PrintVersion ARGS((FILE *fp)); -EXTERN double Cudd_AverageDistance ARGS((DdManager *dd)); -EXTERN long Cudd_Random ARGS(()); -EXTERN void Cudd_Srandom ARGS((long seed)); -EXTERN double Cudd_Density ARGS((DdManager *dd, DdNode *f, int nvars)); -EXTERN void Cudd_OutOfMem ARGS((long size)); -EXTERN int Cudd_zddCount ARGS((DdManager *zdd, DdNode *P)); -EXTERN double Cudd_zddCountDouble ARGS((DdManager *zdd, DdNode *P)); -EXTERN DdNode * Cudd_zddProduct ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_zddUnateProduct ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_zddWeakDiv ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_zddDivide ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_zddWeakDivF ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_zddDivideF ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * Cudd_zddComplement ARGS((DdManager *dd, DdNode *node)); -EXTERN MtrNode * Cudd_MakeZddTreeNode ARGS((DdManager *dd, unsigned int low, unsigned int size, unsigned int type)); -EXTERN DdNode * Cudd_zddIsop ARGS((DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)); -EXTERN DdNode * Cudd_bddIsop ARGS((DdManager *dd, DdNode *L, DdNode *U)); -EXTERN DdNode * Cudd_MakeBddFromZddCover ARGS((DdManager *dd, DdNode *node)); -EXTERN int Cudd_zddDagSize ARGS((DdNode *p_node)); -EXTERN double Cudd_zddCountMinterm ARGS((DdManager *zdd, DdNode *node, int path)); -EXTERN void Cudd_zddPrintSubtable ARGS((DdManager *table)); -EXTERN DdNode * Cudd_zddPortFromBdd ARGS((DdManager *dd, DdNode *B)); -EXTERN DdNode * Cudd_zddPortToBdd ARGS((DdManager *dd, DdNode *f)); -EXTERN int Cudd_zddReduceHeap ARGS((DdManager *table, Cudd_ReorderingType heuristic, int minsize)); -EXTERN int Cudd_zddShuffleHeap ARGS((DdManager *table, int *permutation)); -EXTERN DdNode * Cudd_zddIte ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * Cudd_zddUnion ARGS((DdManager *dd, DdNode *P, DdNode *Q)); -EXTERN DdNode * Cudd_zddIntersect ARGS((DdManager *dd, DdNode *P, DdNode *Q)); -EXTERN DdNode * Cudd_zddDiff ARGS((DdManager *dd, DdNode *P, DdNode *Q)); -EXTERN DdNode * Cudd_zddDiffConst ARGS((DdManager *zdd, DdNode *P, DdNode *Q)); -EXTERN DdNode * Cudd_zddSubset1 ARGS((DdManager *dd, DdNode *P, int var)); -EXTERN DdNode * Cudd_zddSubset0 ARGS((DdManager *dd, DdNode *P, int var)); -EXTERN DdNode * Cudd_zddChange ARGS((DdManager *dd, DdNode *P, int var)); -EXTERN void Cudd_zddSymmProfile ARGS((DdManager *table, int lower, int upper)); -EXTERN int Cudd_zddPrintMinterm ARGS((DdManager *zdd, DdNode *node)); -EXTERN int Cudd_zddPrintCover ARGS((DdManager *zdd, DdNode *node)); -EXTERN int Cudd_zddPrintDebug ARGS((DdManager *zdd, DdNode *f, int n, int pr)); -EXTERN DdGen * Cudd_zddFirstPath ARGS((DdManager *zdd, DdNode *f, int **path)); -EXTERN int Cudd_zddNextPath ARGS((DdGen *gen, int **path)); -EXTERN char * Cudd_zddCoverPathToString ARGS((DdManager *zdd, int *path, char *str)); -EXTERN int Cudd_zddDumpDot ARGS((DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp)); -EXTERN int Cudd_bddSetPiVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddSetPsVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddSetNsVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddIsPiVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddIsPsVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddIsNsVar ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddSetPairIndex ARGS((DdManager *dd, int index, int pairIndex)); -EXTERN int Cudd_bddReadPairIndex ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddSetVarToBeGrouped ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddSetVarHardGroup ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddResetVarToBeGrouped ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddIsVarToBeGrouped ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddSetVarToBeUngrouped ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddIsVarToBeUngrouped ARGS((DdManager *dd, int index)); -EXTERN int Cudd_bddIsVarHardGroup ARGS((DdManager *dd, int index)); +extern DdNode * Cudd_addNewVar( DdManager * dd ); +extern DdNode * Cudd_addNewVarAtLevel( DdManager * dd, int level ); +extern DdNode * Cudd_bddNewVar( DdManager * dd ); +extern DdNode * Cudd_bddNewVarAtLevel( DdManager * dd, int level ); +extern DdNode * Cudd_addIthVar( DdManager * dd, int i ); +extern DdNode * Cudd_bddIthVar( DdManager * dd, int i ); +extern DdNode * Cudd_zddIthVar( DdManager * dd, int i ); +extern int Cudd_zddVarsFromBddVars( DdManager * dd, int multiplicity ); +extern DdNode * Cudd_addConst( DdManager * dd, CUDD_VALUE_TYPE c ); +extern int Cudd_IsNonConstant( DdNode * f ); +extern void Cudd_AutodynEnable( DdManager * unique, Cudd_ReorderingType method ); +extern void Cudd_AutodynDisable( DdManager * unique ); +extern int Cudd_ReorderingStatus( DdManager * unique, Cudd_ReorderingType * method ); +extern void Cudd_AutodynEnableZdd( DdManager * unique, Cudd_ReorderingType method ); +extern void Cudd_AutodynDisableZdd( DdManager * unique ); +extern int Cudd_ReorderingStatusZdd( DdManager * unique, Cudd_ReorderingType * method ); +extern int Cudd_zddRealignmentEnabled( DdManager * unique ); +extern void Cudd_zddRealignEnable( DdManager * unique ); +extern void Cudd_zddRealignDisable( DdManager * unique ); +extern int Cudd_bddRealignmentEnabled( DdManager * unique ); +extern void Cudd_bddRealignEnable( DdManager * unique ); +extern void Cudd_bddRealignDisable( DdManager * unique ); +extern DdNode * Cudd_ReadOne( DdManager * dd ); +extern DdNode * Cudd_ReadZddOne( DdManager * dd, int i ); +extern DdNode * Cudd_ReadZero( DdManager * dd ); +extern DdNode * Cudd_ReadLogicZero( DdManager * dd ); +extern DdNode * Cudd_ReadPlusInfinity( DdManager * dd ); +extern DdNode * Cudd_ReadMinusInfinity( DdManager * dd ); +extern DdNode * Cudd_ReadBackground( DdManager * dd ); +extern void Cudd_SetBackground( DdManager * dd, DdNode * bck ); +extern unsigned int Cudd_ReadCacheSlots( DdManager * dd ); +extern double Cudd_ReadCacheUsedSlots( DdManager * dd ); +extern double Cudd_ReadCacheLookUps( DdManager * dd ); +extern double Cudd_ReadCacheHits( DdManager * dd ); +extern double Cudd_ReadRecursiveCalls( DdManager * dd ); +extern unsigned int Cudd_ReadMinHit( DdManager * dd ); +extern void Cudd_SetMinHit( DdManager * dd, unsigned int hr ); +extern unsigned int Cudd_ReadLooseUpTo( DdManager * dd ); +extern void Cudd_SetLooseUpTo( DdManager * dd, unsigned int lut ); +extern unsigned int Cudd_ReadMaxCache( DdManager * dd ); +extern unsigned int Cudd_ReadMaxCacheHard( DdManager * dd ); +extern void Cudd_SetMaxCacheHard( DdManager * dd, unsigned int mc ); +extern int Cudd_ReadSize( DdManager * dd ); +extern int Cudd_ReadZddSize( DdManager * dd ); +extern unsigned int Cudd_ReadSlots( DdManager * dd ); +extern double Cudd_ReadUsedSlots( DdManager * dd ); +extern double Cudd_ExpectedUsedSlots( DdManager * dd ); +extern unsigned int Cudd_ReadKeys( DdManager * dd ); +extern unsigned int Cudd_ReadDead( DdManager * dd ); +extern unsigned int Cudd_ReadMinDead( DdManager * dd ); +extern int Cudd_ReadReorderings( DdManager * dd ); +extern long Cudd_ReadReorderingTime( DdManager * dd ); +extern int Cudd_ReadGarbageCollections( DdManager * dd ); +extern long Cudd_ReadGarbageCollectionTime( DdManager * dd ); +extern double Cudd_ReadNodesFreed( DdManager * dd ); +extern double Cudd_ReadNodesDropped( DdManager * dd ); +extern double Cudd_ReadUniqueLookUps( DdManager * dd ); +extern double Cudd_ReadUniqueLinks( DdManager * dd ); +extern int Cudd_ReadSiftMaxVar( DdManager * dd ); +extern void Cudd_SetSiftMaxVar( DdManager * dd, int smv ); +extern int Cudd_ReadSiftMaxSwap( DdManager * dd ); +extern void Cudd_SetSiftMaxSwap( DdManager * dd, int sms ); +extern double Cudd_ReadMaxGrowth( DdManager * dd ); +extern void Cudd_SetMaxGrowth( DdManager * dd, double mg ); +extern double Cudd_ReadMaxGrowthAlternate( DdManager * dd ); +extern void Cudd_SetMaxGrowthAlternate( DdManager * dd, double mg ); +extern int Cudd_ReadReorderingCycle( DdManager * dd ); +extern void Cudd_SetReorderingCycle( DdManager * dd, int cycle ); +extern MtrNode * Cudd_ReadTree( DdManager * dd ); +extern void Cudd_SetTree( DdManager * dd, MtrNode * tree ); +extern void Cudd_FreeTree( DdManager * dd ); +extern MtrNode * Cudd_ReadZddTree( DdManager * dd ); +extern void Cudd_SetZddTree( DdManager * dd, MtrNode * tree ); +extern void Cudd_FreeZddTree( DdManager * dd ); +extern unsigned int Cudd_NodeReadIndex( DdNode * node ); +extern int Cudd_ReadPerm( DdManager * dd, int i ); +extern int Cudd_ReadPermZdd( DdManager * dd, int i ); +extern int Cudd_ReadInvPerm( DdManager * dd, int i ); +extern int Cudd_ReadInvPermZdd( DdManager * dd, int i ); +extern DdNode * Cudd_ReadVars( DdManager * dd, int i ); +extern CUDD_VALUE_TYPE Cudd_ReadEpsilon( DdManager * dd ); +extern void Cudd_SetEpsilon( DdManager * dd, CUDD_VALUE_TYPE ep ); +extern Cudd_AggregationType Cudd_ReadGroupcheck( DdManager * dd ); +extern void Cudd_SetGroupcheck( DdManager * dd, Cudd_AggregationType gc ); +extern int Cudd_GarbageCollectionEnabled( DdManager * dd ); +extern void Cudd_EnableGarbageCollection( DdManager * dd ); +extern void Cudd_DisableGarbageCollection( DdManager * dd ); +extern int Cudd_DeadAreCounted( DdManager * dd ); +extern void Cudd_TurnOnCountDead( DdManager * dd ); +extern void Cudd_TurnOffCountDead( DdManager * dd ); +extern int Cudd_ReadRecomb( DdManager * dd ); +extern void Cudd_SetRecomb( DdManager * dd, int recomb ); +extern int Cudd_ReadSymmviolation( DdManager * dd ); +extern void Cudd_SetSymmviolation( DdManager * dd, int symmviolation ); +extern int Cudd_ReadArcviolation( DdManager * dd ); +extern void Cudd_SetArcviolation( DdManager * dd, int arcviolation ); +extern int Cudd_ReadPopulationSize( DdManager * dd ); +extern void Cudd_SetPopulationSize( DdManager * dd, int populationSize ); +extern int Cudd_ReadNumberXovers( DdManager * dd ); +extern void Cudd_SetNumberXovers( DdManager * dd, int numberXovers ); +extern unsigned long Cudd_ReadMemoryInUse( DdManager * dd ); +extern int Cudd_PrintInfo( DdManager * dd, FILE * fp ); +extern long Cudd_ReadPeakNodeCount( DdManager * dd ); +extern int Cudd_ReadPeakLiveNodeCount( DdManager * dd ); +extern long Cudd_ReadNodeCount( DdManager * dd ); +extern long Cudd_zddReadNodeCount( DdManager * dd ); +extern int Cudd_AddHook( DdManager * dd, DD_HFP f, Cudd_HookType where ); +extern int Cudd_RemoveHook( DdManager * dd, DD_HFP f, Cudd_HookType where ); +extern int Cudd_IsInHook( DdManager * dd, DD_HFP f, Cudd_HookType where ); +extern int Cudd_StdPreReordHook( DdManager * dd, const char * str, void * data ); +extern int Cudd_StdPostReordHook( DdManager * dd, const char * str, void * data ); +extern int Cudd_EnableReorderingReporting( DdManager * dd ); +extern int Cudd_DisableReorderingReporting( DdManager * dd ); +extern int Cudd_ReorderingReporting( DdManager * dd ); +extern Cudd_ErrorType Cudd_ReadErrorCode( DdManager * dd ); +extern void Cudd_ClearErrorCode( DdManager * dd ); +extern FILE * Cudd_ReadStdout( DdManager * dd ); +extern void Cudd_SetStdout( DdManager * dd, FILE * fp ); +extern FILE * Cudd_ReadStderr( DdManager * dd ); +extern void Cudd_SetStderr( DdManager * dd, FILE * fp ); +extern unsigned int Cudd_ReadNextReordering( DdManager * dd ); +extern void Cudd_SetNextReordering( DdManager * dd, unsigned int next ); +extern double Cudd_ReadSwapSteps( DdManager * dd ); +extern unsigned int Cudd_ReadMaxLive( DdManager * dd ); +extern void Cudd_SetMaxLive( DdManager * dd, unsigned int maxLive ); +extern unsigned long Cudd_ReadMaxMemory( DdManager * dd ); +extern void Cudd_SetMaxMemory( DdManager * dd, unsigned long maxMemory ); +extern int Cudd_bddBindVar( DdManager * dd, int index ); +extern int Cudd_bddUnbindVar( DdManager * dd, int index ); +extern int Cudd_bddVarIsBound( DdManager * dd, int index ); +extern DdNode * Cudd_addExistAbstract( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * Cudd_addUnivAbstract( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * Cudd_addOrAbstract( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * Cudd_addApply( DdManager * dd, DdNode * ( * )(DdManager * , DdNode ** , DdNode ** ), DdNode * f, DdNode * g ); +extern DdNode * Cudd_addPlus( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addTimes( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addThreshold( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addSetNZ( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addDivide( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addMinus( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addMinimum( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addMaximum( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addOneZeroMaximum( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addDiff( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addAgreement( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addOr( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addNand( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addNor( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addXor( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addXnor( DdManager * dd, DdNode ** f, DdNode ** g ); +extern DdNode * Cudd_addMonadicApply( DdManager * dd, DdNode * ( * op)(DdManager * , DdNode * ), DdNode * f ); +extern DdNode * Cudd_addLog( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_addFindMax( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_addFindMin( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_addIthBit( DdManager * dd, DdNode * f, int bit ); +extern DdNode * Cudd_addScalarInverse( DdManager * dd, DdNode * f, DdNode * epsilon ); +extern DdNode * Cudd_addIte( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * Cudd_addIteConstant( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * Cudd_addEvalConst( DdManager * dd, DdNode * f, DdNode * g ); +extern int Cudd_addLeq( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_addCmpl( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_addNegate( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_addRoundOff( DdManager * dd, DdNode * f, int N ); +extern DdNode * Cudd_addWalsh( DdManager * dd, DdNode ** x, DdNode ** y, int n ); +extern DdNode * Cudd_addResidue( DdManager * dd, int n, int m, int options, int top ); +extern DdNode * Cudd_bddAndAbstract( DdManager * manager, DdNode * f, DdNode * g, DdNode * cube ); +extern DdNode * Cudd_bddAndAbstractLimit( DdManager * manager, DdNode * f, DdNode * g, DdNode * cube, unsigned int limit ); +extern int Cudd_ApaNumberOfDigits( int binaryDigits ); +extern DdApaNumber Cudd_NewApaNumber( int digits ); +extern void Cudd_ApaCopy( int digits, DdApaNumber source, DdApaNumber dest ); +extern DdApaDigit Cudd_ApaAdd( int digits, DdApaNumber a, DdApaNumber b, DdApaNumber sum ); +extern DdApaDigit Cudd_ApaSubtract( int digits, DdApaNumber a, DdApaNumber b, DdApaNumber diff ); +extern DdApaDigit Cudd_ApaShortDivision( int digits, DdApaNumber dividend, DdApaDigit divisor, DdApaNumber quotient ); +extern unsigned int Cudd_ApaIntDivision( int digits, DdApaNumber dividend, unsigned int divisor, DdApaNumber quotient ); +extern void Cudd_ApaShiftRight( int digits, DdApaDigit in, DdApaNumber a, DdApaNumber b ); +extern void Cudd_ApaSetToLiteral( int digits, DdApaNumber number, DdApaDigit literal ); +extern void Cudd_ApaPowerOfTwo( int digits, DdApaNumber number, int power ); +extern int Cudd_ApaCompare( int digitsFirst, DdApaNumber first, int digitsSecond, DdApaNumber second ); +extern int Cudd_ApaCompareRatios( int digitsFirst, DdApaNumber firstNum, unsigned int firstDen, int digitsSecond, DdApaNumber secondNum, unsigned int secondDen ); +extern int Cudd_ApaPrintHex( FILE * fp, int digits, DdApaNumber number ); +extern int Cudd_ApaPrintDecimal( FILE * fp, int digits, DdApaNumber number ); +extern int Cudd_ApaPrintExponential( FILE * fp, int digits, DdApaNumber number, int precision ); +extern DdApaNumber Cudd_ApaCountMinterm( DdManager * manager, DdNode * node, int nvars, int * digits ); +extern int Cudd_ApaPrintMinterm( FILE * fp, DdManager * dd, DdNode * node, int nvars ); +extern int Cudd_ApaPrintMintermExp( FILE * fp, DdManager * dd, DdNode * node, int nvars, int precision ); +extern int Cudd_ApaPrintDensity( FILE * fp, DdManager * dd, DdNode * node, int nvars ); +extern DdNode * Cudd_UnderApprox( DdManager * dd, DdNode * f, int numVars, int threshold, int safe, double quality ); +extern DdNode * Cudd_OverApprox( DdManager * dd, DdNode * f, int numVars, int threshold, int safe, double quality ); +extern DdNode * Cudd_RemapUnderApprox( DdManager * dd, DdNode * f, int numVars, int threshold, double quality ); +extern DdNode * Cudd_RemapOverApprox( DdManager * dd, DdNode * f, int numVars, int threshold, double quality ); +extern DdNode * Cudd_BiasedUnderApprox( DdManager * dd, DdNode * f, DdNode * b, int numVars, int threshold, double quality1, double quality0 ); +extern DdNode * Cudd_BiasedOverApprox( DdManager * dd, DdNode * f, DdNode * b, int numVars, int threshold, double quality1, double quality0 ); +extern DdNode * Cudd_bddExistAbstract( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * Cudd_bddXorExistAbstract( DdManager * manager, DdNode * f, DdNode * g, DdNode * cube ); +extern DdNode * Cudd_bddUnivAbstract( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * Cudd_bddBooleanDiff( DdManager * manager, DdNode * f, int x ); +extern int Cudd_bddVarIsDependent( DdManager * dd, DdNode * f, DdNode * var ); +extern double Cudd_bddCorrelation( DdManager * manager, DdNode * f, DdNode * g ); +extern double Cudd_bddCorrelationWeights( DdManager * manager, DdNode * f, DdNode * g, double * prob ); +extern DdNode * Cudd_bddIte( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * Cudd_bddIteConstant( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * Cudd_bddIntersect( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddAnd( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddAndLimit( DdManager * dd, DdNode * f, DdNode * g, unsigned int limit ); +extern DdNode * Cudd_bddOr( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddNand( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddNor( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddXor( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddXnor( DdManager * dd, DdNode * f, DdNode * g ); +extern int Cudd_bddLeq( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_addBddThreshold( DdManager * dd, DdNode * f, CUDD_VALUE_TYPE value ); +extern DdNode * Cudd_addBddStrictThreshold( DdManager * dd, DdNode * f, CUDD_VALUE_TYPE value ); +extern DdNode * Cudd_addBddInterval( DdManager * dd, DdNode * f, CUDD_VALUE_TYPE lower, CUDD_VALUE_TYPE upper ); +extern DdNode * Cudd_addBddIthBit( DdManager * dd, DdNode * f, int bit ); +extern DdNode * Cudd_BddToAdd( DdManager * dd, DdNode * B ); +extern DdNode * Cudd_addBddPattern( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_bddTransfer( DdManager * ddSource, DdManager * ddDestination, DdNode * f ); +extern int Cudd_DebugCheck( DdManager * table ); +extern int Cudd_CheckKeys( DdManager * table ); +extern DdNode * Cudd_bddClippingAnd( DdManager * dd, DdNode * f, DdNode * g, int maxDepth, int direction ); +extern DdNode * Cudd_bddClippingAndAbstract( DdManager * dd, DdNode * f, DdNode * g, DdNode * cube, int maxDepth, int direction ); +extern DdNode * Cudd_Cofactor( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_bddCompose( DdManager * dd, DdNode * f, DdNode * g, int v ); +extern DdNode * Cudd_addCompose( DdManager * dd, DdNode * f, DdNode * g, int v ); +extern DdNode * Cudd_addPermute( DdManager * manager, DdNode * node, int * permut ); +extern DdNode * Cudd_addSwapVariables( DdManager * dd, DdNode * f, DdNode ** x, DdNode ** y, int n ); +extern DdNode * Cudd_bddPermute( DdManager * manager, DdNode * node, int * permut ); +extern DdNode * Cudd_bddVarMap( DdManager * manager, DdNode * f ); +extern int Cudd_SetVarMap( DdManager * manager, DdNode ** x, DdNode ** y, int n ); +extern DdNode * Cudd_bddSwapVariables( DdManager * dd, DdNode * f, DdNode ** x, DdNode ** y, int n ); +extern DdNode * Cudd_bddAdjPermuteX( DdManager * dd, DdNode * B, DdNode ** x, int n ); +extern DdNode * Cudd_addVectorCompose( DdManager * dd, DdNode * f, DdNode ** vector ); +extern DdNode * Cudd_addGeneralVectorCompose( DdManager * dd, DdNode * f, DdNode ** vectorOn, DdNode ** vectorOff ); +extern DdNode * Cudd_addNonSimCompose( DdManager * dd, DdNode * f, DdNode ** vector ); +extern DdNode * Cudd_bddVectorCompose( DdManager * dd, DdNode * f, DdNode ** vector ); +extern int Cudd_bddApproxConjDecomp( DdManager * dd, DdNode * f, DdNode ** * conjuncts ); +extern int Cudd_bddApproxDisjDecomp( DdManager * dd, DdNode * f, DdNode ** * disjuncts ); +extern int Cudd_bddIterConjDecomp( DdManager * dd, DdNode * f, DdNode ** * conjuncts ); +extern int Cudd_bddIterDisjDecomp( DdManager * dd, DdNode * f, DdNode ** * disjuncts ); +extern int Cudd_bddGenConjDecomp( DdManager * dd, DdNode * f, DdNode ** * conjuncts ); +extern int Cudd_bddGenDisjDecomp( DdManager * dd, DdNode * f, DdNode ** * disjuncts ); +extern int Cudd_bddVarConjDecomp( DdManager * dd, DdNode * f, DdNode ** * conjuncts ); +extern int Cudd_bddVarDisjDecomp( DdManager * dd, DdNode * f, DdNode ** * disjuncts ); +extern DdNode * Cudd_FindEssential( DdManager * dd, DdNode * f ); +extern int Cudd_bddIsVarEssential( DdManager * manager, DdNode * f, int id, int phase ); +extern DdTlcInfo * Cudd_FindTwoLiteralClauses( DdManager * dd, DdNode * f ); +extern int Cudd_PrintTwoLiteralClauses( DdManager * dd, DdNode * f, char ** names, FILE * fp ); +extern int Cudd_ReadIthClause( DdTlcInfo * tlc, int i, DdHalfWord * var1, DdHalfWord * var2, int * phase1, int * phase2 ); +extern void Cudd_tlcInfoFree( DdTlcInfo * t ); +extern int Cudd_DumpBlif( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, char * mname, FILE * fp, int mv ); +extern int Cudd_DumpBlifBody( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, FILE * fp, int mv ); +extern int Cudd_DumpDot( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, FILE * fp ); +extern int Cudd_DumpDaVinci( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, FILE * fp ); +extern int Cudd_DumpDDcal( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, FILE * fp ); +extern int Cudd_DumpFactoredForm( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, FILE * fp ); +extern DdNode * Cudd_bddConstrain( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * Cudd_bddRestrict( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * Cudd_bddNPAnd( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * Cudd_addConstrain( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode ** Cudd_bddConstrainDecomp( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_addRestrict( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode ** Cudd_bddCharToVect( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_bddLICompaction( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * Cudd_bddSqueeze( DdManager * dd, DdNode * l, DdNode * u ); +extern DdNode * Cudd_bddMinimize( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * Cudd_SubsetCompress( DdManager * dd, DdNode * f, int nvars, int threshold ); +extern DdNode * Cudd_SupersetCompress( DdManager * dd, DdNode * f, int nvars, int threshold ); +extern MtrNode * Cudd_MakeTreeNode( DdManager * dd, unsigned int low, unsigned int size, unsigned int type ); +extern 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 ); +extern DdManager * Cudd_Init( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory ); +extern void Cudd_Quit( DdManager * unique ); +extern int Cudd_PrintLinear( DdManager * table ); +extern int Cudd_ReadLinear( DdManager * table, int x, int y ); +extern DdNode * Cudd_bddLiteralSetIntersection( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_addMatrixMultiply( DdManager * dd, DdNode * A, DdNode * B, DdNode ** z, int nz ); +extern DdNode * Cudd_addTimesPlus( DdManager * dd, DdNode * A, DdNode * B, DdNode ** z, int nz ); +extern DdNode * Cudd_addTriangle( DdManager * dd, DdNode * f, DdNode * g, DdNode ** z, int nz ); +extern DdNode * Cudd_addOuterSum( DdManager * dd, DdNode * M, DdNode * r, DdNode * c ); +extern DdNode * Cudd_PrioritySelect( DdManager * dd, DdNode * R, DdNode ** x, DdNode ** y, DdNode ** z, DdNode * Pi, int n, DdNode * ( * )(DdManager * , int, DdNode ** , DdNode ** , DdNode ** ) ); +extern DdNode * Cudd_Xgty( DdManager * dd, int N, DdNode ** z, DdNode ** x, DdNode ** y ); +extern DdNode * Cudd_Xeqy( DdManager * dd, int N, DdNode ** x, DdNode ** y ); +extern DdNode * Cudd_addXeqy( DdManager * dd, int N, DdNode ** x, DdNode ** y ); +extern DdNode * Cudd_Dxygtdxz( DdManager * dd, int N, DdNode ** x, DdNode ** y, DdNode ** z ); +extern DdNode * Cudd_Dxygtdyz( DdManager * dd, int N, DdNode ** x, DdNode ** y, DdNode ** z ); +extern DdNode * Cudd_Inequality( DdManager * dd, int N, int c, DdNode ** x, DdNode ** y ); +extern DdNode * Cudd_Disequality( DdManager * dd, int N, int c, DdNode ** x, DdNode ** y ); +extern DdNode * Cudd_bddInterval( DdManager * dd, int N, DdNode ** x, unsigned int lowerB, unsigned int upperB ); +extern DdNode * Cudd_CProjection( DdManager * dd, DdNode * R, DdNode * Y ); +extern DdNode * Cudd_addHamming( DdManager * dd, DdNode ** xVars, DdNode ** yVars, int nVars ); +extern int Cudd_MinHammingDist( DdManager * dd, DdNode * f, int * minterm, int upperBound ); +extern DdNode * Cudd_bddClosestCube( DdManager * dd, DdNode * f, DdNode * g, int * distance ); +extern 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 ); +extern 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 ); +extern void Cudd_Ref( DdNode * n ); +extern void Cudd_RecursiveDeref( DdManager * table, DdNode * n ); +extern void Cudd_IterDerefBdd( DdManager * table, DdNode * n ); +extern void Cudd_DelayedDerefBdd( DdManager * table, DdNode * n ); +extern void Cudd_RecursiveDerefZdd( DdManager * table, DdNode * n ); +extern void Cudd_Deref( DdNode * node ); +extern int Cudd_CheckZeroRef( DdManager * manager ); +extern int Cudd_ReduceHeap( DdManager * table, Cudd_ReorderingType heuristic, int minsize ); +extern int Cudd_ShuffleHeap( DdManager * table, int * permutation ); +extern DdNode * Cudd_Eval( DdManager * dd, DdNode * f, int * inputs ); +extern DdNode * Cudd_ShortestPath( DdManager * manager, DdNode * f, int * weight, int * support, int * length ); +extern DdNode * Cudd_LargestCube( DdManager * manager, DdNode * f, int * length ); +extern int Cudd_ShortestLength( DdManager * manager, DdNode * f, int * weight ); +extern DdNode * Cudd_Decreasing( DdManager * dd, DdNode * f, int i ); +extern DdNode * Cudd_Increasing( DdManager * dd, DdNode * f, int i ); +extern int Cudd_EquivDC( DdManager * dd, DdNode * F, DdNode * G, DdNode * D ); +extern int Cudd_bddLeqUnless( DdManager * dd, DdNode * f, DdNode * g, DdNode * D ); +extern int Cudd_EqualSupNorm( DdManager * dd, DdNode * f, DdNode * g, CUDD_VALUE_TYPE tolerance, int pr ); +extern DdNode * Cudd_bddMakePrime( DdManager * dd, DdNode * cube, DdNode * f ); +extern double * Cudd_CofMinterm( DdManager * dd, DdNode * node ); +extern DdNode * Cudd_SolveEqn( DdManager * bdd, DdNode * F, DdNode * Y, DdNode ** G, int ** yIndex, int n ); +extern DdNode * Cudd_VerifySol( DdManager * bdd, DdNode * F, DdNode ** G, int * yIndex, int n ); +extern DdNode * Cudd_SplitSet( DdManager * manager, DdNode * S, DdNode ** xVars, int n, double m ); +extern DdNode * Cudd_SubsetHeavyBranch( DdManager * dd, DdNode * f, int numVars, int threshold ); +extern DdNode * Cudd_SupersetHeavyBranch( DdManager * dd, DdNode * f, int numVars, int threshold ); +extern DdNode * Cudd_SubsetShortPaths( DdManager * dd, DdNode * f, int numVars, int threshold, int hardlimit ); +extern DdNode * Cudd_SupersetShortPaths( DdManager * dd, DdNode * f, int numVars, int threshold, int hardlimit ); +extern void Cudd_SymmProfile( DdManager * table, int lower, int upper ); +extern unsigned int Cudd_Prime( unsigned int p ); +extern int Cudd_PrintMinterm( DdManager * manager, DdNode * node ); +extern int Cudd_bddPrintCover( DdManager * dd, DdNode * l, DdNode * u ); +extern int Cudd_PrintDebug( DdManager * dd, DdNode * f, int n, int pr ); +extern int Cudd_DagSize( DdNode * node ); +extern int Cudd_EstimateCofactor( DdManager * dd, DdNode * node, int i, int phase ); +extern int Cudd_EstimateCofactorSimple( DdNode * node, int i ); +extern int Cudd_SharingSize( DdNode ** nodeArray, int n ); +extern double Cudd_CountMinterm( DdManager * manager, DdNode * node, int nvars ); +extern int Cudd_EpdCountMinterm( DdManager * manager, DdNode * node, int nvars, EpDouble * epd ); +extern double Cudd_CountPath( DdNode * node ); +extern double Cudd_CountPathsToNonZero( DdNode * node ); +extern DdNode * Cudd_Support( DdManager * dd, DdNode * f ); +extern int * Cudd_SupportIndex( DdManager * dd, DdNode * f ); +extern int Cudd_SupportSize( DdManager * dd, DdNode * f ); +extern DdNode * Cudd_VectorSupport( DdManager * dd, DdNode ** F, int n ); +extern int * Cudd_VectorSupportIndex( DdManager * dd, DdNode ** F, int n ); +extern int Cudd_VectorSupportSize( DdManager * dd, DdNode ** F, int n ); +extern int Cudd_ClassifySupport( DdManager * dd, DdNode * f, DdNode * g, DdNode ** common, DdNode ** onlyF, DdNode ** onlyG ); +extern int Cudd_CountLeaves( DdNode * node ); +extern int Cudd_bddPickOneCube( DdManager * ddm, DdNode * node, char * string ); +extern DdNode * Cudd_bddPickOneMinterm( DdManager * dd, DdNode * f, DdNode ** vars, int n ); +extern DdNode ** Cudd_bddPickArbitraryMinterms( DdManager * dd, DdNode * f, DdNode ** vars, int n, int k ); +extern DdNode * Cudd_SubsetWithMaskVars( DdManager * dd, DdNode * f, DdNode ** vars, int nvars, DdNode ** maskVars, int mvars ); +extern DdGen * Cudd_FirstCube( DdManager * dd, DdNode * f, int ** cube, CUDD_VALUE_TYPE * value ); +extern int Cudd_NextCube( DdGen * gen, int ** cube, CUDD_VALUE_TYPE * value ); +extern DdGen * Cudd_FirstPrime(DdManager * dd, DdNode * l, DdNode * u, int ** cube ); +extern int Cudd_NextPrime(DdGen * gen, int ** cube ); +extern DdNode * Cudd_bddComputeCube( DdManager * dd, DdNode ** vars, int * phase, int n ); +extern DdNode * Cudd_addComputeCube( DdManager * dd, DdNode ** vars, int * phase, int n ); +extern DdNode * Cudd_CubeArrayToBdd( DdManager * dd, int * array ); +extern int Cudd_BddToCubeArray( DdManager * dd, DdNode * cube, int * array ); +extern DdGen * Cudd_FirstNode( DdManager * dd, DdNode * f, DdNode ** node ); +extern int Cudd_NextNode( DdGen * gen, DdNode ** node ); +extern int Cudd_GenFree( DdGen * gen ); +extern int Cudd_IsGenEmpty( DdGen * gen ); +extern DdNode * Cudd_IndicesToCube( DdManager * dd, int * array, int n ); +extern void Cudd_PrintVersion( FILE * fp ); +extern double Cudd_AverageDistance( DdManager * dd ); +extern long Cudd_Random( void ); +extern void Cudd_Srandom( long seed ); +extern double Cudd_Density( DdManager * dd, DdNode * f, int nvars ); +extern void Cudd_OutOfMem( long size ); +extern int Cudd_zddCount( DdManager * zdd, DdNode * P ); +extern double Cudd_zddCountDouble( DdManager * zdd, DdNode * P ); +extern DdNode * Cudd_zddProduct( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_zddUnateProduct( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_zddWeakDiv( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_zddDivide( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_zddWeakDivF( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_zddDivideF( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * Cudd_zddComplement( DdManager * dd, DdNode * node ); +extern MtrNode * Cudd_MakeZddTreeNode( DdManager * dd, unsigned int low, unsigned int size, unsigned int type ); +extern DdNode * Cudd_zddIsop( DdManager * dd, DdNode * L, DdNode * U, DdNode ** zdd_I ); +extern DdNode * Cudd_bddIsop( DdManager * dd, DdNode * L, DdNode * U ); +extern DdNode * Cudd_MakeBddFromZddCover( DdManager * dd, DdNode * node ); +extern int Cudd_zddDagSize( DdNode * p_node ); +extern double Cudd_zddCountMinterm( DdManager * zdd, DdNode * node, int path ); +extern void Cudd_zddPrintSubtable( DdManager * table ); +extern DdNode * Cudd_zddPortFromBdd( DdManager * dd, DdNode * B ); +extern DdNode * Cudd_zddPortToBdd( DdManager * dd, DdNode * f ); +extern int Cudd_zddReduceHeap( DdManager * table, Cudd_ReorderingType heuristic, int minsize ); +extern int Cudd_zddShuffleHeap( DdManager * table, int * permutation ); +extern DdNode * Cudd_zddIte( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * Cudd_zddUnion( DdManager * dd, DdNode * P, DdNode * Q ); +extern DdNode * Cudd_zddIntersect( DdManager * dd, DdNode * P, DdNode * Q ); +extern DdNode * Cudd_zddDiff( DdManager * dd, DdNode * P, DdNode * Q ); +extern DdNode * Cudd_zddDiffConst( DdManager * zdd, DdNode * P, DdNode * Q ); +extern DdNode * Cudd_zddSubset1( DdManager * dd, DdNode * P, int var ); +extern DdNode * Cudd_zddSubset0( DdManager * dd, DdNode * P, int var ); +extern DdNode * Cudd_zddChange( DdManager * dd, DdNode * P, int var ); +extern void Cudd_zddSymmProfile( DdManager * table, int lower, int upper ); +extern int Cudd_zddPrintMinterm( DdManager * zdd, DdNode * node ); +extern int Cudd_zddPrintCover( DdManager * zdd, DdNode * node ); +extern int Cudd_zddPrintDebug( DdManager * zdd, DdNode * f, int n, int pr ); +extern DdGen * Cudd_zddFirstPath( DdManager * zdd, DdNode * f, int ** path ); +extern int Cudd_zddNextPath( DdGen * gen, int ** path ); +extern char * Cudd_zddCoverPathToString( DdManager * zdd, int * path, char * str ); +extern int Cudd_zddDumpDot( DdManager * dd, int n, DdNode ** f, char ** inames, char ** onames, FILE * fp ); +extern int Cudd_bddSetPiVar( DdManager * dd, int index ); +extern int Cudd_bddSetPsVar( DdManager * dd, int index ); +extern int Cudd_bddSetNsVar( DdManager * dd, int index ); +extern int Cudd_bddIsPiVar( DdManager * dd, int index ); +extern int Cudd_bddIsPsVar( DdManager * dd, int index ); +extern int Cudd_bddIsNsVar( DdManager * dd, int index ); +extern int Cudd_bddSetPairIndex( DdManager * dd, int index, int pairIndex ); +extern int Cudd_bddReadPairIndex( DdManager * dd, int index ); +extern int Cudd_bddSetVarToBeGrouped( DdManager * dd, int index ); +extern int Cudd_bddSetVarHardGroup( DdManager * dd, int index ); +extern int Cudd_bddResetVarToBeGrouped( DdManager * dd, int index ); +extern int Cudd_bddIsVarToBeGrouped( DdManager * dd, int index ); +extern int Cudd_bddSetVarToBeUngrouped( DdManager * dd, int index ); +extern int Cudd_bddIsVarToBeUngrouped( DdManager * dd, int index ); +extern int Cudd_bddIsVarHardGroup( DdManager * dd, int index ); /**AutomaticEnd***************************************************************/ diff --git a/src/bdd/cudd/cuddAPI.c b/src/bdd/cudd/cuddAPI.c index 729dd329..233795e2 100644 --- a/src/bdd/cudd/cuddAPI.c +++ b/src/bdd/cudd/cuddAPI.c @@ -7,169 +7,197 @@ Synopsis [Application interface functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_addNewVar() - <li> Cudd_addNewVarAtLevel() - <li> Cudd_bddNewVar() - <li> Cudd_bddNewVarAtLevel() - <li> Cudd_addIthVar() - <li> Cudd_bddIthVar() - <li> Cudd_zddIthVar() - <li> Cudd_zddVarsFromBddVars() - <li> Cudd_addConst() - <li> Cudd_IsNonConstant() - <li> Cudd_AutodynEnable() - <li> Cudd_AutodynDisable() - <li> Cudd_ReorderingStatus() - <li> Cudd_AutodynEnableZdd() - <li> Cudd_AutodynDisableZdd() - <li> Cudd_ReorderingStatusZdd() - <li> Cudd_zddRealignmentEnabled() - <li> Cudd_zddRealignEnable() - <li> Cudd_zddRealignDisable() - <li> Cudd_bddRealignmentEnabled() - <li> Cudd_bddRealignEnable() - <li> Cudd_bddRealignDisable() - <li> Cudd_ReadOne() - <li> Cudd_ReadZddOne() - <li> Cudd_ReadZero() - <li> Cudd_ReadLogicZero() - <li> Cudd_ReadPlusInfinity() - <li> Cudd_ReadMinusInfinity() - <li> Cudd_ReadBackground() - <li> Cudd_SetBackground() - <li> Cudd_ReadCacheSlots() - <li> Cudd_ReadCacheUsedSlots() - <li> Cudd_ReadCacheLookUps() - <li> Cudd_ReadCacheHits() - <li> Cudd_ReadMinHit() - <li> Cudd_SetMinHit() - <li> Cudd_ReadLooseUpTo() - <li> Cudd_SetLooseUpTo() - <li> Cudd_ReadMaxCache() - <li> Cudd_ReadMaxCacheHard() - <li> Cudd_SetMaxCacheHard() - <li> Cudd_ReadSize() - <li> Cudd_ReadSlots() - <li> Cudd_ReadUsedSlots() - <li> Cudd_ExpectedUsedSlots() - <li> Cudd_ReadKeys() - <li> Cudd_ReadDead() - <li> Cudd_ReadMinDead() - <li> Cudd_ReadReorderings() - <li> Cudd_ReadReorderingTime() - <li> Cudd_ReadGarbageCollections() - <li> Cudd_ReadGarbageCollectionTime() - <li> Cudd_ReadNodesFreed() - <li> Cudd_ReadNodesDropped() - <li> Cudd_ReadUniqueLookUps() - <li> Cudd_ReadUniqueLinks() - <li> Cudd_ReadSiftMaxVar() - <li> Cudd_SetSiftMaxVar() - <li> Cudd_ReadMaxGrowth() - <li> Cudd_SetMaxGrowth() - <li> Cudd_ReadMaxGrowthAlternate() - <li> Cudd_SetMaxGrowthAlternate() - <li> Cudd_ReadReorderingCycle() - <li> Cudd_SetReorderingCycle() - <li> Cudd_ReadTree() - <li> Cudd_SetTree() - <li> Cudd_FreeTree() - <li> Cudd_ReadZddTree() - <li> Cudd_SetZddTree() - <li> Cudd_FreeZddTree() + <ul> + <li> Cudd_addNewVar() + <li> Cudd_addNewVarAtLevel() + <li> Cudd_bddNewVar() + <li> Cudd_bddNewVarAtLevel() + <li> Cudd_addIthVar() + <li> Cudd_bddIthVar() + <li> Cudd_zddIthVar() + <li> Cudd_zddVarsFromBddVars() + <li> Cudd_addConst() + <li> Cudd_IsNonConstant() + <li> Cudd_AutodynEnable() + <li> Cudd_AutodynDisable() + <li> Cudd_ReorderingStatus() + <li> Cudd_AutodynEnableZdd() + <li> Cudd_AutodynDisableZdd() + <li> Cudd_ReorderingStatusZdd() + <li> Cudd_zddRealignmentEnabled() + <li> Cudd_zddRealignEnable() + <li> Cudd_zddRealignDisable() + <li> Cudd_bddRealignmentEnabled() + <li> Cudd_bddRealignEnable() + <li> Cudd_bddRealignDisable() + <li> Cudd_ReadOne() + <li> Cudd_ReadZddOne() + <li> Cudd_ReadZero() + <li> Cudd_ReadLogicZero() + <li> Cudd_ReadPlusInfinity() + <li> Cudd_ReadMinusInfinity() + <li> Cudd_ReadBackground() + <li> Cudd_SetBackground() + <li> Cudd_ReadCacheSlots() + <li> Cudd_ReadCacheUsedSlots() + <li> Cudd_ReadCacheLookUps() + <li> Cudd_ReadCacheHits() + <li> Cudd_ReadMinHit() + <li> Cudd_SetMinHit() + <li> Cudd_ReadLooseUpTo() + <li> Cudd_SetLooseUpTo() + <li> Cudd_ReadMaxCache() + <li> Cudd_ReadMaxCacheHard() + <li> Cudd_SetMaxCacheHard() + <li> Cudd_ReadSize() + <li> Cudd_ReadSlots() + <li> Cudd_ReadUsedSlots() + <li> Cudd_ExpectedUsedSlots() + <li> Cudd_ReadKeys() + <li> Cudd_ReadDead() + <li> Cudd_ReadMinDead() + <li> Cudd_ReadReorderings() + <li> Cudd_ReadReorderingTime() + <li> Cudd_ReadGarbageCollections() + <li> Cudd_ReadGarbageCollectionTime() + <li> Cudd_ReadNodesFreed() + <li> Cudd_ReadNodesDropped() + <li> Cudd_ReadUniqueLookUps() + <li> Cudd_ReadUniqueLinks() + <li> Cudd_ReadSiftMaxVar() + <li> Cudd_SetSiftMaxVar() + <li> Cudd_ReadMaxGrowth() + <li> Cudd_SetMaxGrowth() + <li> Cudd_ReadMaxGrowthAlternate() + <li> Cudd_SetMaxGrowthAlternate() + <li> Cudd_ReadReorderingCycle() + <li> Cudd_SetReorderingCycle() + <li> Cudd_ReadTree() + <li> Cudd_SetTree() + <li> Cudd_FreeTree() + <li> Cudd_ReadZddTree() + <li> Cudd_SetZddTree() + <li> Cudd_FreeZddTree() <li> Cudd_NodeReadIndex() - <li> Cudd_ReadPerm() - <li> Cudd_ReadInvPerm() - <li> Cudd_ReadVars() - <li> Cudd_ReadEpsilon() - <li> Cudd_SetEpsilon() - <li> Cudd_ReadGroupCheck() - <li> Cudd_SetGroupcheck() - <li> Cudd_GarbageCollectionEnabled() - <li> Cudd_EnableGarbageCollection() - <li> Cudd_DisableGarbageCollection() - <li> Cudd_DeadAreCounted() - <li> Cudd_TurnOnCountDead() - <li> Cudd_TurnOffCountDead() - <li> Cudd_ReadRecomb() - <li> Cudd_SetRecomb() - <li> Cudd_ReadSymmviolation() - <li> Cudd_SetSymmviolation() - <li> Cudd_ReadArcviolation() - <li> Cudd_SetArcviolation() - <li> Cudd_ReadPopulationSize() - <li> Cudd_SetPopulationSize() - <li> Cudd_ReadNumberXovers() - <li> Cudd_SetNumberXovers() - <li> Cudd_ReadMemoryInUse() - <li> Cudd_PrintInfo() - <li> Cudd_ReadPeakNodeCount() - <li> Cudd_ReadPeakLiveNodeCount() - <li> Cudd_ReadNodeCount() - <li> Cudd_zddReadNodeCount() - <li> Cudd_AddHook() - <li> Cudd_RemoveHook() - <li> Cudd_IsInHook() - <li> Cudd_StdPreReordHook() - <li> Cudd_StdPostReordHook() - <li> Cudd_EnableReorderingReporting() - <li> Cudd_DisableReorderingReporting() - <li> Cudd_ReorderingReporting() - <li> Cudd_ReadErrorCode() - <li> Cudd_ClearErrorCode() - <li> Cudd_ReadStdout() - <li> Cudd_SetStdout() - <li> Cudd_ReadStderr() - <li> Cudd_SetStderr() - <li> Cudd_ReadNextReordering() - <li> Cudd_SetNextReordering() - <li> Cudd_ReadSwapSteps() - <li> Cudd_ReadMaxLive() - <li> Cudd_SetMaxLive() - <li> Cudd_ReadMaxMemory() - <li> Cudd_SetMaxMemory() - <li> Cudd_bddBindVar() - <li> Cudd_bddUnbindVar() - <li> Cudd_bddVarIsBound() - <li> Cudd_bddSetPiVar() - <li> Cudd_bddSetPsVar() - <li> Cudd_bddSetNsVar() - <li> Cudd_bddIsPiVar() - <li> Cudd_bddIsPsVar() - <li> Cudd_bddIsNsVar() - <li> Cudd_bddSetPairIndex() - <li> Cudd_bddReadPairIndex() - <li> Cudd_bddSetVarToBeGrouped() - <li> Cudd_bddSetVarHardGroup() - <li> Cudd_bddResetVarToBeGrouped() - <li> Cudd_bddIsVarToBeGrouped() - <li> Cudd_bddSetVarToBeUngrouped() - <li> Cudd_bddIsVarToBeUngrouped() - <li> Cudd_bddIsVarHardGroup() - </ul> - Static procedures included in this module: - <ul> - <li> fixVarTree() - </ul>] + <li> Cudd_ReadPerm() + <li> Cudd_ReadInvPerm() + <li> Cudd_ReadVars() + <li> Cudd_ReadEpsilon() + <li> Cudd_SetEpsilon() + <li> Cudd_ReadGroupCheck() + <li> Cudd_SetGroupcheck() + <li> Cudd_GarbageCollectionEnabled() + <li> Cudd_EnableGarbageCollection() + <li> Cudd_DisableGarbageCollection() + <li> Cudd_DeadAreCounted() + <li> Cudd_TurnOnCountDead() + <li> Cudd_TurnOffCountDead() + <li> Cudd_ReadRecomb() + <li> Cudd_SetRecomb() + <li> Cudd_ReadSymmviolation() + <li> Cudd_SetSymmviolation() + <li> Cudd_ReadArcviolation() + <li> Cudd_SetArcviolation() + <li> Cudd_ReadPopulationSize() + <li> Cudd_SetPopulationSize() + <li> Cudd_ReadNumberXovers() + <li> Cudd_SetNumberXovers() + <li> Cudd_ReadMemoryInUse() + <li> Cudd_PrintInfo() + <li> Cudd_ReadPeakNodeCount() + <li> Cudd_ReadPeakLiveNodeCount() + <li> Cudd_ReadNodeCount() + <li> Cudd_zddReadNodeCount() + <li> Cudd_AddHook() + <li> Cudd_RemoveHook() + <li> Cudd_IsInHook() + <li> Cudd_StdPreReordHook() + <li> Cudd_StdPostReordHook() + <li> Cudd_EnableReorderingReporting() + <li> Cudd_DisableReorderingReporting() + <li> Cudd_ReorderingReporting() + <li> Cudd_ReadErrorCode() + <li> Cudd_ClearErrorCode() + <li> Cudd_ReadStdout() + <li> Cudd_SetStdout() + <li> Cudd_ReadStderr() + <li> Cudd_SetStderr() + <li> Cudd_ReadNextReordering() + <li> Cudd_SetNextReordering() + <li> Cudd_ReadSwapSteps() + <li> Cudd_ReadMaxLive() + <li> Cudd_SetMaxLive() + <li> Cudd_ReadMaxMemory() + <li> Cudd_SetMaxMemory() + <li> Cudd_bddBindVar() + <li> Cudd_bddUnbindVar() + <li> Cudd_bddVarIsBound() + <li> Cudd_bddSetPiVar() + <li> Cudd_bddSetPsVar() + <li> Cudd_bddSetNsVar() + <li> Cudd_bddIsPiVar() + <li> Cudd_bddIsPsVar() + <li> Cudd_bddIsNsVar() + <li> Cudd_bddSetPairIndex() + <li> Cudd_bddReadPairIndex() + <li> Cudd_bddSetVarToBeGrouped() + <li> Cudd_bddSetVarHardGroup() + <li> Cudd_bddResetVarToBeGrouped() + <li> Cudd_bddIsVarToBeGrouped() + <li> Cudd_bddSetVarToBeUngrouped() + <li> Cudd_bddIsVarToBeUngrouped() + <li> Cudd_bddIsVarHardGroup() + </ul> + Static procedures included in this module: + <ul> + <li> fixVarTree() + </ul>] SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -187,7 +215,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAPI.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAPI.c,v 1.59 2009/02/19 16:14:14 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -200,8 +228,8 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAPI.c,v 1.1.1.1 2003/02/24 22:23:51 wj /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void fixVarTree ARGS((MtrNode *treenode, int *perm, int size)); -static int addMultiplicityGroups ARGS((DdManager *dd, MtrNode *treenode, int multiplicity, char *vmask, char *lmask)); +static void fixVarTree (MtrNode *treenode, int *perm, int size); +static int addMultiplicityGroups (DdManager *dd, MtrNode *treenode, int multiplicity, char *vmask, char *lmask); /**AutomaticEnd***************************************************************/ @@ -235,8 +263,8 @@ Cudd_addNewVar( if ((unsigned int) dd->size >= CUDD_MAXINDEX - 1) return(NULL); do { - dd->reordered = 0; - res = cuddUniqueInter(dd,dd->size,DD_ONE(dd),DD_ZERO(dd)); + dd->reordered = 0; + res = cuddUniqueInter(dd,dd->size,DD_ONE(dd),DD_ZERO(dd)); } while (dd->reordered == 1); return(res); @@ -269,8 +297,8 @@ Cudd_addNewVarAtLevel( if (level >= dd->size) return(Cudd_addIthVar(dd,level)); if (!cuddInsertSubtables(dd,1,level)) return(NULL); do { - dd->reordered = 0; - res = cuddUniqueInter(dd,dd->size - 1,DD_ONE(dd),DD_ZERO(dd)); + dd->reordered = 0; + res = cuddUniqueInter(dd,dd->size - 1,DD_ONE(dd),DD_ZERO(dd)); } while (dd->reordered == 1); return(res); @@ -361,8 +389,8 @@ Cudd_addIthVar( if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); do { - dd->reordered = 0; - res = cuddUniqueInter(dd,i,DD_ONE(dd),DD_ZERO(dd)); + dd->reordered = 0; + res = cuddUniqueInter(dd,i,DD_ONE(dd),DD_ZERO(dd)); } while (dd->reordered == 1); return(res); @@ -393,9 +421,9 @@ Cudd_bddIthVar( if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL); if (i < dd->size) { - res = dd->vars[i]; + res = dd->vars[i]; } else { - res = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + res = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); } return(res); @@ -437,27 +465,27 @@ Cudd_zddIthVar( /* First we build the node at the level of index i. */ lower = (i < dd->sizeZ - 1) ? dd->univ[dd->permZ[i]+1] : DD_ONE(dd); do { - dd->reordered = 0; - zvar = cuddUniqueInterZdd(dd, i, lower, DD_ZERO(dd)); + dd->reordered = 0; + zvar = cuddUniqueInterZdd(dd, i, lower, DD_ZERO(dd)); } while (dd->reordered == 1); if (zvar == NULL) - return(NULL); + return(NULL); cuddRef(zvar); /* Now we add the "filler" nodes above the level of index i. */ for (j = dd->permZ[i] - 1; j >= 0; j--) { - do { - dd->reordered = 0; - res = cuddUniqueInterZdd(dd, dd->invpermZ[j], zvar, zvar); - } while (dd->reordered == 1); - if (res == NULL) { + do { + dd->reordered = 0; + res = cuddUniqueInterZdd(dd, dd->invpermZ[j], zvar, zvar); + } while (dd->reordered == 1); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd,zvar); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDerefZdd(dd,zvar); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDerefZdd(dd,zvar); - zvar = res; + zvar = res; } cuddDeref(zvar); return(zvar); @@ -500,75 +528,75 @@ Cudd_zddVarsFromBddVars( if (multiplicity < 1) return(0); allnew = dd->sizeZ == 0; if (dd->size * multiplicity > dd->sizeZ) { - res = cuddResizeTableZdd(dd,dd->size * multiplicity - 1); - if (res == 0) return(0); + res = cuddResizeTableZdd(dd,dd->size * multiplicity - 1); + if (res == 0) return(0); } /* Impose the order of the BDD variables to the ZDD variables. */ if (allnew) { - for (i = 0; i < dd->size; i++) { - for (j = 0; j < multiplicity; j++) { - dd->permZ[i * multiplicity + j] = - dd->perm[i] * multiplicity + j; - dd->invpermZ[dd->permZ[i * multiplicity + j]] = - i * multiplicity + j; + for (i = 0; i < dd->size; i++) { + for (j = 0; j < multiplicity; j++) { + dd->permZ[i * multiplicity + j] = + dd->perm[i] * multiplicity + j; + dd->invpermZ[dd->permZ[i * multiplicity + j]] = + i * multiplicity + j; + } + } + for (i = 0; i < dd->sizeZ; i++) { + dd->univ[i]->index = dd->invpermZ[i]; } - } - for (i = 0; i < dd->sizeZ; i++) { - dd->univ[i]->index = dd->invpermZ[i]; - } } else { - permutation = ABC_ALLOC(int,dd->sizeZ); - if (permutation == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - for (i = 0; i < dd->size; i++) { - for (j = 0; j < multiplicity; j++) { - permutation[i * multiplicity + j] = - dd->invperm[i] * multiplicity + j; + permutation = ABC_ALLOC(int,dd->sizeZ); + if (permutation == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - } - for (i = dd->size * multiplicity; i < dd->sizeZ; i++) { - permutation[i] = i; - } - res = Cudd_zddShuffleHeap(dd, permutation); - ABC_FREE(permutation); - if (res == 0) return(0); + for (i = 0; i < dd->size; i++) { + for (j = 0; j < multiplicity; j++) { + permutation[i * multiplicity + j] = + dd->invperm[i] * multiplicity + j; + } + } + for (i = dd->size * multiplicity; i < dd->sizeZ; i++) { + permutation[i] = i; + } + res = Cudd_zddShuffleHeap(dd, permutation); + ABC_FREE(permutation); + if (res == 0) return(0); } /* Copy and expand the variable group tree if it exists. */ if (dd->treeZ != NULL) { - Cudd_FreeZddTree(dd); + Cudd_FreeZddTree(dd); } if (dd->tree != NULL) { - dd->treeZ = Mtr_CopyTree(dd->tree, multiplicity); - if (dd->treeZ == NULL) return(0); + dd->treeZ = Mtr_CopyTree(dd->tree, multiplicity); + if (dd->treeZ == NULL) return(0); } else if (multiplicity > 1) { - dd->treeZ = Mtr_InitGroupTree(0, dd->sizeZ); - if (dd->treeZ == NULL) return(0); - dd->treeZ->index = dd->invpermZ[0]; + dd->treeZ = Mtr_InitGroupTree(0, dd->sizeZ); + if (dd->treeZ == NULL) return(0); + dd->treeZ->index = dd->invpermZ[0]; } /* Create groups for the ZDD variables derived from the same BDD variable. */ if (multiplicity > 1) { - char *vmask, *lmask; + char *vmask, *lmask; - vmask = ABC_ALLOC(char, dd->size); - if (vmask == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - lmask = ABC_ALLOC(char, dd->size); - if (lmask == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - for (i = 0; i < dd->size; i++) { - vmask[i] = lmask[i] = 0; - } - res = addMultiplicityGroups(dd,dd->treeZ,multiplicity,vmask,lmask); - ABC_FREE(vmask); - ABC_FREE(lmask); - if (res == 0) return(0); + vmask = ABC_ALLOC(char, dd->size); + if (vmask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + lmask = ABC_ALLOC(char, dd->size); + if (lmask == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (i = 0; i < dd->size; i++) { + vmask[i] = lmask[i] = 0; + } + res = addMultiplicityGroups(dd,dd->treeZ,multiplicity,vmask,lmask); + ABC_FREE(vmask); + ABC_FREE(lmask); + if (res == 0) return(0); } return(1); @@ -644,7 +672,7 @@ Cudd_AutodynEnable( { unique->autoDyn = 1; if (method != CUDD_REORDER_SAME) { - unique->autoMethod = method; + unique->autoMethod = method; } #ifndef DD_NO_DEATH_ROW /* If reordering is enabled, using the death row causes too many @@ -654,10 +682,10 @@ Cudd_AutodynEnable( unique->deathRowDepth = 1; unique->deadMask = unique->deathRowDepth - 1; if ((unsigned) unique->nextDead > unique->deadMask) { - unique->nextDead = 0; + unique->nextDead = 0; } unique->deathRow = ABC_REALLOC(DdNodePtr, unique->deathRow, - unique->deathRowDepth); + unique->deathRowDepth); #endif return; @@ -735,7 +763,7 @@ Cudd_AutodynEnableZdd( { unique->autoDynZ = 1; if (method != CUDD_REORDER_SAME) { - unique->autoMethodZ = method; + unique->autoMethodZ = method; } return; @@ -984,7 +1012,7 @@ Cudd_ReadZddOne( int i) { if (i < 0) - return(NULL); + return(NULL); return(i < dd->sizeZ ? dd->univ[i] : DD_ONE(dd)); } /* end of Cudd_ReadZddOne */ @@ -1153,7 +1181,7 @@ Cudd_ReadCacheUsedSlots( int i; for (i = 0; i < slots; i++) { - used += cache[i].h != 0; + used += cache[i].h != 0; } return((double)used / (double) dd->cacheSlots); @@ -1177,7 +1205,7 @@ Cudd_ReadCacheLookUps( DdManager * dd) { return(dd->cacheHits + dd->cacheMisses + - dd->totCachehits + dd->totCacheMisses); + dd->totCachehits + dd->totCacheMisses); } /* end of Cudd_ReadCacheLookUps */ @@ -1319,9 +1347,9 @@ Cudd_SetLooseUpTo( unsigned int lut) { if (lut == 0) { - long datalimit = getSoftDataLimit(); - lut = (unsigned int) (datalimit / (sizeof(DdNode) * - DD_MAX_LOOSE_FRACTION)); + unsigned long datalimit = getSoftDataLimit(); + lut = (unsigned int) (datalimit / (sizeof(DdNode) * + DD_MAX_LOOSE_FRACTION)); } dd->looseUpTo = lut; @@ -1389,9 +1417,9 @@ Cudd_SetMaxCacheHard( unsigned int mc) { if (mc == 0) { - long datalimit = getSoftDataLimit(); - mc = (unsigned int) (datalimit / (sizeof(DdCache) * - DD_MAX_CACHE_FRACTION)); + unsigned long datalimit = getSoftDataLimit(); + mc = (unsigned int) (datalimit / (sizeof(DdCache) * + DD_MAX_CACHE_FRACTION)); } dd->maxCacheHard = mc; @@ -1485,38 +1513,38 @@ Cudd_ReadUsedSlots( /* Scan each BDD/ADD subtable. */ for (i = 0; i < size; i++) { - subtable = &(dd->subtables[i]); - nodelist = subtable->nodelist; - for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - if (node != sentinel) { - used++; + subtable = &(dd->subtables[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != sentinel) { + used++; + } } } - } /* Scan the ZDD subtables. */ size = dd->sizeZ; for (i = 0; i < size; i++) { - subtable = &(dd->subtableZ[i]); - nodelist = subtable->nodelist; - for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - if (node != NULL) { - used++; + subtable = &(dd->subtableZ[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + used++; + } } } - } /* Constant table. */ subtable = &(dd->constants); nodelist = subtable->nodelist; for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - if (node != NULL) { - used++; - } + node = nodelist[j]; + if (node != NULL) { + used++; + } } return((double)used / (double) dd->slots); @@ -1551,31 +1579,31 @@ Cudd_ExpectedUsedSlots( /* To each subtable we apply the corollary to Theorem 8.5 (occupancy ** distribution) from Sedgewick and Flajolet's Analysis of Algorithms. - ** The corollary says that for a a table with M buckets and a load ratio + ** The corollary says that for a table with M buckets and a load ratio ** of r, the expected number of empty buckets is asymptotically given ** by M * exp(-r). */ /* Scan each BDD/ADD subtable. */ for (i = 0; i < size; i++) { - subtable = &(dd->subtables[i]); - empty += (double) subtable->slots * - exp(-(double) subtable->keys / (double) subtable->slots); + subtable = &(dd->subtables[i]); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); } /* Scan the ZDD subtables. */ size = dd->sizeZ; for (i = 0; i < size; i++) { - subtable = &(dd->subtableZ[i]); - empty += (double) subtable->slots * - exp(-(double) subtable->keys / (double) subtable->slots); + subtable = &(dd->subtableZ[i]); + empty += (double) subtable->slots * + exp(-(double) subtable->keys / (double) subtable->slots); } /* Constant table. */ subtable = &(dd->constants); empty += (double) subtable->slots * - exp(-(double) subtable->keys / (double) subtable->slots); + exp(-(double) subtable->keys / (double) subtable->slots); return(1.0 - empty / (double) dd->slots); @@ -2126,7 +2154,7 @@ Cudd_SetTree( MtrNode * tree) { if (dd->tree != NULL) { - Mtr_FreeTree(dd->tree); + Mtr_FreeTree(dd->tree); } dd->tree = tree; if (tree == NULL) return; @@ -2153,8 +2181,8 @@ Cudd_FreeTree( DdManager * dd) { if (dd->tree != NULL) { - Mtr_FreeTree(dd->tree); - dd->tree = NULL; + Mtr_FreeTree(dd->tree); + dd->tree = NULL; } return; @@ -2198,7 +2226,7 @@ Cudd_SetZddTree( MtrNode * tree) { if (dd->treeZ != NULL) { - Mtr_FreeTree(dd->treeZ); + Mtr_FreeTree(dd->treeZ); } dd->treeZ = tree; if (tree == NULL) return; @@ -2225,8 +2253,8 @@ Cudd_FreeZddTree( DdManager * dd) { if (dd->treeZ != NULL) { - Mtr_FreeTree(dd->treeZ); - dd->treeZ = NULL; + Mtr_FreeTree(dd->treeZ); + dd->treeZ = NULL; } return; @@ -2884,7 +2912,7 @@ Cudd_SetNumberXovers( SeeAlso [] ******************************************************************************/ -long +unsigned long Cudd_ReadMemoryInUse( DdManager * dd) { @@ -2917,78 +2945,80 @@ Cudd_PrintInfo( retval = fprintf(fp,"**** CUDD modifiable parameters ****\n"); if (retval == EOF) return(0); retval = fprintf(fp,"Hard limit for cache size: %u\n", - Cudd_ReadMaxCacheHard(dd)); + Cudd_ReadMaxCacheHard(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Cache hit threshold for resizing: %u%%\n", - Cudd_ReadMinHit(dd)); + Cudd_ReadMinHit(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Garbage collection enabled: %s\n", - Cudd_GarbageCollectionEnabled(dd) ? "yes" : "no"); + Cudd_GarbageCollectionEnabled(dd) ? "yes" : "no"); if (retval == EOF) return(0); retval = fprintf(fp,"Limit for fast unique table growth: %u\n", - Cudd_ReadLooseUpTo(dd)); + Cudd_ReadLooseUpTo(dd)); if (retval == EOF) return(0); retval = fprintf(fp, - "Maximum number of variables sifted per reordering: %d\n", - Cudd_ReadSiftMaxVar(dd)); + "Maximum number of variables sifted per reordering: %d\n", + Cudd_ReadSiftMaxVar(dd)); if (retval == EOF) return(0); retval = fprintf(fp, - "Maximum number of variable swaps per reordering: %d\n", - Cudd_ReadSiftMaxSwap(dd)); + "Maximum number of variable swaps per reordering: %d\n", + Cudd_ReadSiftMaxSwap(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Maximum growth while sifting a variable: %g\n", - Cudd_ReadMaxGrowth(dd)); + Cudd_ReadMaxGrowth(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Dynamic reordering of BDDs enabled: %s\n", - Cudd_ReorderingStatus(dd,&autoMethod) ? "yes" : "no"); + Cudd_ReorderingStatus(dd,&autoMethod) ? "yes" : "no"); if (retval == EOF) return(0); - retval = fprintf(fp,"Default BDD reordering method: %d\n", autoMethod); + retval = fprintf(fp,"Default BDD reordering method: %d\n", + (int) autoMethod); if (retval == EOF) return(0); retval = fprintf(fp,"Dynamic reordering of ZDDs enabled: %s\n", - Cudd_ReorderingStatusZdd(dd,&autoMethodZ) ? "yes" : "no"); + Cudd_ReorderingStatusZdd(dd,&autoMethodZ) ? "yes" : "no"); if (retval == EOF) return(0); - retval = fprintf(fp,"Default ZDD reordering method: %d\n", autoMethodZ); + retval = fprintf(fp,"Default ZDD reordering method: %d\n", + (int) autoMethodZ); if (retval == EOF) return(0); retval = fprintf(fp,"Realignment of ZDDs to BDDs enabled: %s\n", - Cudd_zddRealignmentEnabled(dd) ? "yes" : "no"); + Cudd_zddRealignmentEnabled(dd) ? "yes" : "no"); if (retval == EOF) return(0); retval = fprintf(fp,"Realignment of BDDs to ZDDs enabled: %s\n", - Cudd_bddRealignmentEnabled(dd) ? "yes" : "no"); + Cudd_bddRealignmentEnabled(dd) ? "yes" : "no"); if (retval == EOF) return(0); retval = fprintf(fp,"Dead nodes counted in triggering reordering: %s\n", - Cudd_DeadAreCounted(dd) ? "yes" : "no"); + Cudd_DeadAreCounted(dd) ? "yes" : "no"); if (retval == EOF) return(0); retval = fprintf(fp,"Group checking criterion: %d\n", - Cudd_ReadGroupcheck(dd)); + (int) Cudd_ReadGroupcheck(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Recombination threshold: %d\n", Cudd_ReadRecomb(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Symmetry violation threshold: %d\n", - Cudd_ReadSymmviolation(dd)); + Cudd_ReadSymmviolation(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Arc violation threshold: %d\n", - Cudd_ReadArcviolation(dd)); + Cudd_ReadArcviolation(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"GA population size: %d\n", - Cudd_ReadPopulationSize(dd)); + Cudd_ReadPopulationSize(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Number of crossovers for GA: %d\n", - Cudd_ReadNumberXovers(dd)); + Cudd_ReadNumberXovers(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Next reordering threshold: %u\n", - Cudd_ReadNextReordering(dd)); + Cudd_ReadNextReordering(dd)); if (retval == EOF) return(0); /* Non-modifiable parameters. */ retval = fprintf(fp,"**** CUDD non-modifiable parameters ****\n"); if (retval == EOF) return(0); - retval = fprintf(fp,"Memory in use: %ld\n", Cudd_ReadMemoryInUse(dd)); + retval = fprintf(fp,"Memory in use: %lu\n", Cudd_ReadMemoryInUse(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Peak number of nodes: %ld\n", - Cudd_ReadPeakNodeCount(dd)); + Cudd_ReadPeakNodeCount(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Peak number of live nodes: %d\n", - Cudd_ReadPeakLiveNodeCount(dd)); + Cudd_ReadPeakLiveNodeCount(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Number of BDD variables: %d\n", dd->size); if (retval == EOF) return(0); @@ -2997,36 +3027,36 @@ Cudd_PrintInfo( retval = fprintf(fp,"Number of cache entries: %u\n", dd->cacheSlots); if (retval == EOF) return(0); retval = fprintf(fp,"Number of cache look-ups: %.0f\n", - Cudd_ReadCacheLookUps(dd)); + Cudd_ReadCacheLookUps(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Number of cache hits: %.0f\n", - Cudd_ReadCacheHits(dd)); + Cudd_ReadCacheHits(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Number of cache insertions: %.0f\n", - dd->cacheinserts); + dd->cacheinserts); if (retval == EOF) return(0); retval = fprintf(fp,"Number of cache collisions: %.0f\n", - dd->cachecollisions); + dd->cachecollisions); if (retval == EOF) return(0); retval = fprintf(fp,"Number of cache deletions: %.0f\n", - dd->cachedeletions); + dd->cachedeletions); if (retval == EOF) return(0); retval = cuddCacheProfile(dd,fp); if (retval == 0) return(0); retval = fprintf(fp,"Soft limit for cache size: %u\n", - Cudd_ReadMaxCache(dd)); + Cudd_ReadMaxCache(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Number of buckets in unique table: %u\n", dd->slots); if (retval == EOF) return(0); retval = fprintf(fp,"Used buckets in unique table: %.2f%% (expected %.2f%%)\n", - 100.0 * Cudd_ReadUsedSlots(dd), - 100.0 * Cudd_ExpectedUsedSlots(dd)); + 100.0 * Cudd_ReadUsedSlots(dd), + 100.0 * Cudd_ExpectedUsedSlots(dd)); if (retval == EOF) return(0); #ifdef DD_UNIQUE_PROFILE retval = fprintf(fp,"Unique lookups: %.0f\n", dd->uniqueLookUps); if (retval == EOF) return(0); retval = fprintf(fp,"Unique links: %.0f (%g per lookup)\n", - dd->uniqueLinks, dd->uniqueLinks / dd->uniqueLookUps); + dd->uniqueLinks, dd->uniqueLinks / dd->uniqueLookUps); if (retval == EOF) return(0); #endif retval = fprintf(fp,"Number of BDD and ADD nodes: %u\n", dd->keys); @@ -3038,36 +3068,36 @@ Cudd_PrintInfo( retval = fprintf(fp,"Number of dead ZDD nodes: %u\n", dd->deadZ); if (retval == EOF) return(0); retval = fprintf(fp,"Total number of nodes allocated: %.0f\n", - dd->allocated); + dd->allocated); if (retval == EOF) return(0); retval = fprintf(fp,"Total number of nodes reclaimed: %.0f\n", - dd->reclaimed); + dd->reclaimed); if (retval == EOF) return(0); -#if DD_STATS +#ifdef DD_STATS retval = fprintf(fp,"Nodes freed: %.0f\n", dd->nodesFreed); if (retval == EOF) return(0); retval = fprintf(fp,"Nodes dropped: %.0f\n", dd->nodesDropped); if (retval == EOF) return(0); #endif -#if DD_COUNT +#ifdef DD_COUNT retval = fprintf(fp,"Number of recursive calls: %.0f\n", - Cudd_ReadRecursiveCalls(dd)); + Cudd_ReadRecursiveCalls(dd)); if (retval == EOF) return(0); #endif retval = fprintf(fp,"Garbage collections so far: %d\n", - Cudd_ReadGarbageCollections(dd)); + Cudd_ReadGarbageCollections(dd)); if (retval == EOF) return(0); retval = fprintf(fp,"Time for garbage collection: %.2f sec\n", - ((double)Cudd_ReadGarbageCollectionTime(dd)/1000.0)); + ((double)Cudd_ReadGarbageCollectionTime(dd)/1000.0)); if (retval == EOF) return(0); retval = fprintf(fp,"Reorderings so far: %d\n", dd->reorderings); if (retval == EOF) return(0); retval = fprintf(fp,"Time for reordering: %.2f sec\n", - ((double)Cudd_ReadReorderingTime(dd)/1000.0)); + ((double)Cudd_ReadReorderingTime(dd)/1000.0)); if (retval == EOF) return(0); -#if DD_COUNT +#ifdef DD_COUNT retval = fprintf(fp,"Node swaps in reordering: %.0f\n", - Cudd_ReadSwapSteps(dd)); + Cudd_ReadSwapSteps(dd)); if (retval == EOF) return(0); #endif @@ -3097,8 +3127,8 @@ Cudd_ReadPeakNodeCount( DdNodePtr *scan = dd->memoryList; while (scan != NULL) { - count += DD_MEM_CHUNK; - scan = (DdNodePtr *) *scan; + count += DD_MEM_CHUNK; + scan = (DdNodePtr *) *scan; } return(count); @@ -3125,7 +3155,7 @@ Cudd_ReadPeakLiveNodeCount( unsigned int live = dd->keys - dd->dead; if (live > dd->peakLiveNodes) { - dd->peakLiveNodes = live; + dd->peakLiveNodes = live; } return((int)dd->peakLiveNodes); @@ -3157,13 +3187,13 @@ Cudd_ReadNodeCount( cuddClearDeathRow(dd); #endif - count = dd->keys - dd->dead; + count = (long) (dd->keys - dd->dead); /* Count isolated projection functions. Their number is subtracted ** from the node count because they are not part of the BDDs. */ for (i=0; i < dd->size; i++) { - if (dd->vars[i]->ref == 1) count--; + if (dd->vars[i]->ref == 1) count--; } /* Subtract from the count the unused constants. */ if (DD_ZERO(dd)->ref == 1) count--; @@ -3192,7 +3222,7 @@ long Cudd_zddReadNodeCount( DdManager * dd) { - return(dd->keysZ - dd->deadZ + 2); + return((long)(dd->keysZ - dd->deadZ + 2)); } /* end of Cudd_zddReadNodeCount */ @@ -3214,43 +3244,43 @@ Cudd_zddReadNodeCount( int Cudd_AddHook( DdManager * dd, - int (*f)(DdManager *, char *, void *) , + DD_HFP f, Cudd_HookType where) { DdHook **hook, *nextHook, *newHook; switch (where) { case CUDD_PRE_GC_HOOK: - hook = &(dd->preGCHook); - break; + hook = &(dd->preGCHook); + break; case CUDD_POST_GC_HOOK: - hook = &(dd->postGCHook); - break; + hook = &(dd->postGCHook); + break; case CUDD_PRE_REORDERING_HOOK: - hook = &(dd->preReorderingHook); - break; + hook = &(dd->preReorderingHook); + break; case CUDD_POST_REORDERING_HOOK: - hook = &(dd->postReorderingHook); - break; + hook = &(dd->postReorderingHook); + break; default: - return(0); + return(0); } /* Scan the list and find whether the function is already there. ** If so, just return. */ nextHook = *hook; while (nextHook != NULL) { - if (nextHook->f == f) { - return(2); - } - hook = &(nextHook->next); - nextHook = nextHook->next; + if (nextHook->f == f) { + return(2); + } + hook = &(nextHook->next); + nextHook = nextHook->next; } /* The function was not in the list. Create a new item and append it ** to the end of the list. */ newHook = ABC_ALLOC(DdHook,1); if (newHook == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } newHook->next = NULL; newHook->f = f; @@ -3276,36 +3306,36 @@ Cudd_AddHook( int Cudd_RemoveHook( DdManager * dd, - int (*f)(DdManager *, char *, void *) , + DD_HFP f, Cudd_HookType where) { DdHook **hook, *nextHook; switch (where) { case CUDD_PRE_GC_HOOK: - hook = &(dd->preGCHook); - break; + hook = &(dd->preGCHook); + break; case CUDD_POST_GC_HOOK: - hook = &(dd->postGCHook); - break; + hook = &(dd->postGCHook); + break; case CUDD_PRE_REORDERING_HOOK: - hook = &(dd->preReorderingHook); - break; + hook = &(dd->preReorderingHook); + break; case CUDD_POST_REORDERING_HOOK: - hook = &(dd->postReorderingHook); - break; + hook = &(dd->postReorderingHook); + break; default: - return(0); + return(0); } nextHook = *hook; while (nextHook != NULL) { - if (nextHook->f == f) { - *hook = nextHook->next; - ABC_FREE(nextHook); - return(1); - } - hook = &(nextHook->next); - nextHook = nextHook->next; + if (nextHook->f == f) { + *hook = nextHook->next; + ABC_FREE(nextHook); + return(1); + } + hook = &(nextHook->next); + nextHook = nextHook->next; } return(0); @@ -3329,33 +3359,33 @@ Cudd_RemoveHook( int Cudd_IsInHook( DdManager * dd, - int (*f)(DdManager *, char *, void *) , + DD_HFP f, Cudd_HookType where) { DdHook *hook; switch (where) { case CUDD_PRE_GC_HOOK: - hook = dd->preGCHook; - break; + hook = dd->preGCHook; + break; case CUDD_POST_GC_HOOK: - hook = dd->postGCHook; - break; + hook = dd->postGCHook; + break; case CUDD_PRE_REORDERING_HOOK: - hook = dd->preReorderingHook; - break; + hook = dd->preReorderingHook; + break; case CUDD_POST_REORDERING_HOOK: - hook = dd->postReorderingHook; - break; + hook = dd->postReorderingHook; + break; default: - return(0); + return(0); } /* Scan the list and find whether the function is already there. */ while (hook != NULL) { - if (hook->f == f) { - return(1); - } - hook = hook->next; + if (hook->f == f) { + return(1); + } + hook = hook->next; } return(0); @@ -3378,7 +3408,7 @@ Cudd_IsInHook( int Cudd_StdPreReordHook( DdManager *dd, - char *str, + const char *str, void *data) { Cudd_ReorderingType method = (Cudd_ReorderingType) (ptruint) data; @@ -3394,60 +3424,60 @@ Cudd_StdPreReordHook( case CUDD_REORDER_WINDOW3_CONV: case CUDD_REORDER_WINDOW4_CONV: case CUDD_REORDER_LINEAR_CONVERGE: - retval = fprintf(dd->out,"converging "); - if (retval == EOF) return(0); - break; + retval = fprintf(dd->out,"converging "); + if (retval == EOF) return(0); + break; default: - break; + break; } switch (method) { case CUDD_REORDER_RANDOM: case CUDD_REORDER_RANDOM_PIVOT: - retval = fprintf(dd->out,"random"); - break; + retval = fprintf(dd->out,"random"); + break; case CUDD_REORDER_SIFT: case CUDD_REORDER_SIFT_CONVERGE: - retval = fprintf(dd->out,"sifting"); - break; + retval = fprintf(dd->out,"sifting"); + break; case CUDD_REORDER_SYMM_SIFT: case CUDD_REORDER_SYMM_SIFT_CONV: - retval = fprintf(dd->out,"symmetric sifting"); - break; + retval = fprintf(dd->out,"symmetric sifting"); + break; case CUDD_REORDER_LAZY_SIFT: - retval = fprintf(dd->out,"lazy sifting"); - break; + retval = fprintf(dd->out,"lazy sifting"); + break; case CUDD_REORDER_GROUP_SIFT: case CUDD_REORDER_GROUP_SIFT_CONV: - retval = fprintf(dd->out,"group sifting"); - break; + retval = fprintf(dd->out,"group sifting"); + break; case CUDD_REORDER_WINDOW2: case CUDD_REORDER_WINDOW3: case CUDD_REORDER_WINDOW4: case CUDD_REORDER_WINDOW2_CONV: case CUDD_REORDER_WINDOW3_CONV: case CUDD_REORDER_WINDOW4_CONV: - retval = fprintf(dd->out,"window"); - break; + retval = fprintf(dd->out,"window"); + break; case CUDD_REORDER_ANNEALING: - retval = fprintf(dd->out,"annealing"); - break; + retval = fprintf(dd->out,"annealing"); + break; case CUDD_REORDER_GENETIC: - retval = fprintf(dd->out,"genetic"); - break; + retval = fprintf(dd->out,"genetic"); + break; case CUDD_REORDER_LINEAR: case CUDD_REORDER_LINEAR_CONVERGE: - retval = fprintf(dd->out,"linear sifting"); - break; + retval = fprintf(dd->out,"linear sifting"); + break; case CUDD_REORDER_EXACT: - retval = fprintf(dd->out,"exact"); - break; + retval = fprintf(dd->out,"exact"); + break; default: - return(0); + return(0); } if (retval == EOF) return(0); retval = fprintf(dd->out,": from %ld to ... ", strcmp(str, "BDD") == 0 ? - Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd)); + Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd)); if (retval == EOF) return(0); fflush(dd->out); return(1); @@ -3471,7 +3501,7 @@ Cudd_StdPreReordHook( int Cudd_StdPostReordHook( DdManager *dd, - char *str, + const char *str, void *data) { long initialTime = (long) data; @@ -3480,8 +3510,8 @@ Cudd_StdPostReordHook( double totalTimeSec = (double)(finalTime - initialTime) / 1000.0; retval = fprintf(dd->out,"%ld nodes in %g sec\n", strcmp(str, "BDD") == 0 ? - Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd), - totalTimeSec); + Cudd_ReadNodeCount(dd) : Cudd_zddReadNodeCount(dd), + totalTimeSec); if (retval == EOF) return(0); retval = fflush(dd->out); if (retval == EOF) return(0); @@ -3508,10 +3538,10 @@ Cudd_EnableReorderingReporting( DdManager *dd) { if (!Cudd_AddHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { - return(0); + return(0); } if (!Cudd_AddHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { - return(0); + return(0); } return(1); @@ -3536,10 +3566,10 @@ Cudd_DisableReorderingReporting( DdManager *dd) { if (!Cudd_RemoveHook(dd, Cudd_StdPreReordHook, CUDD_PRE_REORDERING_HOOK)) { - return(0); + return(0); } if (!Cudd_RemoveHook(dd, Cudd_StdPostReordHook, CUDD_POST_REORDERING_HOOK)) { - return(0); + return(0); } return(1); @@ -3822,7 +3852,7 @@ Cudd_SetMaxLive( SeeAlso [Cudd_SetMaxMemory] ******************************************************************************/ -long +unsigned long Cudd_ReadMaxMemory( DdManager *dd) { @@ -3846,7 +3876,7 @@ Cudd_ReadMaxMemory( void Cudd_SetMaxMemory( DdManager *dd, - long maxMemory) + unsigned long maxMemory) { dd->maxmemhard = maxMemory; @@ -4145,7 +4175,7 @@ Cudd_bddSetVarToBeGrouped( { if (index >= dd->size || index < 0) return(0); if (dd->subtables[dd->perm[index]].varToBeGrouped <= CUDD_LAZY_SOFT_GROUP) { - dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_SOFT_GROUP; + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_SOFT_GROUP; } return(1); @@ -4196,8 +4226,8 @@ Cudd_bddResetVarToBeGrouped( { if (index >= dd->size || index < 0) return(0); if (dd->subtables[dd->perm[index]].varToBeGrouped <= - CUDD_LAZY_SOFT_GROUP) { - dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_NONE; + CUDD_LAZY_SOFT_GROUP) { + dd->subtables[dd->perm[index]].varToBeGrouped = CUDD_LAZY_NONE; } return(1); @@ -4223,9 +4253,9 @@ Cudd_bddIsVarToBeGrouped( { if (index >= dd->size || index < 0) return(-1); if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP) - return(0); + return(0); else - return(dd->subtables[dd->perm[index]].varToBeGrouped); + return(dd->subtables[dd->perm[index]].varToBeGrouped); } /* end of Cudd_bddIsVarToBeGrouped */ @@ -4300,7 +4330,7 @@ Cudd_bddIsVarHardGroup( { if (index >= dd->size || index < 0) return(-1); if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_HARD_GROUP) - return(1); + return(1); return(0); } /* end of Cudd_bddIsVarToBeGrouped */ @@ -4334,11 +4364,11 @@ fixVarTree( { treenode->index = treenode->low; treenode->low = ((int) treenode->index < size) ? - perm[treenode->index] : treenode->index; + perm[treenode->index] : treenode->index; if (treenode->child != NULL) - fixVarTree(treenode->child, perm, size); + fixVarTree(treenode->child, perm, size); if (treenode->younger != NULL) - fixVarTree(treenode->younger, perm, size); + fixVarTree(treenode->younger, perm, size); return; } /* end of fixVarTree */ @@ -4382,33 +4412,34 @@ addMultiplicityGroups( MtrNode *auxnode = treenode; while (auxnode != NULL) { - if (auxnode->child != NULL) { - addMultiplicityGroups(dd,auxnode->child,multiplicity,vmask,lmask); - } - /* Build remaining groups. */ - startV = dd->permZ[auxnode->index] / multiplicity; - startL = auxnode->low / multiplicity; - stopV = startV + auxnode->size / multiplicity; - /* Walk down vmask starting at startV and build missing groups. */ - for (i = startV, j = startL; i < stopV; i++) { - if (vmask[i] == 0) { - MtrNode *node; - while (lmask[j] == 1) j++; - node = Mtr_MakeGroup(auxnode, j * multiplicity, multiplicity, - MTR_FIXED); - if (node == NULL) { - return(0); + if (auxnode->child != NULL) { + addMultiplicityGroups(dd,auxnode->child,multiplicity,vmask,lmask); } - node->index = dd->invpermZ[i * multiplicity]; - vmask[i] = 1; - lmask[j] = 1; + /* Build remaining groups. */ + startV = dd->permZ[auxnode->index] / multiplicity; + startL = auxnode->low / multiplicity; + stopV = startV + auxnode->size / multiplicity; + /* Walk down vmask starting at startV and build missing groups. */ + for (i = startV, j = startL; i < stopV; i++) { + if (vmask[i] == 0) { + MtrNode *node; + while (lmask[j] == 1) j++; + node = Mtr_MakeGroup(auxnode, j * multiplicity, multiplicity, + MTR_FIXED); + if (node == NULL) { + return(0); + } + node->index = dd->invpermZ[i * multiplicity]; + vmask[i] = 1; + lmask[j] = 1; + } } - } - auxnode = auxnode->younger; + auxnode = auxnode->younger; } return(1); } /* end of addMultiplicityGroups */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddAddAbs.c b/src/bdd/cudd/cuddAddAbs.c index 40d3222b..f420f99e 100644 --- a/src/bdd/cudd/cuddAddAbs.c +++ b/src/bdd/cudd/cuddAddAbs.c @@ -7,37 +7,65 @@ Synopsis [Quantification functions for ADDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_addExistAbstract() - <li> Cudd_addUnivAbstract() - <li> Cudd_addOrAbstract() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddAddExistAbstractRecur() - <li> cuddAddUnivAbstractRecur() - <li> cuddAddOrAbstractRecur() - </ul> - Static procedures included in this module: - <ul> - <li> addCheckPositiveCube() - </ul>] + <ul> + <li> Cudd_addExistAbstract() + <li> Cudd_addUnivAbstract() + <li> Cudd_addOrAbstract() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddAddExistAbstractRecur() + <li> cuddAddUnivAbstractRecur() + <li> cuddAddOrAbstractRecur() + </ul> + Static procedures included in this module: + <ul> + <li> addCheckPositiveCube() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -58,10 +86,10 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddAbs.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddAbs.c,v 1.15 2004/08/13 18:04:45 fabio Exp $"; #endif -static DdNode *two; +static DdNode *two; /*---------------------------------------------------------------------------*/ /* Macro declarations */ @@ -74,7 +102,7 @@ static DdNode *two; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int addCheckPositiveCube ARGS((DdManager *manager, DdNode *cube)); +static int addCheckPositiveCube (DdManager *manager, DdNode *cube); /**AutomaticEnd***************************************************************/ @@ -115,13 +143,13 @@ Cudd_addExistAbstract( } do { - manager->reordered = 0; - res = cuddAddExistAbstractRecur(manager, f, cube); + manager->reordered = 0; + res = cuddAddExistAbstractRecur(manager, f, cube); } while (manager->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(manager,two); - return(NULL); + Cudd_RecursiveDeref(manager,two); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(manager,two); @@ -152,16 +180,16 @@ Cudd_addUnivAbstract( DdNode * f, DdNode * cube) { - DdNode *res; + DdNode *res; if (addCheckPositiveCube(manager, cube) == 0) { - (void) fprintf(manager->err,"Error: Can only abstract cubes"); - return(NULL); + (void) fprintf(manager->err,"Error: Can only abstract cubes"); + return(NULL); } do { - manager->reordered = 0; - res = cuddAddUnivAbstractRecur(manager, f, cube); + manager->reordered = 0; + res = cuddAddUnivAbstractRecur(manager, f, cube); } while (manager->reordered == 1); return(res); @@ -198,8 +226,8 @@ Cudd_addOrAbstract( } do { - manager->reordered = 0; - res = cuddAddOrAbstractRecur(manager, f, cube); + manager->reordered = 0; + res = cuddAddOrAbstractRecur(manager, f, cube); } while (manager->reordered == 1); return(res); @@ -230,38 +258,38 @@ cuddAddExistAbstractRecur( DdNode * f, DdNode * cube) { - DdNode *T, *E, *res, *res1, *res2, *zero; + DdNode *T, *E, *res, *res1, *res2, *zero; statLine(manager); zero = DD_ZERO(manager); - /* Cube is guaranteed to be a cube at this point. */ + /* Cube is guaranteed to be a cube at this point. */ if (f == zero || cuddIsConstant(cube)) { return(f); } /* Abstract a variable that does not appear in f => multiply by 2. */ if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { - res1 = cuddAddExistAbstractRecur(manager, f, cuddT(cube)); - if (res1 == NULL) return(NULL); - cuddRef(res1); - /* Use the "internal" procedure to be alerted in case of - ** dynamic reordering. If dynamic reordering occurs, we - ** have to abort the entire abstraction. - */ - res = cuddAddApplyRecur(manager,Cudd_addTimes,res1,two); - if (res == NULL) { + res1 = cuddAddExistAbstractRecur(manager, f, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + /* Use the "internal" procedure to be alerted in case of + ** dynamic reordering. If dynamic reordering occurs, we + ** have to abort the entire abstraction. + */ + res = cuddAddApplyRecur(manager,Cudd_addTimes,res1,two); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(manager,res1); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(manager,res1); - cuddDeref(res); + cuddDeref(res); return(res); } if ((res = cuddCacheLookup2(manager, Cudd_addExistAbstract, f, cube)) != NULL) { - return(res); + return(res); } T = cuddT(f); @@ -269,49 +297,49 @@ cuddAddExistAbstractRecur( /* If the two indices are the same, so are their levels. */ if (f->index == cube->index) { - res1 = cuddAddExistAbstractRecur(manager, T, cuddT(cube)); - if (res1 == NULL) return(NULL); + res1 = cuddAddExistAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); cuddRef(res1); - res2 = cuddAddExistAbstractRecur(manager, E, cuddT(cube)); - if (res2 == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } + res2 = cuddAddExistAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } cuddRef(res2); - res = cuddAddApplyRecur(manager, Cudd_addPlus, res1, res2); - if (res == NULL) { + res = cuddAddApplyRecur(manager, Cudd_addPlus, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(manager,res1); Cudd_RecursiveDeref(manager,res2); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); - cuddDeref(res); + cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); + cuddDeref(res); return(res); } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ - res1 = cuddAddExistAbstractRecur(manager, T, cube); - if (res1 == NULL) return(NULL); + res1 = cuddAddExistAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); cuddRef(res1); - res2 = cuddAddExistAbstractRecur(manager, E, cube); - if (res2 == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } + res2 = cuddAddExistAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } cuddRef(res2); - res = (res1 == res2) ? res1 : - cuddUniqueInter(manager, (int) f->index, res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - return(NULL); - } - cuddDeref(res1); - cuddDeref(res2); - cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addExistAbstract, f, cube, res); return(res); - } + } } /* end of cuddAddExistAbstractRecur */ @@ -335,7 +363,7 @@ cuddAddUnivAbstractRecur( DdNode * f, DdNode * cube) { - DdNode *T, *E, *res, *res1, *res2, *one, *zero; + DdNode *T, *E, *res, *res1, *res2, *one, *zero; statLine(manager); one = DD_ONE(manager); @@ -345,31 +373,31 @@ cuddAddUnivAbstractRecur( ** zero and one are the only constatnts c such that c*c=c. */ if (f == zero || f == one || cube == one) { - return(f); + return(f); } /* Abstract a variable that does not appear in f. */ if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { - res1 = cuddAddUnivAbstractRecur(manager, f, cuddT(cube)); - if (res1 == NULL) return(NULL); - cuddRef(res1); - /* Use the "internal" procedure to be alerted in case of - ** dynamic reordering. If dynamic reordering occurs, we - ** have to abort the entire abstraction. - */ - res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res1); - if (res == NULL) { + res1 = cuddAddUnivAbstractRecur(manager, f, cuddT(cube)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + /* Use the "internal" procedure to be alerted in case of + ** dynamic reordering. If dynamic reordering occurs, we + ** have to abort the entire abstraction. + */ + res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res1); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(manager,res1); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(manager,res1); - cuddDeref(res); - return(res); + cuddDeref(res); + return(res); } if ((res = cuddCacheLookup2(manager, Cudd_addUnivAbstract, f, cube)) != NULL) { - return(res); + return(res); } T = cuddT(f); @@ -377,47 +405,47 @@ cuddAddUnivAbstractRecur( /* If the two indices are the same, so are their levels. */ if (f->index == cube->index) { - res1 = cuddAddUnivAbstractRecur(manager, T, cuddT(cube)); - if (res1 == NULL) return(NULL); + res1 = cuddAddUnivAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); cuddRef(res1); - res2 = cuddAddUnivAbstractRecur(manager, E, cuddT(cube)); - if (res2 == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } + res2 = cuddAddUnivAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } cuddRef(res2); - res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res2); - if (res == NULL) { + res = cuddAddApplyRecur(manager, Cudd_addTimes, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(manager,res1); Cudd_RecursiveDeref(manager,res2); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); - cuddDeref(res); + cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); + cuddDeref(res); return(res); } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ - res1 = cuddAddUnivAbstractRecur(manager, T, cube); - if (res1 == NULL) return(NULL); + res1 = cuddAddUnivAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); cuddRef(res1); - res2 = cuddAddUnivAbstractRecur(manager, E, cube); - if (res2 == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } + res2 = cuddAddUnivAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } cuddRef(res2); - res = (res1 == res2) ? res1 : - cuddUniqueInter(manager, (int) f->index, res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - return(NULL); - } - cuddDeref(res1); - cuddDeref(res2); - cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addUnivAbstract, f, cube, res); return(res); } @@ -443,38 +471,24 @@ cuddAddOrAbstractRecur( DdNode * f, DdNode * cube) { - DdNode *T, *E, *res, *res1, *res2, *one; + DdNode *T, *E, *res, *res1, *res2, *one; statLine(manager); one = DD_ONE(manager); /* Cube is guaranteed to be a cube at this point. */ if (cuddIsConstant(f) || cube == one) { - return(f); + return(f); } /* Abstract a variable that does not appear in f. */ if (cuddI(manager,f->index) > cuddI(manager,cube->index)) { - res1 = cuddAddOrAbstractRecur(manager, f, cuddT(cube)); - if (res1 == NULL) return(NULL); - cuddRef(res1); - /* Use the "internal" procedure to be alerted in case of - ** dynamic reordering. If dynamic reordering occurs, we - ** have to abort the entire abstraction. - */ - res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res1); - if (res == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(manager,res1); - cuddDeref(res); - return(res); + res = cuddAddOrAbstractRecur(manager, f, cuddT(cube)); + return(res); } if ((res = cuddCacheLookup2(manager, Cudd_addOrAbstract, f, cube)) != NULL) { - return(res); + return(res); } T = cuddT(f); @@ -482,51 +496,51 @@ cuddAddOrAbstractRecur( /* If the two indices are the same, so are their levels. */ if (f->index == cube->index) { - res1 = cuddAddOrAbstractRecur(manager, T, cuddT(cube)); - if (res1 == NULL) return(NULL); + res1 = cuddAddOrAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); cuddRef(res1); - if (res1 != one) { - res2 = cuddAddOrAbstractRecur(manager, E, cuddT(cube)); - if (res2 == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } - cuddRef(res2); - res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - return(NULL); + if (res1 != one) { + res2 = cuddAddOrAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } + cuddRef(res2); + res = cuddAddApplyRecur(manager, Cudd_addOr, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + } else { + res = res1; } - cuddRef(res); - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - } else { - res = res1; - } - cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); - cuddDeref(res); + cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); + cuddDeref(res); return(res); } else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */ - res1 = cuddAddOrAbstractRecur(manager, T, cube); - if (res1 == NULL) return(NULL); + res1 = cuddAddOrAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); cuddRef(res1); - res2 = cuddAddOrAbstractRecur(manager, E, cube); - if (res2 == NULL) { - Cudd_RecursiveDeref(manager,res1); - return(NULL); - } + res2 = cuddAddOrAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_RecursiveDeref(manager,res1); + return(NULL); + } cuddRef(res2); - res = (res1 == res2) ? res1 : - cuddUniqueInter(manager, (int) f->index, res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(manager,res1); - Cudd_RecursiveDeref(manager,res2); - return(NULL); - } - cuddDeref(res1); - cuddDeref(res2); - cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); + res = (res1 == res2) ? res1 : + cuddUniqueInter(manager, (int) f->index, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(manager,res1); + Cudd_RecursiveDeref(manager,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + cuddCacheInsert2(manager, Cudd_addOrAbstract, f, cube, res); return(res); } @@ -567,5 +581,8 @@ addCheckPositiveCube( } /* end of addCheckPositiveCube */ + ABC_NAMESPACE_IMPL_END + + diff --git a/src/bdd/cudd/cuddAddApply.c b/src/bdd/cudd/cuddAddApply.c index 5bdc5773..7bea5871 100644 --- a/src/bdd/cudd/cuddAddApply.c +++ b/src/bdd/cudd/cuddAddApply.c @@ -7,47 +7,75 @@ Synopsis [Apply functions for ADDs and their operators.] Description [External procedures included in this module: - <ul> - <li> Cudd_addApply() - <li> Cudd_addMonadicApply() - <li> Cudd_addPlus() - <li> Cudd_addTimes() - <li> Cudd_addThreshold() - <li> Cudd_addSetNZ() - <li> Cudd_addDivide() - <li> Cudd_addMinus() - <li> Cudd_addMinimum() - <li> Cudd_addMaximum() - <li> Cudd_addOneZeroMaximum() - <li> Cudd_addDiff() - <li> Cudd_addAgreement() - <li> Cudd_addOr() - <li> Cudd_addNand() - <li> Cudd_addNor() - <li> Cudd_addXor() - <li> Cudd_addXnor() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddAddApplyRecur() - <li> cuddAddMonadicApplyRecur() - </ul>] + <ul> + <li> Cudd_addApply() + <li> Cudd_addMonadicApply() + <li> Cudd_addPlus() + <li> Cudd_addTimes() + <li> Cudd_addThreshold() + <li> Cudd_addSetNZ() + <li> Cudd_addDivide() + <li> Cudd_addMinus() + <li> Cudd_addMinimum() + <li> Cudd_addMaximum() + <li> Cudd_addOneZeroMaximum() + <li> Cudd_addDiff() + <li> Cudd_addAgreement() + <li> Cudd_addOr() + <li> Cudd_addNand() + <li> Cudd_addNor() + <li> Cudd_addXor() + <li> Cudd_addXnor() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddAddApplyRecur() + <li> cuddAddMonadicApplyRecur() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at Boulder. - The University of Colorado at Boulder makes no warranty about the - suitability of this software for any purpose. It is presented on an - AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -68,7 +96,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.18 2009/02/19 16:15:26 fabio Exp $"; #endif @@ -109,15 +137,15 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddApply.c,v 1.1.1.1 2003/02/24 22:23: DdNode * Cudd_addApply( DdManager * dd, - DdNode * (*op)(DdManager *, DdNode **, DdNode **), + DD_AOP op, DdNode * f, DdNode * g) { DdNode *res; do { - dd->reordered = 0; - res = cuddAddApplyRecur(dd,op,f,g); + dd->reordered = 0; + res = cuddAddApplyRecur(dd,op,f,g); } while (dd->reordered == 1); return(res); @@ -150,13 +178,13 @@ Cudd_addPlus( if (F == DD_ZERO(dd)) return(G); if (G == DD_ZERO(dd)) return(F); if (cuddIsConstant(F) && cuddIsConstant(G)) { - value = cuddV(F)+cuddV(G); - res = cuddUniqueConst(dd,value); - return(res); + value = cuddV(F)+cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); } if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -191,13 +219,13 @@ Cudd_addTimes( if (F == DD_ONE(dd)) return(G); if (G == DD_ONE(dd)) return(F); if (cuddIsConstant(F) && cuddIsConstant(G)) { - value = cuddV(F)*cuddV(G); - res = cuddUniqueConst(dd,value); - return(res); + value = cuddV(F)*cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); } if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -227,11 +255,11 @@ Cudd_addThreshold( F = *f; G = *g; if (F == G || F == DD_PLUS_INFINITY(dd)) return(F); if (cuddIsConstant(F) && cuddIsConstant(G)) { - if (cuddV(F) >= cuddV(G)) { - return(F); - } else { - return(DD_ZERO(dd)); - } + if (cuddV(F) >= cuddV(G)) { + return(F); + } else { + return(DD_ZERO(dd)); + } } return(NULL); @@ -296,9 +324,9 @@ Cudd_addDivide( if (F == DD_ZERO(dd)) return(DD_ZERO(dd)); if (G == DD_ONE(dd)) return(F); if (cuddIsConstant(F) && cuddIsConstant(G)) { - value = cuddV(F)/cuddV(G); - res = cuddUniqueConst(dd,value); - return(res); + value = cuddV(F)/cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); } return(NULL); @@ -332,9 +360,9 @@ Cudd_addMinus( if (F == DD_ZERO(dd)) return(cuddAddNegateRecur(dd,G)); if (G == DD_ZERO(dd)) return(F); if (cuddIsConstant(F) && cuddIsConstant(G)) { - value = cuddV(F)-cuddV(G); - res = cuddUniqueConst(dd,value); - return(res); + value = cuddV(F)-cuddV(G); + res = cuddUniqueConst(dd,value); + return(res); } return(NULL); @@ -371,15 +399,15 @@ Cudd_addMinimum( if (G == DD_MINUS_INFINITY(dd)) return(G); #endif if (cuddIsConstant(F) && cuddIsConstant(G)) { - if (cuddV(F) <= cuddV(G)) { - return(F); - } else { - return(G); - } + if (cuddV(F) <= cuddV(G)) { + return(F); + } else { + return(G); + } } if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -416,15 +444,15 @@ Cudd_addMaximum( if (G == DD_PLUS_INFINITY(dd)) return(G); #endif if (cuddIsConstant(F) && cuddIsConstant(G)) { - if (cuddV(F) >= cuddV(G)) { - return(F); - } else { - return(G); - } + if (cuddV(F) >= cuddV(G)) { + return(F); + } else { + return(G); + } } if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -453,13 +481,13 @@ Cudd_addOneZeroMaximum( if (*f == *g) return(DD_ZERO(dd)); if (*g == DD_PLUS_INFINITY(dd)) - return DD_ZERO(dd); + return DD_ZERO(dd); if (cuddIsConstant(*f) && cuddIsConstant(*g)) { - if (cuddV(*f) > cuddV(*g)) { - return(DD_ONE(dd)); - } else { - return(DD_ZERO(dd)); - } + if (cuddV(*f) > cuddV(*g)) { + return(DD_ONE(dd)); + } else { + return(DD_ZERO(dd)); + } } return(NULL); @@ -492,15 +520,15 @@ Cudd_addDiff( if (F == DD_PLUS_INFINITY(dd)) return(G); if (G == DD_PLUS_INFINITY(dd)) return(F); if (cuddIsConstant(F) && cuddIsConstant(G)) { - if (cuddV(F) != cuddV(G)) { + if (cuddV(F) != cuddV(G)) { if (cuddV(F) < cuddV(G)) { return(F); } else { return(G); } - } else { - return(DD_PLUS_INFINITY(dd)); - } + } else { + return(DD_PLUS_INFINITY(dd)); + } } return(NULL); @@ -563,8 +591,8 @@ Cudd_addOr( if (cuddIsConstant(G)) return(F); if (F == G) return(F); if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -595,8 +623,8 @@ Cudd_addNand( if (F == DD_ZERO(dd) || G == DD_ZERO(dd)) return(DD_ONE(dd)); if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -627,8 +655,8 @@ Cudd_addNor( if (F == DD_ONE(dd) || G == DD_ONE(dd)) return(DD_ZERO(dd)); if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ONE(dd)); if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -661,8 +689,8 @@ Cudd_addXor( if (G == DD_ONE(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd)); if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -695,8 +723,8 @@ Cudd_addXnor( if (G == DD_ZERO(dd) && F == DD_ZERO(dd)) return(DD_ONE(dd)); if (cuddIsConstant(F) && cuddIsConstant(G)) return(DD_ZERO(dd)); if (F > G) { /* swap f and g */ - *f = G; - *g = F; + *f = G; + *g = F; } return(NULL); @@ -718,14 +746,14 @@ Cudd_addXnor( DdNode * Cudd_addMonadicApply( DdManager * dd, - DdNode * (*op)(DdManager *, DdNode *), + DD_MAOP op, DdNode * f) { DdNode *res; do { - dd->reordered = 0; - res = cuddAddMonadicApplyRecur(dd,op,f); + dd->reordered = 0; + res = cuddAddMonadicApplyRecur(dd,op,f); } while (dd->reordered == 1); return(res); @@ -751,9 +779,9 @@ Cudd_addLog( DdNode * f) { if (cuddIsConstant(f)) { - CUDD_VALUE_TYPE value = log(cuddV(f)); - DdNode *res = cuddUniqueConst(dd,value); - return(res); + CUDD_VALUE_TYPE value = log(cuddV(f)); + DdNode *res = cuddUniqueConst(dd,value); + return(res); } return(NULL); @@ -780,16 +808,16 @@ Cudd_addLog( DdNode * cuddAddApplyRecur( DdManager * dd, - DdNode * (*op)(DdManager *, DdNode **, DdNode **), + DD_AOP op, DdNode * f, DdNode * g) { DdNode *res, - *fv, *fvn, *gv, *gvn, - *T, *E; + *fv, *fvn, *gv, *gvn, + *T, *E; unsigned int ford, gord; unsigned int index; - DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *); + DD_CTFP cacheOp; /* Check terminal cases. Op may swap f and g to increase the * cache hit rate. @@ -799,7 +827,7 @@ cuddAddApplyRecur( if (res != NULL) return(res); /* Check cache. */ - cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) op; + cacheOp = (DD_CTFP) op; res = cuddCacheLookup2(dd,cacheOp,f,g); if (res != NULL) return(res); @@ -807,18 +835,18 @@ cuddAddApplyRecur( ford = cuddI(dd,f->index); gord = cuddI(dd,g->index); if (ford <= gord) { - index = f->index; - fv = cuddT(f); - fvn = cuddE(f); + index = f->index; + fv = cuddT(f); + fvn = cuddE(f); } else { - index = g->index; - fv = fvn = f; + index = g->index; + fv = fvn = f; } if (gord <= ford) { - gv = cuddT(g); - gvn = cuddE(g); + gv = cuddT(g); + gvn = cuddE(g); } else { - gv = gvn = g; + gv = gvn = g; } T = cuddAddApplyRecur(dd,op,fv,gv); @@ -827,16 +855,16 @@ cuddAddApplyRecur( E = cuddAddApplyRecur(dd,op,fvn,gvn); if (E == NULL) { - Cudd_RecursiveDeref(dd,T); - return(NULL); + Cudd_RecursiveDeref(dd,T); + return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); } cuddDeref(T); cuddDeref(E); @@ -864,11 +892,10 @@ cuddAddApplyRecur( DdNode * cuddAddMonadicApplyRecur( DdManager * dd, - DdNode * (*op)(DdManager *, DdNode *), + DD_MAOP op, DdNode * f) { DdNode *res, *ft, *fe, *T, *E; - unsigned int ford; unsigned int index; /* Check terminal cases. */ @@ -881,7 +908,6 @@ cuddAddMonadicApplyRecur( if (res != NULL) return(res); /* Recursive step. */ - ford = cuddI(dd,f->index); index = f->index; ft = cuddT(f); fe = cuddE(f); @@ -892,16 +918,16 @@ cuddAddMonadicApplyRecur( E = cuddAddMonadicApplyRecur(dd,op,fe); if (E == NULL) { - Cudd_RecursiveDeref(dd,T); - return(NULL); + Cudd_RecursiveDeref(dd,T); + return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,(int)index,T,E); if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); } cuddDeref(T); cuddDeref(E); @@ -918,5 +944,6 @@ cuddAddMonadicApplyRecur( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddAddFind.c b/src/bdd/cudd/cuddAddFind.c index 6cc58f2d..4d63965d 100644 --- a/src/bdd/cudd/cuddAddFind.c +++ b/src/bdd/cudd/cuddAddFind.c @@ -8,22 +8,49 @@ extract the i-th bit.] Description [External procedures included in this module: - <ul> - <li> Cudd_addFindMax() - <li> Cudd_addFindMin() - <li> Cudd_addIthBit() - </ul> - Static functions included in this module: - <ul> - <li> addDoIthBit() - </ul>] + <ul> + <li> Cudd_addFindMax() + <li> Cudd_addFindMin() + <li> Cudd_addIthBit() + </ul> + Static functions included in this module: + <ul> + <li> addDoIthBit() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -33,6 +60,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -53,7 +81,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.8 2004/08/13 18:04:45 fabio Exp $"; #endif @@ -61,6 +89,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.1.1.1 2003/02/24 22:23:5 /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -68,10 +99,13 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddFind.c,v 1.1.1.1 2003/02/24 22:23:5 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * addDoIthBit ARGS((DdManager *dd, DdNode *f, DdNode *index)); +static DdNode * addDoIthBit (DdManager *dd, DdNode *f, DdNode *index); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -95,12 +129,12 @@ Cudd_addFindMax( statLine(dd); if (cuddIsConstant(f)) { - return(f); + return(f); } res = cuddCacheLookup1(dd,Cudd_addFindMax,f); if (res != NULL) { - return(res); + return(res); } t = Cudd_addFindMax(dd,cuddT(f)); @@ -135,12 +169,12 @@ Cudd_addFindMin( statLine(dd); if (cuddIsConstant(f)) { - return(f); + return(f); } res = cuddCacheLookup1(dd,Cudd_addFindMin,f); if (res != NULL) { - return(res); + return(res); } t = Cudd_addFindMin(dd,cuddT(f)); @@ -192,13 +226,13 @@ Cudd_addIthBit( cuddRef(index); do { - dd->reordered = 0; - res = addDoIthBit(dd, f, index); + dd->reordered = 0; + res = addDoIthBit(dd, f, index); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd, index); - return(NULL); + Cudd_RecursiveDeref(dd, index); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, index); @@ -244,9 +278,9 @@ addDoIthBit( statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { - mask = 1 << ((int) cuddV(index)); - value = (int) cuddV(f); - return((value & mask) == 0 ? DD_ZERO(dd) : DD_ONE(dd)); + mask = 1 << ((int) cuddV(index)); + value = (int) cuddV(f); + return((value & mask) == 0 ? DD_ZERO(dd) : DD_ONE(dd)); } /* Check cache. */ @@ -263,16 +297,16 @@ addDoIthBit( E = addDoIthBit(dd,fvn,index); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); + Cudd_RecursiveDeref(dd, T); + return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); } cuddDeref(T); cuddDeref(E); @@ -284,5 +318,7 @@ addDoIthBit( } /* end of addDoIthBit */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddAddInv.c b/src/bdd/cudd/cuddAddInv.c index 05650c0e..cae00ca1 100644 --- a/src/bdd/cudd/cuddAddInv.c +++ b/src/bdd/cudd/cuddAddInv.c @@ -7,20 +7,47 @@ Synopsis [Function to compute the scalar inverse of an ADD.] Description [External procedures included in this module: - <ul> - <li> Cudd_addScalarInverse() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddAddScalarInverseRecur() - </ul>] + <ul> + <li> Cudd_addScalarInverse() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddAddScalarInverseRecur() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -31,6 +58,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -51,7 +79,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddInv.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddInv.c,v 1.9 2004/08/13 18:04:45 fabio Exp $"; #endif @@ -97,12 +125,12 @@ Cudd_addScalarInverse( DdNode *res; if (!cuddIsConstant(epsilon)) { - (void) fprintf(dd->err,"Invalid epsilon\n"); - return(NULL); + (void) fprintf(dd->err,"Invalid epsilon\n"); + return(NULL); } do { - dd->reordered = 0; - res = cuddAddScalarInverseRecur(dd,f,epsilon); + dd->reordered = 0; + res = cuddAddScalarInverseRecur(dd,f,epsilon); } while (dd->reordered == 1); return(res); @@ -135,10 +163,10 @@ cuddAddScalarInverseRecur( statLine(dd); if (cuddIsConstant(f)) { - if (ddAbs(cuddV(f)) < cuddV(epsilon)) return(NULL); - value = 1.0 / cuddV(f); - res = cuddUniqueConst(dd,value); - return(res); + if (ddAbs(cuddV(f)) < cuddV(epsilon)) return(NULL); + value = 1.0 / cuddV(f); + res = cuddUniqueConst(dd,value); + return(res); } res = cuddCacheLookup2(dd,Cudd_addScalarInverse,f,epsilon); @@ -150,17 +178,19 @@ cuddAddScalarInverseRecur( e = cuddAddScalarInverseRecur(dd,cuddE(f),epsilon); if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); + Cudd_RecursiveDeref(dd, t); + return(NULL); } cuddRef(e); res = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); if (res == NULL) { - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - return(NULL); + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); } + cuddDeref(t); + cuddDeref(e); cuddCacheInsert2(dd,Cudd_addScalarInverse,f,epsilon,res); @@ -173,5 +203,7 @@ cuddAddScalarInverseRecur( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddAddIte.c b/src/bdd/cudd/cuddAddIte.c index def55537..67f1cf14 100644 --- a/src/bdd/cudd/cuddAddIte.c +++ b/src/bdd/cudd/cuddAddIte.c @@ -7,29 +7,56 @@ Synopsis [ADD ITE function and satellites.] Description [External procedures included in this module: - <ul> - <li> Cudd_addIte() - <li> Cudd_addIteConstant() - <li> Cudd_addEvalConst() - <li> Cudd_addCmpl() - <li> Cudd_addLeq() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddAddIteRecur() - <li> cuddAddCmplRecur() - </ul> - Static procedures included in this module: - <ul> - <li> addVarToConst() - </ul>] + <ul> + <li> Cudd_addIte() + <li> Cudd_addIteConstant() + <li> Cudd_addEvalConst() + <li> Cudd_addCmpl() + <li> Cudd_addLeq() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddAddIteRecur() + <li> cuddAddCmplRecur() + </ul> + Static procedures included in this module: + <ul> + <li> addVarToConst() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -39,6 +66,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -59,7 +87,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.15 2004/08/13 18:04:45 fabio Exp $"; #endif @@ -74,7 +102,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddIte.c,v 1.1.1.1 2003/02/24 22:23:50 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void addVarToConst ARGS((DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero)); +static void addVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero); /**AutomaticEnd***************************************************************/ @@ -107,8 +135,8 @@ Cudd_addIte( DdNode *res; do { - dd->reordered = 0; - res = cuddAddIteRecur(dd,f,g,h); + dd->reordered = 0; + res = cuddAddIteRecur(dd,f,g,h); } while (dd->reordered == 1); return(res); @@ -144,7 +172,7 @@ Cudd_addIteConstant( statLine(dd); /* Trivial cases. */ - if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ + if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ return(g); } if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ @@ -155,7 +183,7 @@ Cudd_addIteConstant( addVarToConst(f,&g,&h,one,zero); /* Check remaining one variable cases. */ - if (g == h) { /* ITE(F,G,G) = G */ + if (g == h) { /* ITE(F,G,G) = G */ return(g); } if (cuddIsConstant(g) && cuddIsConstant(h)) { @@ -169,7 +197,7 @@ Cudd_addIteConstant( /* ITE(F,G,H) = (x,G,H) (non constant) if F = (x,1,0), x < top(G,H). */ if (topf < v && cuddIsConstant(cuddT(f)) && cuddIsConstant(cuddE(f))) { - return(DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } /* Check cache. */ @@ -180,7 +208,7 @@ Cudd_addIteConstant( /* Compute cofactors. */ if (topf <= v) { - v = ddMin(topf,v); /* v = top_var(F,G,H) */ + v = ddMin(topf,v); /* v = top_var(F,G,H) */ Fv = cuddT(f); Fnv = cuddE(f); } else { Fv = Fnv = f; @@ -199,13 +227,13 @@ Cudd_addIteConstant( /* Recursive step. */ t = Cudd_addIteConstant(dd,Fv,Gv,Hv); if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { - cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); - return(DD_NON_CONSTANT); + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } e = Cudd_addIteConstant(dd,Fnv,Gnv,Hnv); if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { - cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); - return(DD_NON_CONSTANT); + cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, t); return(t); @@ -279,24 +307,24 @@ Cudd_addEvalConst( /* Recursive step. */ if (Fv != zero) { - t = Cudd_addEvalConst(dd,Fv,Gv); - if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { - cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); - return(DD_NON_CONSTANT); - } - if (Fnv != zero) { - e = Cudd_addEvalConst(dd,Fnv,Gnv); - if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { - cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); - return(DD_NON_CONSTANT); + t = Cudd_addEvalConst(dd,Fv,Gv); + if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) { + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } - } - cuddCacheInsert2(dd,Cudd_addEvalConst,f,g,t); - return(t); + if (Fnv != zero) { + e = Cudd_addEvalConst(dd,Fnv,Gnv); + if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) { + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); + } + } + cuddCacheInsert2(dd,Cudd_addEvalConst,f,g,t); + return(t); } else { /* Fnv must be != zero */ - e = Cudd_addEvalConst(dd,Fnv,Gnv); - cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e); - return(e); + e = Cudd_addEvalConst(dd,Fnv,Gnv); + cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e); + return(e); } } /* end of Cudd_addEvalConst */ @@ -323,8 +351,8 @@ Cudd_addCmpl( DdNode *res; do { - dd->reordered = 0; - res = cuddAddCmplRecur(dd,f); + dd->reordered = 0; + res = cuddAddCmplRecur(dd,f); } while (dd->reordered == 1); return(res); @@ -358,39 +386,38 @@ Cudd_addLeq( statLine(dd); if (cuddIsConstant(f)) { - if (cuddIsConstant(g)) return(cuddV(f) <= cuddV(g)); - if (f == DD_MINUS_INFINITY(dd)) return(1); - if (f == DD_PLUS_INFINITY(dd)) return(0); /* since f != g */ + if (cuddIsConstant(g)) return(cuddV(f) <= cuddV(g)); + if (f == DD_MINUS_INFINITY(dd)) return(1); + if (f == DD_PLUS_INFINITY(dd)) return(0); /* since f != g */ } if (g == DD_PLUS_INFINITY(dd)) return(1); if (g == DD_MINUS_INFINITY(dd)) return(0); /* since f != g */ /* Check cache. */ - tmp = cuddCacheLookup2(dd,(DdNode * (*)(DdManager *, DdNode *, - DdNode *))Cudd_addLeq,f,g); + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g); if (tmp != NULL) { - return(tmp == DD_ONE(dd)); + return(tmp == DD_ONE(dd)); } /* Compute cofactors. One of f and g is not constant. */ topf = cuddI(dd,f->index); topg = cuddI(dd,g->index); if (topf <= topg) { - fv = cuddT(f); fvn = cuddE(f); + fv = cuddT(f); fvn = cuddE(f); } else { - fv = fvn = f; + fv = fvn = f; } if (topg <= topf) { - gv = cuddT(g); gvn = cuddE(g); + gv = cuddT(g); gvn = cuddE(g); } else { - gv = gvn = g; + gv = gvn = g; } res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv); /* Store result in cache and return. */ - cuddCacheInsert2(dd,(DdNode * (*)(DdManager *, DdNode *, DdNode *)) - Cudd_addLeq,f,g,Cudd_NotCond(DD_ONE(dd),res==0)); + cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq,f,g, + Cudd_NotCond(DD_ONE(dd),res==0)); return(res); } /* end of Cudd_addLeq */ @@ -424,13 +451,13 @@ cuddAddIteRecur( DdNode *one,*zero; DdNode *r,*Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*t,*e; unsigned int topf,topg,toph,v; - int index = 0; // Suppress "might be used uninitialized" + int index; statLine(dd); /* Trivial cases. */ /* One variable cases. */ - if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ + if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */ return(g); } if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ @@ -441,11 +468,11 @@ cuddAddIteRecur( addVarToConst(f,&g,&h,one,zero); /* Check remaining one variable cases. */ - if (g == h) { /* ITE(F,G,G) = G */ + if (g == h) { /* ITE(F,G,G) = G */ return(g); } - if (g == one) { /* ITE(F,1,0) = F */ + if (g == one) { /* ITE(F,1,0) = F */ if (h == zero) return(f); } @@ -456,12 +483,12 @@ cuddAddIteRecur( /* A shortcut: ITE(F,G,H) = (x,G,H) if F=(x,1,0), x < top(G,H). */ if (topf < v && cuddT(f) == one && cuddE(f) == zero) { - r = cuddUniqueInter(dd,(int)f->index,g,h); - return(r); + r = cuddUniqueInter(dd,(int)f->index,g,h); + return(r); } if (topf < v && cuddT(f) == zero && cuddE(f) == one) { - r = cuddUniqueInter(dd,(int)f->index,h,g); - return(r); + r = cuddUniqueInter(dd,(int)f->index,h,g); + return(r); } /* Check cache. */ @@ -472,20 +499,20 @@ cuddAddIteRecur( /* Compute cofactors. */ if (topf <= v) { - v = ddMin(topf,v); /* v = top_var(F,G,H) */ - index = f->index; + v = ddMin(topf,v); /* v = top_var(F,G,H) */ + index = f->index; Fv = cuddT(f); Fnv = cuddE(f); } else { Fv = Fnv = f; } if (topg == v) { - index = g->index; + index = g->index; Gv = cuddT(g); Gnv = cuddE(g); } else { Gv = Gnv = g; } if (toph == v) { - index = h->index; + index = h->index; Hv = cuddT(h); Hnv = cuddE(h); } else { Hv = Hnv = h; @@ -498,16 +525,16 @@ cuddAddIteRecur( e = cuddAddIteRecur(dd,Fnv,Gnv,Hnv); if (e == NULL) { - Cudd_RecursiveDeref(dd,t); - return(NULL); + Cudd_RecursiveDeref(dd,t); + return(NULL); } cuddRef(e); r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); if (r == NULL) { - Cudd_RecursiveDeref(dd,t); - Cudd_RecursiveDeref(dd,e); - return(NULL); + Cudd_RecursiveDeref(dd,t); + Cudd_RecursiveDeref(dd,e); + return(NULL); } cuddDeref(t); cuddDeref(e); @@ -545,14 +572,14 @@ cuddAddCmplRecur( if (cuddIsConstant(f)) { if (f == zero) { - return(one); - } else { - return(zero); - } + return(one); + } else { + return(zero); + } } r = cuddCacheLookup1(dd,Cudd_addCmpl,f); if (r != NULL) { - return(r); + return(r); } Fv = cuddT(f); Fnv = cuddE(f); @@ -561,15 +588,15 @@ cuddAddCmplRecur( cuddRef(t); e = cuddAddCmplRecur(dd,Fnv); if (e == NULL) { - Cudd_RecursiveDeref(dd,t); - return(NULL); + Cudd_RecursiveDeref(dd,t); + return(NULL); } cuddRef(e); r = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e); if (r == NULL) { - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - return(NULL); + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); } cuddDeref(t); cuddDeref(e); @@ -606,13 +633,15 @@ addVarToConst( DdNode *h = *hp; if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ - *gp = one; + *gp = one; } if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ - *hp = zero; + *hp = zero; } } /* end of addVarToConst */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddAddNeg.c b/src/bdd/cudd/cuddAddNeg.c index d99d0357..c21c995a 100644 --- a/src/bdd/cudd/cuddAddNeg.c +++ b/src/bdd/cudd/cuddAddNeg.c @@ -4,35 +4,63 @@ PackageName [cudd] - Synopsis [function to compute the negation of an ADD.] + Synopsis [Function to compute the negation of an ADD.] Description [External procedures included in this module: - <ul> - <li> Cudd_addNegate() - <li> Cudd_addRoundOff() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddAddNegateRecur() - <li> cuddAddRoundOffRecur() - </ul> ] + <ul> + <li> Cudd_addNegate() + <li> Cudd_addRoundOff() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddAddNegateRecur() + <li> cuddAddRoundOffRecur() + </ul> ] Author [Fabio Somenzi, Balakrishna Kumthekar] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" +#include "util_hack.h" #include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -53,7 +81,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddNeg.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddNeg.c,v 1.12 2009/02/20 02:14:58 fabio Exp $"; #endif @@ -96,7 +124,7 @@ Cudd_addNegate( DdNode *res; do { - res = cuddAddNegateRecur(dd,f); + res = cuddAddNegateRecur(dd,f); } while (dd->reordered == 1); return(res); @@ -126,7 +154,7 @@ Cudd_addRoundOff( double trunc = pow(10.0,(double)N); do { - res = cuddAddRoundOffRecur(dd,f,trunc); + res = cuddAddRoundOffRecur(dd,f,trunc); } while (dd->reordered == 1); return(res); @@ -154,14 +182,14 @@ cuddAddNegateRecur( DdNode * f) { DdNode *res, - *fv, *fvn, - *T, *E; + *fv, *fvn, + *T, *E; statLine(dd); /* Check terminal cases. */ if (cuddIsConstant(f)) { - res = cuddUniqueConst(dd,-cuddV(f)); - return(res); + res = cuddUniqueConst(dd,-cuddV(f)); + return(res); } /* Check cache */ @@ -177,15 +205,15 @@ cuddAddNegateRecur( E = cuddAddNegateRecur(dd,fvn); if (E == NULL) { - Cudd_RecursiveDeref(dd,T); - return(NULL); + Cudd_RecursiveDeref(dd,T); + return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); } cuddDeref(T); cuddDeref(E); @@ -217,15 +245,15 @@ cuddAddRoundOffRecur( DdNode *res, *fv, *fvn, *T, *E; double n; - DdNode *(*cacheOp)(DdManager *, DdNode *); - + DD_CTFP1 cacheOp; + statLine(dd); if (cuddIsConstant(f)) { n = ceil(cuddV(f)*trunc)/trunc; - res = cuddUniqueConst(dd,n); - return(res); + res = cuddUniqueConst(dd,n); + return(res); } - cacheOp = (DdNode *(*)(DdManager *, DdNode *)) Cudd_addRoundOff; + cacheOp = (DD_CTFP1) Cudd_addRoundOff; res = cuddCacheLookup1(dd,cacheOp,f); if (res != NULL) { return(res); @@ -241,14 +269,14 @@ cuddAddRoundOffRecur( E = cuddAddRoundOffRecur(dd,fvn,trunc); if (E == NULL) { Cudd_RecursiveDeref(dd,T); - return(NULL); + return(NULL); } cuddRef(E); res = (T == E) ? T : cuddUniqueInter(dd,(int)f->index,T,E); if (res == NULL) { Cudd_RecursiveDeref(dd,T); - Cudd_RecursiveDeref(dd,E); - return(NULL); + Cudd_RecursiveDeref(dd,E); + return(NULL); } cuddDeref(T); cuddDeref(E); @@ -256,12 +284,13 @@ cuddAddRoundOffRecur( /* Store result. */ cuddCacheInsert1(dd,cacheOp,f,res); return(res); - + } /* end of cuddAddRoundOffRecur */ /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddAddWalsh.c b/src/bdd/cudd/cuddAddWalsh.c index 44b4415d..e8e8a641 100644 --- a/src/bdd/cudd/cuddAddWalsh.c +++ b/src/bdd/cudd/cuddAddWalsh.c @@ -8,21 +8,48 @@ functions in ADD form.] Description [External procedures included in this module: - <ul> - <li> Cudd_addWalsh() - <li> Cudd_addResidue() - </ul> - Static procedures included in this module: - <ul> - <li> addWalshInt() - </ul>] + <ul> + <li> Cudd_addWalsh() + <li> Cudd_addResidue() + </ul> + Static procedures included in this module: + <ul> + <li> addWalshInt() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -33,6 +60,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -53,7 +81,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.1.1.1 2003/02/24 22:23:50 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.10 2008/04/17 21:17:11 fabio Exp $"; #endif @@ -68,7 +96,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddAddWalsh.c,v 1.1.1.1 2003/02/24 22:23: /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * addWalshInt ARGS((DdManager *dd, DdNode **x, DdNode **y, int n)); +static DdNode * addWalshInt (DdManager *dd, DdNode **x, DdNode **y, int n); /**AutomaticEnd***************************************************************/ @@ -98,8 +126,8 @@ Cudd_addWalsh( DdNode *res; do { - dd->reordered = 0; - res = addWalshInt(dd, x, y, n); + dd->reordered = 0; + res = addWalshInt(dd, x, y, n); } while (dd->reordered == 1); return(res); @@ -137,8 +165,8 @@ Cudd_addResidue( int options /* options */, int top /* index of top variable */) { - int msbLsb; /* MSB on top (1) or LSB on top (0) */ - int tc; /* two's complement (1) or unsigned (0) */ + int msbLsb; /* MSB on top (1) or LSB on top (0) */ + int tc; /* two's complement (1) or unsigned (0) */ int i, j, k, t, residue, thisOne, previous, index; DdNode **array[2], *var, *tmp, *res; @@ -151,89 +179,89 @@ Cudd_addResidue( /* Allocate and initialize working arrays. */ array[0] = ABC_ALLOC(DdNode *,m); if (array[0] == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } array[1] = ABC_ALLOC(DdNode *,m); if (array[1] == NULL) { - ABC_FREE(array[0]); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + ABC_FREE(array[0]); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < m; i++) { - array[0][i] = array[1][i] = NULL; + array[0][i] = array[1][i] = NULL; } /* Initialize residues. */ for (i = 0; i < m; i++) { - tmp = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) i); - if (tmp == NULL) { - for (j = 0; j < i; j++) { - Cudd_RecursiveDeref(dd,array[1][j]); + tmp = cuddUniqueConst(dd,(CUDD_VALUE_TYPE) i); + if (tmp == NULL) { + for (j = 0; j < i; j++) { + Cudd_RecursiveDeref(dd,array[1][j]); + } + ABC_FREE(array[0]); + ABC_FREE(array[1]); + return(NULL); } - ABC_FREE(array[0]); - ABC_FREE(array[1]); - return(NULL); - } - cuddRef(tmp); - array[1][i] = tmp; + cuddRef(tmp); + array[1][i] = tmp; } /* Main iteration. */ - residue = 1; /* residue of 2**0 */ + residue = 1; /* residue of 2**0 */ for (k = 0; k < n; k++) { - /* Choose current and previous arrays. */ - thisOne = k & 1; - previous = thisOne ^ 1; - /* Build an ADD projection function. */ - if (msbLsb) { - index = top+n-k-1; - } else { - index = top+k; - } - var = cuddUniqueInter(dd,index,DD_ONE(dd),DD_ZERO(dd)); - if (var == NULL) { - for (j = 0; j < m; j++) { - Cudd_RecursiveDeref(dd,array[previous][j]); + /* Choose current and previous arrays. */ + thisOne = k & 1; + previous = thisOne ^ 1; + /* Build an ADD projection function. */ + if (msbLsb) { + index = top+n-k-1; + } else { + index = top+k; } - ABC_FREE(array[0]); - ABC_FREE(array[1]); - return(NULL); - } - cuddRef(var); - for (i = 0; i < m; i ++) { - t = (i + residue) % m; - tmp = Cudd_addIte(dd,var,array[previous][t],array[previous][i]); - if (tmp == NULL) { - for (j = 0; j < i; j++) { - Cudd_RecursiveDeref(dd,array[thisOne][j]); + var = cuddUniqueInter(dd,index,DD_ONE(dd),DD_ZERO(dd)); + if (var == NULL) { + for (j = 0; j < m; j++) { + Cudd_RecursiveDeref(dd,array[previous][j]); + } + ABC_FREE(array[0]); + ABC_FREE(array[1]); + return(NULL); } - for (j = 0; j < m; j++) { - Cudd_RecursiveDeref(dd,array[previous][j]); + cuddRef(var); + for (i = 0; i < m; i ++) { + t = (i + residue) % m; + tmp = Cudd_addIte(dd,var,array[previous][t],array[previous][i]); + if (tmp == NULL) { + for (j = 0; j < i; j++) { + Cudd_RecursiveDeref(dd,array[thisOne][j]); + } + for (j = 0; j < m; j++) { + Cudd_RecursiveDeref(dd,array[previous][j]); + } + ABC_FREE(array[0]); + ABC_FREE(array[1]); + return(NULL); + } + cuddRef(tmp); + array[thisOne][i] = tmp; } - ABC_FREE(array[0]); - ABC_FREE(array[1]); - return(NULL); + /* One layer completed. Free the other array for the next iteration. */ + for (i = 0; i < m; i++) { + Cudd_RecursiveDeref(dd,array[previous][i]); + } + Cudd_RecursiveDeref(dd,var); + /* Update residue of 2**k. */ + residue = (2 * residue) % m; + /* Adjust residue for MSB, if this is a two's complement number. */ + if (tc && (k == n - 1)) { + residue = (m - residue) % m; } - cuddRef(tmp); - array[thisOne][i] = tmp; - } - /* One layer completed. Free the other array for the next iteration. */ - for (i = 0; i < m; i++) { - Cudd_RecursiveDeref(dd,array[previous][i]); - } - Cudd_RecursiveDeref(dd,var); - /* Update residue of 2**k. */ - residue = (2 * residue) % m; - /* Adjust residue for MSB, if this is a two's complement number. */ - if (tc && (k == n - 1)) { - residue = (m - residue) % m; - } } /* We are only interested in the 0-residue node of the top layer. */ for (i = 1; i < m; i++) { - Cudd_RecursiveDeref(dd,array[(n - 1) & 1][i]); + Cudd_RecursiveDeref(dd,array[(n - 1) & 1][i]); } res = array[(n - 1) & 1][0]; @@ -274,8 +302,7 @@ addWalshInt( int n) { DdNode *one, *minusone; - DdNode *t = NULL; // Suppress "might be used uninitialized" - DdNode *u, *t1, *u1, *v, *w; + DdNode *t, *u, *t1, *u1, *v, *w; int i; one = DD_ONE(dd); @@ -287,84 +314,86 @@ addWalshInt( cuddRef(minusone); v = Cudd_addIte(dd, y[n-1], minusone, one); if (v == NULL) { - Cudd_RecursiveDeref(dd, minusone); - return(NULL); + Cudd_RecursiveDeref(dd, minusone); + return(NULL); } cuddRef(v); u = Cudd_addIte(dd, x[n-1], v, one); if (u == NULL) { - Cudd_RecursiveDeref(dd, minusone); - Cudd_RecursiveDeref(dd, v); - return(NULL); + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, v); + return(NULL); } cuddRef(u); Cudd_RecursiveDeref(dd, v); if (n>1) { - w = Cudd_addIte(dd, y[n-1], one, minusone); - if (w == NULL) { - Cudd_RecursiveDeref(dd, minusone); - Cudd_RecursiveDeref(dd, u); - return(NULL); - } - cuddRef(w); - t = Cudd_addIte(dd, x[n-1], w, minusone); - if (t == NULL) { - Cudd_RecursiveDeref(dd, minusone); - Cudd_RecursiveDeref(dd, u); + w = Cudd_addIte(dd, y[n-1], one, minusone); + if (w == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(w); + t = Cudd_addIte(dd, x[n-1], w, minusone); + if (t == NULL) { + Cudd_RecursiveDeref(dd, minusone); + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(t); Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(t); - Cudd_RecursiveDeref(dd, w); } cuddDeref(minusone); /* minusone is in the result; it won't die */ /* Loop to build the rest of the ADD */ for (i=n-2; i>=0; i--) { - t1 = t; u1 = u; - v = Cudd_addIte(dd, y[i], t1, u1); - if (v == NULL) { - Cudd_RecursiveDeref(dd, u1); - Cudd_RecursiveDeref(dd, t1); - return(NULL); - } - cuddRef(v); - u = Cudd_addIte(dd, x[i], v, u1); - if (u == NULL) { - Cudd_RecursiveDeref(dd, u1); - Cudd_RecursiveDeref(dd, t1); - Cudd_RecursiveDeref(dd, v); - return(NULL); - } - cuddRef(u); - Cudd_RecursiveDeref(dd, v); - if (i>0) { - w = Cudd_addIte(dd, y[i], u1, t1); - if (u == NULL) { - Cudd_RecursiveDeref(dd, u1); - Cudd_RecursiveDeref(dd, t1); - Cudd_RecursiveDeref(dd, u); - return(NULL); + t1 = t; u1 = u; + v = Cudd_addIte(dd, y[i], t1, u1); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + return(NULL); } - cuddRef(w); - t = Cudd_addIte(dd, x[i], w, t1); + cuddRef(v); + u = Cudd_addIte(dd, x[i], v, u1); if (u == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(u); + Cudd_RecursiveDeref(dd, v); + if (i>0) { + w = Cudd_addIte(dd, y[i], u1, t1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(w); + t = Cudd_addIte(dd, x[i], w, t1); + if (u == NULL) { + Cudd_RecursiveDeref(dd, u1); + Cudd_RecursiveDeref(dd, t1); + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(t); + Cudd_RecursiveDeref(dd, w); + } Cudd_RecursiveDeref(dd, u1); Cudd_RecursiveDeref(dd, t1); - Cudd_RecursiveDeref(dd, u); - Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(t); - Cudd_RecursiveDeref(dd, w); - } - Cudd_RecursiveDeref(dd, u1); - Cudd_RecursiveDeref(dd, t1); } cuddDeref(u); return(u); } /* end of addWalshInt */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddAndAbs.c b/src/bdd/cudd/cuddAndAbs.c index 10b057ac..39695918 100644 --- a/src/bdd/cudd/cuddAndAbs.c +++ b/src/bdd/cudd/cuddAndAbs.c @@ -7,20 +7,48 @@ Synopsis [Combined AND and existential abstraction for BDDs] Description [External procedures included in this module: - <ul> - <li> Cudd_bddAndAbstract() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddAndAbstractRecur() - </ul>] + <ul> + <li> Cudd_bddAndAbstract() + <li> Cudd_bddAndAbstractLimit() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddBddAndAbstractRecur() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -31,6 +59,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -51,7 +80,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAndAbs.c,v 1.19 2004/08/13 18:04:46 fabio Exp $"; #endif @@ -101,8 +130,8 @@ Cudd_bddAndAbstract( DdNode *res; do { - manager->reordered = 0; - res = cuddBddAndAbstractRecur(manager, f, g, cube); + manager->reordered = 0; + res = cuddBddAndAbstractRecur(manager, f, g, cube); } while (manager->reordered == 1); return(res); @@ -135,10 +164,11 @@ Cudd_bddAndAbstractLimit( { DdNode *res; unsigned int saveLimit = manager->maxLive; + + manager->maxLive = (manager->keys - manager->dead) + + (manager->keysZ - manager->deadZ) + limit; do { manager->reordered = 0; - manager->maxLive = (manager->keys - manager->dead) + - (manager->keysZ - manager->deadZ) + limit; res = cuddBddAndAbstractRecur(manager, f, g, cube); } while (manager->reordered == 1); manager->maxLive = saveLimit; @@ -147,7 +177,6 @@ Cudd_bddAndAbstractLimit( } /* end of Cudd_bddAndAbstractLimit */ - /*---------------------------------------------------------------------------*/ /* Definition of internal functions */ /*---------------------------------------------------------------------------*/ @@ -184,23 +213,23 @@ cuddBddAndAbstractRecur( /* Terminal cases. */ if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); - if (f == one && g == one) return(one); + if (f == one && g == one) return(one); if (cube == one) { - return(cuddBddAndRecur(manager, f, g)); + return(cuddBddAndRecur(manager, f, g)); } if (f == one || f == g) { - return(cuddBddExistAbstractRecur(manager, g, cube)); + return(cuddBddExistAbstractRecur(manager, g, cube)); } if (g == one) { - return(cuddBddExistAbstractRecur(manager, f, cube)); + return(cuddBddExistAbstractRecur(manager, f, cube)); } /* At this point f, g, and cube are not constant. */ if (f > g) { /* Try to increase cache efficiency. */ - DdNode *tmp = f; - f = g; - g = tmp; + DdNode *tmp = f; + f = g; + g = tmp; } /* Here we can skip the use of cuddI, because the operands are known @@ -214,129 +243,129 @@ cuddBddAndAbstractRecur( topcube = manager->perm[cube->index]; while (topcube < top) { - cube = cuddT(cube); - if (cube == one) { - return(cuddBddAndRecur(manager, f, g)); - } - topcube = manager->perm[cube->index]; + cube = cuddT(cube); + if (cube == one) { + return(cuddBddAndRecur(manager, f, g)); + } + topcube = manager->perm[cube->index]; } /* Now, topcube >= top. */ /* Check cache. */ if (F->ref != 1 || G->ref != 1) { - r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube); - if (r != NULL) { - return(r); - } + r = cuddCacheLookup(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube); + if (r != NULL) { + return(r); + } } if (topf == top) { - index = F->index; - ft = cuddT(F); - fe = cuddE(F); - if (Cudd_IsComplement(f)) { - ft = Cudd_Not(ft); - fe = Cudd_Not(fe); - } + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } } else { - index = G->index; - ft = fe = f; + index = G->index; + ft = fe = f; } if (topg == top) { - gt = cuddT(G); - ge = cuddE(G); - if (Cudd_IsComplement(g)) { - gt = Cudd_Not(gt); - ge = Cudd_Not(ge); - } + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } } else { - gt = ge = g; + gt = ge = g; } - if (topcube == top) { /* quantify */ - DdNode *Cube = cuddT(cube); - t = cuddBddAndAbstractRecur(manager, ft, gt, Cube); - if (t == NULL) return(NULL); - /* Special case: 1 OR anything = 1. Hence, no need to compute - ** the else branch if t is 1. Likewise t + t * anything == t. - ** Notice that t == fe implies that fe does not depend on the - ** variables in Cube. Likewise for t == ge. - */ - if (t == one || t == fe || t == ge) { - if (F->ref != 1 || G->ref != 1) - cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, - f, g, cube, t); - return(t); - } - cuddRef(t); - /* Special case: t + !t * anything == t + anything. */ - if (t == Cudd_Not(fe)) { - e = cuddBddExistAbstractRecur(manager, ge, Cube); - } else if (t == Cudd_Not(ge)) { - e = cuddBddExistAbstractRecur(manager, fe, Cube); - } else { - e = cuddBddAndAbstractRecur(manager, fe, ge, Cube); - } - if (e == NULL) { - Cudd_IterDerefBdd(manager, t); - return(NULL); - } - if (t == e) { - r = t; - cuddDeref(t); - } else { - cuddRef(e); - r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); - if (r == NULL) { - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - return(NULL); + if (topcube == top) { /* quantify */ + DdNode *Cube = cuddT(cube); + t = cuddBddAndAbstractRecur(manager, ft, gt, Cube); + if (t == NULL) return(NULL); + /* Special case: 1 OR anything = 1. Hence, no need to compute + ** the else branch if t is 1. Likewise t + t * anything == t. + ** Notice that t == fe implies that fe does not depend on the + ** variables in Cube. Likewise for t == ge. + */ + if (t == one || t == fe || t == ge) { + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, + f, g, cube, t); + return(t); } - r = Cudd_Not(r); - cuddRef(r); - Cudd_DelayedDerefBdd(manager, t); - Cudd_DelayedDerefBdd(manager, e); - cuddDeref(r); - } - } else { - t = cuddBddAndAbstractRecur(manager, ft, gt, cube); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddBddAndAbstractRecur(manager, fe, ge, cube); - if (e == NULL) { - Cudd_IterDerefBdd(manager, t); - return(NULL); - } - if (t == e) { - r = t; - cuddDeref(t); - } else { - cuddRef(e); - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(manager, (int) index, - Cudd_Not(t), Cudd_Not(e)); - if (r == NULL) { + cuddRef(t); + /* Special case: t + !t * anything == t + anything. */ + if (t == Cudd_Not(fe)) { + e = cuddBddExistAbstractRecur(manager, ge, Cube); + } else if (t == Cudd_Not(ge)) { + e = cuddBddExistAbstractRecur(manager, fe, Cube); + } else { + e = cuddBddAndAbstractRecur(manager, fe, ge, Cube); + } + if (e == NULL) { Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); return(NULL); } - r = Cudd_Not(r); + if (t == e) { + r = t; + cuddDeref(t); } else { - r = cuddUniqueInter(manager,(int)index,t,e); - if (r == NULL) { + cuddRef(e); + r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + cuddRef(r); + Cudd_DelayedDerefBdd(manager, t); + Cudd_DelayedDerefBdd(manager, e); + cuddDeref(r); + } + } else { + t = cuddBddAndAbstractRecur(manager, ft, gt, cube); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddAndAbstractRecur(manager, fe, ge, cube); + if (e == NULL) { Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); return(NULL); } + if (t == e) { + r = t; + cuddDeref(t); + } else { + cuddRef(e); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager, (int) index, + Cudd_Not(t), Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + cuddDeref(e); + cuddDeref(t); } - cuddDeref(e); - cuddDeref(t); - } } if (F->ref != 1 || G->ref != 1) - cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r); + cuddCacheInsert(manager, DD_BDD_AND_ABSTRACT_TAG, f, g, cube, r); return (r); } /* end of cuddBddAndAbstractRecur */ @@ -346,5 +375,7 @@ cuddBddAndAbstractRecur( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddAnneal.c b/src/bdd/cudd/cuddAnneal.c index c133cdc8..7a08b5ae 100644 --- a/src/bdd/cudd/cuddAnneal.c +++ b/src/bdd/cudd/cuddAnneal.c @@ -7,31 +7,58 @@ Synopsis [Reordering of DDs based on simulated annealing] Description [Internal procedures included in this file: - <ul> - <li> cuddAnnealing() - </ul> - Static procedures included in this file: - <ul> - <li> stopping_criterion() - <li> random_generator() - <li> ddExchange() - <li> ddJumpingAux() - <li> ddJumpingUp() - <li> ddJumpingDown() - <li> siftBackwardProb() - <li> copyOrder() - <li> restoreOrder() - </ul> - ] + <ul> + <li> cuddAnnealing() + </ul> + Static procedures included in this file: + <ul> + <li> stopping_criterion() + <li> random_generator() + <li> ddExchange() + <li> ddJumpingAux() + <li> ddJumpingUp() + <li> ddJumpingDown() + <li> siftBackwardProb() + <li> copyOrder() + <li> restoreOrder() + </ul> + ] SeeAlso [] Author [Jae-Young Jang, Jorgen Sivesind] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -41,6 +68,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -68,14 +96,14 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddAnneal.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddAnneal.c,v 1.14 2004/08/13 18:04:46 fabio Exp $"; #endif #ifdef DD_STATS -extern int ddTotalNumberSwapping; -extern int ddTotalNISwaps; -static int tosses; -static int acceptances; +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +static int tosses; +static int acceptances; #endif /*---------------------------------------------------------------------------*/ @@ -89,15 +117,15 @@ static int acceptances; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int stopping_criterion ARGS((int c1, int c2, int c3, int c4, double temp)); -static double random_generator ARGS(()); -static int ddExchange ARGS((DdManager *table, int x, int y, double temp)); -static int ddJumpingAux ARGS((DdManager *table, int x, int x_low, int x_high, double temp)); -static Move * ddJumpingUp ARGS((DdManager *table, int x, int x_low, int initial_size)); -static Move * ddJumpingDown ARGS((DdManager *table, int x, int x_high, int initial_size)); -static int siftBackwardProb ARGS((DdManager *table, Move *moves, int size, double temp)); -static void copyOrder ARGS((DdManager *table, int *array, int lower, int upper)); -static int restoreOrder ARGS((DdManager *table, int *array, int lower, int upper)); +static int stopping_criterion (int c1, int c2, int c3, int c4, double temp); +static double random_generator (void); +static int ddExchange (DdManager *table, int x, int y, double temp); +static int ddJumpingAux (DdManager *table, int x, int x_low, int x_high, double temp); +static Move * ddJumpingUp (DdManager *table, int x, int x_low, int initial_size); +static Move * ddJumpingDown (DdManager *table, int x, int x_high, int initial_size); +static int siftBackwardProb (DdManager *table, Move *moves, int size, double temp); +static void copyOrder (DdManager *table, int *array, int lower, int upper); +static int restoreOrder (DdManager *table, int *array, int lower, int upper); /**AutomaticEnd***************************************************************/ @@ -136,11 +164,11 @@ cuddAnnealing( int size; int x,y; int result; - int c1, c2, c3, c4; - int BestCost; - int *BestOrder; - double NewTemp, temp; - double rand1; + int c1, c2, c3, c4; + int BestCost; + int *BestOrder; + double NewTemp, temp; + double rand1; int innerloop, maxGen; int ecount, ucount, dcount; @@ -158,8 +186,8 @@ cuddAnnealing( BestCost = size; BestOrder = ABC_ALLOC(int,nvars); if (BestOrder == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } copyOrder(table,BestOrder,lower,upper); @@ -174,76 +202,76 @@ cuddAnnealing( while (!stopping_criterion(c1, c2, c3, c4, temp)) { #ifdef DD_STATS - (void) fprintf(table->out,"temp=%f\tsize=%d\tgen=%d\t", - temp,size,maxGen); - tosses = acceptances = 0; + (void) fprintf(table->out,"temp=%f\tsize=%d\tgen=%d\t", + temp,size,maxGen); + tosses = acceptances = 0; #endif - for (innerloop = 0; innerloop < maxGen; innerloop++) { - /* Choose x, y randomly. */ - x = (int) Cudd_Random() % nvars; - do { - y = (int) Cudd_Random() % nvars; - } while (x == y); - x += lower; - y += lower; - if (x > y) { - int tmp = x; - x = y; - y = tmp; - } - - /* Choose move with roulette wheel. */ - rand1 = random_generator(); - if (rand1 < EXC_PROB) { - result = ddExchange(table,x,y,temp); /* exchange */ - ecount++; + for (innerloop = 0; innerloop < maxGen; innerloop++) { + /* Choose x, y randomly. */ + x = (int) Cudd_Random() % nvars; + do { + y = (int) Cudd_Random() % nvars; + } while (x == y); + x += lower; + y += lower; + if (x > y) { + int tmp = x; + x = y; + y = tmp; + } + + /* Choose move with roulette wheel. */ + rand1 = random_generator(); + if (rand1 < EXC_PROB) { + result = ddExchange(table,x,y,temp); /* exchange */ + ecount++; #if 0 - (void) fprintf(table->out, - "Exchange of %d and %d: size = %d\n", - x,y,table->keys - table->isolated); + (void) fprintf(table->out, + "Exchange of %d and %d: size = %d\n", + x,y,table->keys - table->isolated); #endif - } else if (rand1 < EXC_PROB + JUMP_UP_PROB) { - result = ddJumpingAux(table,y,x,y,temp); /* jumping_up */ - ucount++; + } else if (rand1 < EXC_PROB + JUMP_UP_PROB) { + result = ddJumpingAux(table,y,x,y,temp); /* jumping_up */ + ucount++; #if 0 - (void) fprintf(table->out, - "Jump up of %d to %d: size = %d\n", - y,x,table->keys - table->isolated); + (void) fprintf(table->out, + "Jump up of %d to %d: size = %d\n", + y,x,table->keys - table->isolated); #endif - } else { - result = ddJumpingAux(table,x,x,y,temp); /* jumping_down */ - dcount++; + } else { + result = ddJumpingAux(table,x,x,y,temp); /* jumping_down */ + dcount++; #if 0 - (void) fprintf(table->out, - "Jump down of %d to %d: size = %d\n", - x,y,table->keys - table->isolated); + (void) fprintf(table->out, + "Jump down of %d to %d: size = %d\n", + x,y,table->keys - table->isolated); #endif + } + + if (!result) { + ABC_FREE(BestOrder); + return(0); + } + + size = table->keys - table->isolated; /* keep current size */ + if (size < BestCost) { /* update best order */ + BestCost = size; + copyOrder(table,BestOrder,lower,upper); + } } - - if (!result) { - ABC_FREE(BestOrder); - return(0); - } - - size = table->keys - table->isolated; /* keep current size */ - if (size < BestCost) { /* update best order */ - BestCost = size; - copyOrder(table,BestOrder,lower,upper); + c1 = c2; + c2 = c3; + c3 = c4; + c4 = size; + NewTemp = ALPHA * temp; + if (NewTemp >= 1.0) { + maxGen = (int)(log(NewTemp) / log(temp) * maxGen); } - } - c1 = c2; - c2 = c3; - c3 = c4; - c4 = size; - NewTemp = ALPHA * temp; - if (NewTemp >= 1.0) { - maxGen = (int)(log(NewTemp) / log(temp) * maxGen); - } - temp = NewTemp; /* control variable */ + temp = NewTemp; /* control variable */ #ifdef DD_STATS - (void) fprintf(table->out,"uphill = %d\taccepted = %d\n", - tosses,acceptances); - fflush(table->out); + (void) fprintf(table->out,"uphill = %d\taccepted = %d\n", + tosses,acceptances); + fflush(table->out); #endif } @@ -286,11 +314,11 @@ stopping_criterion( double temp) { if (STOP_TEMP < temp) { - return(0); + return(0); } else if ((c1 == c2) && (c1 == c3) && (c1 == c4)) { - return(1); + return(1); } else { - return(0); + return(0); } } /* end of stopping_criterion */ @@ -308,8 +336,7 @@ stopping_criterion( ******************************************************************************/ static double -random_generator( - ) +random_generator(void) { return((double)(Cudd_Random() / 2147483561.0)); @@ -351,83 +378,83 @@ ddExchange( initial_size = limit_size = table->keys - table->isolated; for (;;) { - if (x_next == y_next) { - size = cuddSwapInPlace(table,x,x_next); - if (size == 0) goto ddExchangeOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddExchangeOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; - size = cuddSwapInPlace(table,y_next,y); - if (size == 0) goto ddExchangeOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddExchangeOutOfMem; - move->x = y_next; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - size = cuddSwapInPlace(table,x,x_next); - if (size == 0) goto ddExchangeOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddExchangeOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; - - tmp = x; - x = y; - y = tmp; - } else if (x == y_next) { - size = cuddSwapInPlace(table,x,x_next); - if (size == 0) goto ddExchangeOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddExchangeOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; - tmp = x; - x = y; - y = tmp; - } else { - size = cuddSwapInPlace(table,x,x_next); - if (size == 0) goto ddExchangeOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddExchangeOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; - size = cuddSwapInPlace(table,y_next,y); - if (size == 0) goto ddExchangeOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddExchangeOutOfMem; - move->x = y_next; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - x = x_next; - y = y_next; - } + if (x_next == y_next) { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; + x = y; + y = tmp; + } else if (x == y_next) { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + tmp = x; + x = y; + y = tmp; + } else { + size = cuddSwapInPlace(table,x,x_next); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + size = cuddSwapInPlace(table,y_next,y); + if (size == 0) goto ddExchangeOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddExchangeOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + x = x_next; + y = y_next; + } - x_next = cuddNextHigh(table,x); - y_next = cuddNextLow(table,y); - if (x_next > y_ref) break; + x_next = cuddNextHigh(table,x); + y_next = cuddNextLow(table,y); + if (x_next > y_ref) break; - if ((double) size > DD_MAX_REORDER_GROWTH * (double) limit_size) { - break; - } else if (size < limit_size) { - limit_size = size; - } + if ((double) size > DD_MAX_REORDER_GROWTH * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } } if (y_next>=x_ref) { @@ -447,16 +474,16 @@ ddExchange( if (!result) goto ddExchangeOutOfMem; while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(1); ddExchangeOutOfMem: while (moves != NULL) { move = moves->next; - cuddDeallocNode(table,(DdNode *) moves); + cuddDeallocMove(table, moves); moves = move; } return(0); @@ -499,36 +526,36 @@ ddJumpingAux( moves = NULL; if (cuddNextLow(table,x) < x_low) { - if (cuddNextHigh(table,x) > x_high) return(1); - moves = ddJumpingDown(table,x,x_high,initial_size); - /* after that point x --> x_high unless early termination */ - if (moves == NULL) goto ddJumpingAuxOutOfMem; - /* move backward and stop at best position or accept uphill move */ - result = siftBackwardProb(table,moves,initial_size,temp); - if (!result) goto ddJumpingAuxOutOfMem; + if (cuddNextHigh(table,x) > x_high) return(1); + moves = ddJumpingDown(table,x,x_high,initial_size); + /* after that point x --> x_high unless early termination */ + if (moves == NULL) goto ddJumpingAuxOutOfMem; + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddJumpingAuxOutOfMem; } else if (cuddNextHigh(table,x) > x_high) { - moves = ddJumpingUp(table,x,x_low,initial_size); - /* after that point x --> x_low unless early termination */ - if (moves == NULL) goto ddJumpingAuxOutOfMem; - /* move backward and stop at best position or accept uphill move */ - result = siftBackwardProb(table,moves,initial_size,temp); - if (!result) goto ddJumpingAuxOutOfMem; + moves = ddJumpingUp(table,x,x_low,initial_size); + /* after that point x --> x_low unless early termination */ + if (moves == NULL) goto ddJumpingAuxOutOfMem; + /* move backward and stop at best position or accept uphill move */ + result = siftBackwardProb(table,moves,initial_size,temp); + if (!result) goto ddJumpingAuxOutOfMem; } else { - (void) fprintf(table->err,"Unexpected condition in ddJumping\n"); - goto ddJumpingAuxOutOfMem; + (void) fprintf(table->err,"Unexpected condition in ddJumping\n"); + goto ddJumpingAuxOutOfMem; } while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(1); ddJumpingAuxOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(0); @@ -564,30 +591,30 @@ ddJumpingUp( moves = NULL; y = cuddNextLow(table,x); while (y >= x_low) { - size = cuddSwapInPlace(table,y,x); - if (size == 0) goto ddJumpingUpOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddJumpingUpOutOfMem; - move->x = y; - move->y = x; - move->size = size; - move->next = moves; - moves = move; - if ((double) size > table->maxGrowth * (double) limit_size) { - break; - } else if (size < limit_size) { - limit_size = size; - } - x = y; - y = cuddNextLow(table,x); + size = cuddSwapInPlace(table,y,x); + if (size == 0) goto ddJumpingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddJumpingUpOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > table->maxGrowth * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + x = y; + y = cuddNextLow(table,x); } return(moves); ddJumpingUpOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(NULL); @@ -623,30 +650,30 @@ ddJumpingDown( moves = NULL; y = cuddNextHigh(table,x); while (y <= x_high) { - size = cuddSwapInPlace(table,x,y); - if (size == 0) goto ddJumpingDownOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddJumpingDownOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - if ((double) size > table->maxGrowth * (double) limit_size) { - break; - } else if (size < limit_size) { - limit_size = size; - } - x = y; - y = cuddNextHigh(table,x); + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddJumpingDownOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddJumpingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > table->maxGrowth * (double) limit_size) { + break; + } else if (size < limit_size) { + limit_size = size; + } + x = y; + y = cuddNextHigh(table,x); } return(moves); ddJumpingDownOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(NULL); @@ -681,9 +708,9 @@ siftBackwardProb( /* Look for best size during the last sifting */ for (move = moves; move != NULL; move = move->next) { - if (move->size < best_size) { - best_size = move->size; - } + if (move->size < best_size) { + best_size = move->size; + } } /* If best_size equals size, the last sifting did not produce any @@ -691,17 +718,17 @@ siftBackwardProb( ** this change or not. */ if (best_size == size) { - coin = random_generator(); + coin = random_generator(); #ifdef DD_STATS - tosses++; + tosses++; #endif - threshold = exp(-((double)(table->keys - table->isolated - size))/temp); - if (coin < threshold) { + threshold = exp(-((double)(table->keys - table->isolated - size))/temp); + if (coin < threshold) { #ifdef DD_STATS - acceptances++; + acceptances++; #endif - return(1); - } + return(1); + } } /* Either there was improvement, or we have decided not to @@ -709,9 +736,9 @@ siftBackwardProb( */ res = table->keys - table->isolated; for (move = moves; move != NULL; move = move->next) { - if (res == best_size) return(1); - res = cuddSwapInPlace(table,(int)move->x,(int)move->y); - if (!res) return(0); + if (res == best_size) return(1); + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); } return(1); @@ -743,7 +770,7 @@ copyOrder( nvars = upper - lower + 1; for (i = 0; i < nvars; i++) { - array[i] = table->invperm[i+lower]; + array[i] = table->invperm[i+lower]; } } /* end of copyOrder */ @@ -772,22 +799,24 @@ restoreOrder( int nvars = upper - lower + 1; for (i = 0; i < nvars; i++) { - x = table->perm[array[i]]; + x = table->perm[array[i]]; #ifdef DD_DEBUG assert(x >= lower && x <= upper); #endif - y = cuddNextLow(table,x); - while (y >= i + lower) { - size = cuddSwapInPlace(table,y,x); - if (size == 0) return(0); - x = y; y = cuddNextLow(table,x); - } + while (y >= i + lower) { + size = cuddSwapInPlace(table,y,x); + if (size == 0) return(0); + x = y; + y = cuddNextLow(table,x); + } } return(1); } /* end of restoreOrder */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddApa.c b/src/bdd/cudd/cuddApa.c index 04dac030..82547b54 100644 --- a/src/bdd/cudd/cuddApa.c +++ b/src/bdd/cudd/cuddApa.c @@ -7,24 +7,66 @@ Synopsis [Arbitrary precision arithmetic functions.] Description [External procedures included in this module: - <ul> - <li> - </ul> - Internal procedures included in this module: - <ul> - <li> () - </ul> - Static procedures included in this module: - <ul> - <li> () - </ul>] + <ul> + <li> Cudd_ApaNumberOfDigits() + <li> Cudd_NewApaNumber() + <li> Cudd_ApaCopy() + <li> Cudd_ApaAdd() + <li> Cudd_ApaSubtract() + <li> Cudd_ApaShortDivision() + <li> Cudd_ApaIntDivision() + <li> Cudd_ApaShiftRight() + <li> Cudd_ApaSetToLiteral() + <li> Cudd_ApaPowerOfTwo() + <li> Cudd_ApaCompare() + <li> Cudd_ApaCompareRatios() + <li> Cudd_ApaPrintHex() + <li> Cudd_ApaPrintDecimal() + <li> Cudd_ApaPrintExponential() + <li> Cudd_ApaCountMinterm() + <li> Cudd_ApaPrintMinterm() + <li> Cudd_ApaPrintMintermExp() + <li> Cudd_ApaPrintDensity() + </ul> + Static procedures included in this module: + <ul> + <li> cuddApaCountMintermAux() + <li> cuddApaStCountfree() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -34,6 +76,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -51,15 +94,18 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.19 2009/03/08 01:27:50 fabio Exp $"; #endif -static DdNode *background, *zero; +static DdNode *background, *zero; /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -67,11 +113,15 @@ static DdNode *background, *zero; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdApaNumber cuddApaCountMintermAux ARGS((DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table)); -static enum st_retval cuddApaStCountfree ARGS((char * key, char * value, char * arg)); +static DdApaNumber cuddApaCountMintermAux (DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table); +static enum st_retval cuddApaStCountfree (char * key, char * value, char * arg); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -101,11 +151,11 @@ Cudd_ApaNumberOfDigits( digits = binaryDigits / DD_APA_BITS; if ((digits * DD_APA_BITS) != binaryDigits) - digits++; + digits++; return(digits); } /* end of Cudd_ApaNumberOfDigits */ - + /**Function******************************************************************** @@ -149,7 +199,7 @@ Cudd_ApaCopy( int i; for (i = 0; i < digits; i++) { - dest[i] = source[i]; + dest[i] = source[i]; } } /* end of Cudd_ApaCopy */ @@ -178,10 +228,10 @@ Cudd_ApaAdd( DdApaDoubleDigit partial = 0; for (i = digits - 1; i >= 0; i--) { - partial = a[i] + b[i] + DD_MSDIGIT(partial); - sum[i] = (DdApaDigit) DD_LSDIGIT(partial); + partial = a[i] + b[i] + DD_MSDIGIT(partial); + sum[i] = (DdApaDigit) DD_LSDIGIT(partial); } - return(DD_MSDIGIT(partial)); + return((DdApaDigit) DD_MSDIGIT(partial)); } /* end of Cudd_ApaAdd */ @@ -210,10 +260,10 @@ Cudd_ApaSubtract( DdApaDoubleDigit partial = DD_APA_BASE; for (i = digits - 1; i >= 0; i--) { - partial = a[i] - b[i] + DD_MSDIGIT(partial) + DD_APA_MASK; - diff[i] = (DdApaDigit) DD_LSDIGIT(partial); + partial = DD_MSDIGIT(partial) + DD_APA_MASK + a[i] - b[i]; + diff[i] = (DdApaDigit) DD_LSDIGIT(partial); } - return(DD_MSDIGIT(partial) - 1); + return((DdApaDigit) DD_MSDIGIT(partial) - 1); } /* end of Cudd_ApaSubtract */ @@ -242,9 +292,9 @@ Cudd_ApaShortDivision( remainder = 0; for (i = 0; i < digits; i++) { - partial = remainder * DD_APA_BASE + dividend[i]; - quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor); - remainder = (DdApaDigit) (partial % divisor); + partial = remainder * DD_APA_BASE + dividend[i]; + quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor); + remainder = (DdApaDigit) (partial % divisor); } return(remainder); @@ -283,9 +333,9 @@ Cudd_ApaIntDivision( double ddiv = (double) divisor; for (i = 0; i < digits; i++) { - partial = (double) remainder * DD_APA_BASE + dividend[i]; - quotient[i] = (DdApaDigit) (partial / ddiv); - remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv)); + partial = (double) remainder * DD_APA_BASE + dividend[i]; + quotient[i] = (DdApaDigit) (partial / ddiv); + remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv)); } return(remainder); @@ -317,7 +367,7 @@ Cudd_ApaShiftRight( int i; for (i = digits - 1; i > 0; i--) { - b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1)); + b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1)); } b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1)); @@ -344,7 +394,7 @@ Cudd_ApaSetToLiteral( int i; for (i = 0; i < digits - 1; i++) - number[i] = 0; + number[i] = 0; number[digits - 1] = literal; } /* end of Cudd_ApaSetToLiteral */ @@ -373,7 +423,7 @@ Cudd_ApaPowerOfTwo( int index; for (i = 0; i < digits; i++) - number[i] = 0; + number[i] = 0; i = digits - 1 - power / DD_APA_BITS; if (i < 0) return; index = power & (DD_APA_BITS - 1); @@ -407,14 +457,14 @@ Cudd_ApaCompare( /* Find first non-zero in both numbers. */ for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++) - if (first[firstNZ] != 0) break; + if (first[firstNZ] != 0) break; for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++) - if (second[secondNZ] != 0) break; + if (second[secondNZ] != 0) break; if (digitsFirst - firstNZ > digitsSecond - secondNZ) return(1); else if (digitsFirst - firstNZ < digitsSecond - secondNZ) return(-1); for (i = 0; i < digitsFirst - firstNZ; i++) { - if (first[firstNZ + i] > second[secondNZ + i]) return(1); - else if (first[firstNZ + i] < second[secondNZ + i]) return(-1); + if (first[firstNZ + i] > second[secondNZ + i]) return(1); + else if (first[firstNZ + i] < second[secondNZ + i]) return(-1); } return(0); @@ -453,11 +503,13 @@ Cudd_ApaCompareRatios( second = Cudd_NewApaNumber(digitsSecond); secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second); result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second); + ABC_FREE(first); + ABC_FREE(second); if (result == 0) { - if ((double)firstRem/firstDen > (double)secondRem/secondDen) - return(1); - else if ((double)firstRem/firstDen < (double)secondRem/secondDen) - return(-1); + if ((double)firstRem/firstDen > (double)secondRem/secondDen) + return(1); + else if ((double)firstRem/firstDen < (double)secondRem/secondDen) + return(-1); } return(result); @@ -485,9 +537,9 @@ Cudd_ApaPrintHex( int i, result; for (i = 0; i < digits; i++) { - result = fprintf(fp,DD_APA_HEXPRINT,number[i]); - if (result == EOF) - return(0); + result = fprintf(fp,DD_APA_HEXPRINT,number[i]); + if (result == EOF) + return(0); } return(1); @@ -518,33 +570,33 @@ Cudd_ApaPrintDecimal( unsigned char *decimal; int leadingzero; int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; - + work = Cudd_NewApaNumber(digits); if (work == NULL) - return(0); + return(0); decimal = ABC_ALLOC(unsigned char, decimalDigits); if (decimal == NULL) { - ABC_FREE(work); - return(0); + ABC_FREE(work); + return(0); } Cudd_ApaCopy(digits,number,work); for (i = decimalDigits - 1; i >= 0; i--) { - remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); - decimal[i] = remainder; + remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); + decimal[i] = (unsigned char) remainder; } ABC_FREE(work); leadingzero = 1; for (i = 0; i < decimalDigits; i++) { - leadingzero = leadingzero && (decimal[i] == 0); - if ((!leadingzero) || (i == (decimalDigits - 1))) { - result = fprintf(fp,"%1d",decimal[i]); - if (result == EOF) { - ABC_FREE(decimal); - return(0); + leadingzero = leadingzero && (decimal[i] == 0); + if ((!leadingzero) || (i == (decimalDigits - 1))) { + result = fprintf(fp,"%1d",decimal[i]); + if (result == EOF) { + ABC_FREE(decimal); + return(0); + } } } - } ABC_FREE(decimal); return(1); @@ -575,36 +627,36 @@ Cudd_ApaPrintExponential( DdApaNumber work; unsigned char *decimal; int decimalDigits = (int) (digits * log10((double) DD_APA_BASE)) + 1; - + work = Cudd_NewApaNumber(digits); if (work == NULL) - return(0); + return(0); decimal = ABC_ALLOC(unsigned char, decimalDigits); if (decimal == NULL) { - ABC_FREE(work); - return(0); + ABC_FREE(work); + return(0); } Cudd_ApaCopy(digits,number,work); first = decimalDigits - 1; for (i = decimalDigits - 1; i >= 0; i--) { - remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); - decimal[i] = remainder; - if (remainder != 0) first = i; /* keep track of MS non-zero */ + remainder = Cudd_ApaShortDivision(digits,work,(DdApaDigit) 10,work); + decimal[i] = (unsigned char) remainder; + if (remainder != 0) first = i; /* keep track of MS non-zero */ } ABC_FREE(work); last = ddMin(first + precision, decimalDigits); for (i = first; i < last; i++) { - result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]); - if (result == EOF) { - ABC_FREE(decimal); - return(0); - } + result = fprintf(fp,"%s%1d",i == first+1 ? "." : "", decimal[i]); + if (result == EOF) { + ABC_FREE(decimal); + return(0); + } } ABC_FREE(decimal); result = fprintf(fp,"e+%d",decimalDigits - first - 1); if (result == EOF) { - return(0); + return(0); } return(1); @@ -635,9 +687,9 @@ Cudd_ApaCountMinterm( int nvars, int * digits) { - DdApaNumber max, min; + DdApaNumber max, min; st_table *table; - DdApaNumber i,count; + DdApaNumber i,count; background = manager->background; zero = Cudd_Not(manager->one); @@ -645,46 +697,46 @@ Cudd_ApaCountMinterm( *digits = Cudd_ApaNumberOfDigits(nvars+1); max = Cudd_NewApaNumber(*digits); if (max == NULL) { - return(NULL); + return(NULL); } Cudd_ApaPowerOfTwo(*digits,max,nvars); min = Cudd_NewApaNumber(*digits); if (min == NULL) { - ABC_FREE(max); - return(NULL); + ABC_FREE(max); + return(NULL); } Cudd_ApaSetToLiteral(*digits,min,0); - table = st_init_table(st_ptrcmp, st_ptrhash);; + table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) { - ABC_FREE(max); - ABC_FREE(min); - return(NULL); + ABC_FREE(max); + ABC_FREE(min); + return(NULL); } i = cuddApaCountMintermAux(Cudd_Regular(node),*digits,max,min,table); if (i == NULL) { - ABC_FREE(max); - ABC_FREE(min); - st_foreach(table, (ST_PFSR)cuddApaStCountfree, NULL); - st_free_table(table); - return(NULL); + ABC_FREE(max); + ABC_FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + return(NULL); } count = Cudd_NewApaNumber(*digits); if (count == NULL) { - ABC_FREE(max); - ABC_FREE(min); - st_foreach(table, (ST_PFSR)cuddApaStCountfree, NULL); - st_free_table(table); - if (Cudd_Regular(node)->ref == 1) ABC_FREE(i); - return(NULL); + ABC_FREE(max); + ABC_FREE(min); + st_foreach(table, cuddApaStCountfree, NULL); + st_free_table(table); + if (Cudd_Regular(node)->ref == 1) ABC_FREE(i); + return(NULL); } if (Cudd_IsComplement(node)) { - (void) Cudd_ApaSubtract(*digits,max,i,count); + (void) Cudd_ApaSubtract(*digits,max,i,count); } else { - Cudd_ApaCopy(*digits,i,count); + Cudd_ApaCopy(*digits,i,count); } ABC_FREE(max); ABC_FREE(min); - st_foreach(table, (ST_PFSR)cuddApaStCountfree, NULL); + st_foreach(table, cuddApaStCountfree, NULL); st_free_table(table); if (Cudd_Regular(node)->ref == 1) ABC_FREE(i); return(count); @@ -718,11 +770,11 @@ Cudd_ApaPrintMinterm( count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); if (count == NULL) - return(0); + return(0); result = Cudd_ApaPrintDecimal(fp,digits,count); ABC_FREE(count); if (fprintf(fp,"\n") == EOF) { - return(0); + return(0); } return(result); @@ -758,11 +810,11 @@ Cudd_ApaPrintMintermExp( count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); if (count == NULL) - return(0); + return(0); result = Cudd_ApaPrintExponential(fp,digits,count,precision); ABC_FREE(count); if (fprintf(fp,"\n") == EOF) { - return(0); + return(0); } return(result); @@ -796,7 +848,7 @@ Cudd_ApaPrintDensity( count = Cudd_ApaCountMinterm(dd,node,nvars,&digits); if (count == NULL) - return(0); + return(0); size = Cudd_DagSize(node); density = Cudd_NewApaNumber(digits); remainder = Cudd_ApaIntDivision(digits,count,size,density); @@ -805,7 +857,7 @@ Cudd_ApaPrintDensity( ABC_FREE(density); fractional = (unsigned int)((double)remainder / size * 1000000); if (fprintf(fp,".%u\n", fractional) == EOF) { - return(0); + return(0); } return(result); @@ -852,18 +904,18 @@ cuddApaCountMintermAux( st_table * table) { DdNode *Nt, *Ne; - DdApaNumber mint, mint1, mint2; - DdApaDigit carryout; + DdApaNumber mint, mint1, mint2; + DdApaDigit carryout; if (cuddIsConstant(node)) { - if (node == background || node == zero) { - return(min); - } else { - return(max); - } + if (node == background || node == zero) { + return(min); + } else { + return(max); + } } - if (node->ref > 1 && st_lookup(table, (char *)node, (char **)&mint)) { - return(mint); + if (node->ref > 1 && st_lookup(table, (const char *)node, (char **)&mint)) { + return(mint); } Nt = cuddT(node); Ne = cuddE(node); @@ -872,20 +924,20 @@ cuddApaCountMintermAux( if (mint1 == NULL) return(NULL); mint2 = cuddApaCountMintermAux(Cudd_Regular(Ne), digits, max, min, table); if (mint2 == NULL) { - if (Nt->ref == 1) ABC_FREE(mint1); - return(NULL); + if (Nt->ref == 1) ABC_FREE(mint1); + return(NULL); } mint = Cudd_NewApaNumber(digits); if (mint == NULL) { - if (Nt->ref == 1) ABC_FREE(mint1); - if (Cudd_Regular(Ne)->ref == 1) ABC_FREE(mint2); - return(NULL); + if (Nt->ref == 1) ABC_FREE(mint1); + if (Cudd_Regular(Ne)->ref == 1) ABC_FREE(mint2); + return(NULL); } if (Cudd_IsComplement(Ne)) { - (void) Cudd_ApaSubtract(digits,max,mint2,mint); - carryout = Cudd_ApaAdd(digits,mint1,mint,mint); + (void) Cudd_ApaSubtract(digits,max,mint2,mint); + carryout = Cudd_ApaAdd(digits,mint1,mint,mint); } else { - carryout = Cudd_ApaAdd(digits,mint1,mint2,mint); + carryout = Cudd_ApaAdd(digits,mint1,mint2,mint); } Cudd_ApaShiftRight(digits,carryout,mint,mint); /* If the refernce count of a child is 1, its minterm count @@ -893,12 +945,12 @@ cuddApaCountMintermAux( ** freed here. */ if (Nt->ref == 1) ABC_FREE(mint1); if (Cudd_Regular(Ne)->ref == 1) ABC_FREE(mint2); - + if (node->ref > 1) { - if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) { - ABC_FREE(mint); - return(NULL); - } + if (st_insert(table, (char *)node, (char *)mint) == ST_OUT_OF_MEM) { + ABC_FREE(mint); + return(NULL); + } } return(mint); @@ -922,7 +974,7 @@ cuddApaStCountfree( char * value, char * arg) { - DdApaNumber d; + DdApaNumber d; d = (DdApaNumber) value; ABC_FREE(d); diff --git a/src/bdd/cudd/cuddApprox.c b/src/bdd/cudd/cuddApprox.c index 9641aac0..1fdb595f 100644 --- a/src/bdd/cudd/cuddApprox.c +++ b/src/bdd/cudd/cuddApprox.c @@ -8,41 +8,68 @@ Description [External procedures provided by this module: <ul> - <li> Cudd_UnderApprox() - <li> Cudd_OverApprox() - <li> Cudd_RemapUnderApprox() - <li> Cudd_RemapOverApprox() - <li> Cudd_BiasedUnderApprox() - <li> Cudd_BiasedOverApprox() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddUnderApprox() - <li> cuddRemapUnderApprox() - <li> cuddBiasedUnderApprox() - </ul> - Static procedures included in this module: - <ul> - <li> gatherInfoAux() - <li> gatherInfo() - <li> computeSavings() - <li> UAmarkNodes() - <li> UAbuildSubset() - <li> updateRefs() - <li> RAmarkNodes() - <li> BAmarkNodes() - <li> RAbuildSubset() - </ul> - ] + <li> Cudd_UnderApprox() + <li> Cudd_OverApprox() + <li> Cudd_RemapUnderApprox() + <li> Cudd_RemapOverApprox() + <li> Cudd_BiasedUnderApprox() + <li> Cudd_BiasedOverApprox() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddUnderApprox() + <li> cuddRemapUnderApprox() + <li> cuddBiasedUnderApprox() + </ul> + Static procedures included in this module: + <ul> + <li> gatherInfoAux() + <li> gatherInfo() + <li> computeSavings() + <li> UAmarkNodes() + <li> UAbuildSubset() + <li> updateRefs() + <li> RAmarkNodes() + <li> BAmarkNodes() + <li> RAbuildSubset() + </ul> + ] SeeAlso [cuddSubsetHB.c cuddSubsetSP.c cuddGenCof.c] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no - warranty about the suitability of this software for any - purpose. It is presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -57,21 +84,22 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define NOTHING 0 -#define REPLACE_T 1 -#define REPLACE_E 2 -#define REPLACE_N 3 -#define REPLACE_TT 4 -#define REPLACE_TE 5 +#define NOTHING 0 +#define REPLACE_T 1 +#define REPLACE_E 2 +#define REPLACE_N 3 +#define REPLACE_TT 4 +#define REPLACE_TE 5 -#define DONT_CARE 0 -#define CARE 1 -#define TOTAL_CARE 2 -#define CARE_ERROR 3 +#define DONT_CARE 0 +#define CARE 1 +#define TOTAL_CARE 2 +#define CARE_ERROR 3 /*---------------------------------------------------------------------------*/ /* Stucture declarations */ @@ -90,25 +118,25 @@ ABC_NAMESPACE_IMPL_START ** reference count of the node from an internal node; and the flag ** that says whether the node should be replaced and how. */ typedef struct NodeData { - double mintermsP; /* minterms for the regular node */ - double mintermsN; /* minterms for the complemented node */ - int functionRef; /* references from within this function */ - char care; /* node intersects care set */ - char replace; /* replacement decision */ - short int parity; /* 1: even; 2: odd; 3: both */ - DdNode *resultP; /* result for even parity */ - DdNode *resultN; /* result for odd parity */ + double mintermsP; /* minterms for the regular node */ + double mintermsN; /* minterms for the complemented node */ + int functionRef; /* references from within this function */ + char care; /* node intersects care set */ + char replace; /* replacement decision */ + short int parity; /* 1: even; 2: odd; 3: both */ + DdNode *resultP; /* result for even parity */ + DdNode *resultN; /* result for odd parity */ } NodeData; typedef struct ApproxInfo { - DdNode *one; /* one constant */ - DdNode *zero; /* BDD zero constant */ - NodeData *page; /* per-node information */ - st_table *table; /* hash table to access the per-node info */ - int index; /* index of the current node */ - double max; /* max number of minterms */ - int size; /* how many nodes are left */ - double minterms; /* how many minterms are left */ + DdNode *one; /* one constant */ + DdNode *zero; /* BDD zero constant */ + NodeData *page; /* per-node information */ + st_table *table; /* hash table to access the per-node info */ + int index; /* index of the current node */ + double max; /* max number of minterms */ + int size; /* how many nodes are left */ + double minterms; /* how many minterms are left */ } ApproxInfo; /* Item of the queue used in the levelized traversal of the BDD. */ @@ -140,7 +168,7 @@ typedef struct LocalQueueItem { /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddApprox.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddApprox.c,v 1.27 2009/02/19 16:16:51 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -153,17 +181,17 @@ static char rcsid[] DD_UNUSED = "$Id: cuddApprox.c,v 1.1.1.1 2003/02/24 22:23:51 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void updateParity ARGS((DdNode *node, ApproxInfo *info, int newparity)); -static NodeData * gatherInfoAux ARGS((DdNode *node, ApproxInfo *info, int parity)); -static ApproxInfo * gatherInfo ARGS((DdManager *dd, DdNode *node, int numVars, int parity)); -static int computeSavings ARGS((DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue)); -static int updateRefs ARGS((DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue)); -static int UAmarkNodes ARGS((DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, int safe, double quality)); -static DdNode * UAbuildSubset ARGS((DdManager *dd, DdNode *node, ApproxInfo *info)); -static int RAmarkNodes ARGS((DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality)); -static int BAmarkNodes ARGS((DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality1, double quality0)); -static DdNode * RAbuildSubset ARGS((DdManager *dd, DdNode *node, ApproxInfo *info)); -static int BAapplyBias ARGS((DdManager *dd, DdNode *f, DdNode *b, ApproxInfo *info, DdHashTable *cache)); +static void updateParity (DdNode *node, ApproxInfo *info, int newparity); +static NodeData * gatherInfoAux (DdNode *node, ApproxInfo *info, int parity); +static ApproxInfo * gatherInfo (DdManager *dd, DdNode *node, int numVars, int parity); +static int computeSavings (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue); +static int updateRefs (DdManager *dd, DdNode *f, DdNode *skip, ApproxInfo *info, DdLevelQueue *queue); +static int UAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, int safe, double quality); +static DdNode * UAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info); +static int RAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality); +static int BAmarkNodes (DdManager *dd, DdNode *f, ApproxInfo *info, int threshold, double quality1, double quality0); +static DdNode * RAbuildSubset (DdManager *dd, DdNode *node, ApproxInfo *info); +static int BAapplyBias (DdManager *dd, DdNode *f, DdNode *b, ApproxInfo *info, DdHashTable *cache); /**AutomaticEnd***************************************************************/ @@ -208,8 +236,8 @@ Cudd_UnderApprox( DdNode *subset; do { - dd->reordered = 0; - subset = cuddUnderApprox(dd, f, numVars, threshold, safe, quality); + dd->reordered = 0; + subset = cuddUnderApprox(dd, f, numVars, threshold, safe, quality); } while (dd->reordered == 1); return(subset); @@ -256,8 +284,8 @@ Cudd_OverApprox( g = Cudd_Not(f); do { - dd->reordered = 0; - subset = cuddUnderApprox(dd, g, numVars, threshold, safe, quality); + dd->reordered = 0; + subset = cuddUnderApprox(dd, g, numVars, threshold, safe, quality); } while (dd->reordered == 1); return(Cudd_NotCond(subset, (subset != NULL))); @@ -299,8 +327,8 @@ Cudd_RemapUnderApprox( DdNode *subset; do { - dd->reordered = 0; - subset = cuddRemapUnderApprox(dd, f, numVars, threshold, quality); + dd->reordered = 0; + subset = cuddRemapUnderApprox(dd, f, numVars, threshold, quality); } while (dd->reordered == 1); return(subset); @@ -346,8 +374,8 @@ Cudd_RemapOverApprox( g = Cudd_Not(f); do { - dd->reordered = 0; - subset = cuddRemapUnderApprox(dd, g, numVars, threshold, quality); + dd->reordered = 0; + subset = cuddRemapUnderApprox(dd, g, numVars, threshold, quality); } while (dd->reordered == 1); return(Cudd_NotCond(subset, (subset != NULL))); @@ -394,9 +422,9 @@ Cudd_BiasedUnderApprox( DdNode *subset; do { - dd->reordered = 0; - subset = cuddBiasedUnderApprox(dd, f, b, numVars, threshold, quality1, - quality0); + dd->reordered = 0; + subset = cuddBiasedUnderApprox(dd, f, b, numVars, threshold, quality1, + quality0); } while (dd->reordered == 1); return(subset); @@ -445,9 +473,9 @@ Cudd_BiasedOverApprox( g = Cudd_Not(f); do { - dd->reordered = 0; - subset = cuddBiasedUnderApprox(dd, g, b, numVars, threshold, quality1, - quality0); + dd->reordered = 0; + subset = cuddBiasedUnderApprox(dd, g, b, numVars, threshold, quality1, + quality0); } while (dd->reordered == 1); return(Cudd_NotCond(subset, (subset != NULL))); @@ -493,39 +521,39 @@ cuddUnderApprox( int result; if (f == NULL) { - fprintf(dd->err, "Cannot subset, nil object\n"); - return(NULL); + fprintf(dd->err, "Cannot subset, nil object\n"); + return(NULL); } if (Cudd_IsConstant(f)) { - return(f); + return(f); } /* Create table where node data are accessible via a hash table. */ info = gatherInfo(dd, f, numVars, safe); if (info == NULL) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } /* Mark nodes that should be replaced by zero. */ result = UAmarkNodes(dd, f, info, threshold, safe, quality); if (result == 0) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - ABC_FREE(info->page); - st_free_table(info->table); - ABC_FREE(info); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + ABC_FREE(info->page); + st_free_table(info->table); + ABC_FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } /* Build the result. */ subset = UAbuildSubset(dd, f, info); #if 1 if (subset && info->size < Cudd_DagSize(subset)) - (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", - info->size, Cudd_DagSize(subset)); + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); #endif ABC_FREE(info->page); st_free_table(info->table); @@ -533,16 +561,16 @@ cuddUnderApprox( #ifdef DD_DEBUG if (subset != NULL) { - cuddRef(subset); + cuddRef(subset); #if 0 - (void) Cudd_DebugCheck(dd); - (void) Cudd_CheckKeys(dd); + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); #endif - if (!Cudd_bddLeq(dd, subset, f)) { - (void) fprintf(dd->err, "Wrong subset\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - } - cuddDeref(subset); + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + } + cuddDeref(subset); } #endif return(subset); @@ -582,40 +610,40 @@ cuddRemapUnderApprox( int result; if (f == NULL) { - fprintf(dd->err, "Cannot subset, nil object\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); } if (Cudd_IsConstant(f)) { - return(f); + return(f); } /* Create table where node data are accessible via a hash table. */ info = gatherInfo(dd, f, numVars, TRUE); if (info == NULL) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } /* Mark nodes that should be replaced by zero. */ result = RAmarkNodes(dd, f, info, threshold, quality); if (result == 0) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - ABC_FREE(info->page); - st_free_table(info->table); - ABC_FREE(info); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + ABC_FREE(info->page); + st_free_table(info->table); + ABC_FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } /* Build the result. */ subset = RAbuildSubset(dd, f, info); #if 1 if (subset && info->size < Cudd_DagSize(subset)) - (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", - info->size, Cudd_DagSize(subset)); + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); #endif ABC_FREE(info->page); st_free_table(info->table); @@ -623,16 +651,16 @@ cuddRemapUnderApprox( #ifdef DD_DEBUG if (subset != NULL) { - cuddRef(subset); + cuddRef(subset); #if 0 - (void) Cudd_DebugCheck(dd); - (void) Cudd_CheckKeys(dd); + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); #endif - if (!Cudd_bddLeq(dd, subset, f)) { - (void) fprintf(dd->err, "Wrong subset\n"); - } - cuddDeref(subset); - dd->errorCode = CUDD_INTERNAL_ERROR; + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + } + cuddDeref(subset); + dd->errorCode = CUDD_INTERNAL_ERROR; } #endif return(subset); @@ -667,61 +695,61 @@ cuddBiasedUnderApprox( int numVars /* maximum number of variables */, int threshold /* threshold under which approximation stops */, double quality1 /* minimum improvement for accepted changes when b=1 */, - double quality0 /* minimum improvement for accepted changes when b=1 */) + double quality0 /* minimum improvement for accepted changes when b=0 */) { ApproxInfo *info; DdNode *subset; int result; - DdHashTable *cache; + DdHashTable *cache; if (f == NULL) { - fprintf(dd->err, "Cannot subset, nil object\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); } if (Cudd_IsConstant(f)) { - return(f); + return(f); } /* Create table where node data are accessible via a hash table. */ info = gatherInfo(dd, f, numVars, TRUE); if (info == NULL) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } cache = cuddHashTableInit(dd,2,2); result = BAapplyBias(dd, Cudd_Regular(f), b, info, cache); if (result == CARE_ERROR) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - cuddHashTableQuit(cache); - ABC_FREE(info->page); - st_free_table(info->table); - ABC_FREE(info); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + cuddHashTableQuit(cache); + ABC_FREE(info->page); + st_free_table(info->table); + ABC_FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } cuddHashTableQuit(cache); /* Mark nodes that should be replaced by zero. */ result = BAmarkNodes(dd, f, info, threshold, quality1, quality0); if (result == 0) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - ABC_FREE(info->page); - st_free_table(info->table); - ABC_FREE(info); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + ABC_FREE(info->page); + st_free_table(info->table); + ABC_FREE(info); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } /* Build the result. */ subset = RAbuildSubset(dd, f, info); #if 1 if (subset && info->size < Cudd_DagSize(subset)) - (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", - info->size, Cudd_DagSize(subset)); + (void) fprintf(dd->err, "Wrong prediction: %d versus actual %d\n", + info->size, Cudd_DagSize(subset)); #endif ABC_FREE(info->page); st_free_table(info->table); @@ -729,16 +757,16 @@ cuddBiasedUnderApprox( #ifdef DD_DEBUG if (subset != NULL) { - cuddRef(subset); + cuddRef(subset); #if 0 - (void) Cudd_DebugCheck(dd); - (void) Cudd_CheckKeys(dd); + (void) Cudd_DebugCheck(dd); + (void) Cudd_CheckKeys(dd); #endif - if (!Cudd_bddLeq(dd, subset, f)) { - (void) fprintf(dd->err, "Wrong subset\n"); - } - cuddDeref(subset); - dd->errorCode = CUDD_INTERNAL_ERROR; + if (!Cudd_bddLeq(dd, subset, f)) { + (void) fprintf(dd->err, "Wrong subset\n"); + } + cuddDeref(subset); + dd->errorCode = CUDD_INTERNAL_ERROR; } #endif return(subset); @@ -772,16 +800,16 @@ updateParity( NodeData *infoN; DdNode *E; - if (!st_lookup(info->table, (char *)node, (char **)&infoN)) return; + if (!st_lookup(info->table, (const char *)node, (char **)&infoN)) return; if ((infoN->parity & newparity) != 0) return; - infoN->parity |= newparity; + infoN->parity |= (short) newparity; if (Cudd_IsConstant(node)) return; updateParity(cuddT(node),info,newparity); E = cuddE(node); if (Cudd_IsComplement(E)) { - updateParity(Cudd_Not(E),info,3-newparity); + updateParity(Cudd_Not(E),info,3-newparity); } else { - updateParity(E,info,newparity); + updateParity(E,info,newparity); } return; @@ -811,18 +839,18 @@ gatherInfoAux( ApproxInfo * info /* info on BDD */, int parity /* gather parity information */) { - DdNode *N, *Nt, *Ne; + DdNode *N, *Nt, *Ne; NodeData *infoN, *infoT, *infoE; N = Cudd_Regular(node); /* Check whether entry for this node exists. */ - if (st_lookup(info->table, (char *)N, (char **)&infoN)) { - if (parity) { - /* Update parity and propagate. */ - updateParity(N, info, 1 + (int) Cudd_IsComplement(node)); - } - return(infoN); + if (st_lookup(info->table, (const char *)N, (char **)&infoN)) { + if (parity) { + /* Update parity and propagate. */ + updateParity(N, info, 1 + (int) Cudd_IsComplement(node)); + } + return(infoN); } /* Compute the cofactors. */ @@ -839,21 +867,21 @@ gatherInfoAux( /* Point to the correct location in the page. */ infoN = &(info->page[info->index++]); - infoN->parity |= 1 + (short) Cudd_IsComplement(node); + infoN->parity |= (short) (1 + Cudd_IsComplement(node)); infoN->mintermsP = infoT->mintermsP/2; infoN->mintermsN = infoT->mintermsN/2; if (Cudd_IsComplement(Ne) ^ Cudd_IsComplement(node)) { - infoN->mintermsP += infoE->mintermsN/2; - infoN->mintermsN += infoE->mintermsP/2; + infoN->mintermsP += infoE->mintermsN/2; + infoN->mintermsN += infoE->mintermsP/2; } else { - infoN->mintermsP += infoE->mintermsP/2; - infoN->mintermsN += infoE->mintermsN/2; + infoN->mintermsP += infoE->mintermsP/2; + infoN->mintermsN += infoE->mintermsN/2; } /* Insert entry for the node in the table. */ if (st_insert(info->table,(char *)N, (char *)infoN) == ST_OUT_OF_MEM) { - return(NULL); + return(NULL); } return(infoN); @@ -882,7 +910,7 @@ gatherInfo( int numVars /* number of variables node depends on */, int parity /* gather parity information */) { - ApproxInfo *info; + ApproxInfo *info; NodeData *infoTop; /* If user did not give numVars value, set it to the maximum @@ -891,13 +919,13 @@ gatherInfo( ** log gives. */ if (numVars == 0) { - numVars = DBL_MAX_EXP - 1; + numVars = DBL_MAX_EXP - 1; } info = ABC_ALLOC(ApproxInfo,1); if (info == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } info->max = pow(2.0,(double) numVars); info->one = DD_ONE(dd); @@ -910,41 +938,41 @@ gatherInfo( ** that stores the per-node information. */ info->page = ABC_ALLOC(NodeData,info->size); if (info->page == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(info); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(info); + return(NULL); } memset(info->page, 0, info->size * sizeof(NodeData)); /* clear all page */ - info->table = st_init_table(st_ptrcmp, st_ptrhash);; + info->table = st_init_table(st_ptrcmp,st_ptrhash); if (info->table == NULL) { - ABC_FREE(info->page); - ABC_FREE(info); - return(NULL); + ABC_FREE(info->page); + ABC_FREE(info); + return(NULL); } /* We visit the DAG in post-order DFS. Hence, the constant node is ** in first position, and the root of the DAG is in last position. */ /* Info for the constant node: Initialize only fields different from 0. */ if (st_insert(info->table, (char *)info->one, (char *)info->page) == ST_OUT_OF_MEM) { - ABC_FREE(info->page); - ABC_FREE(info); - st_free_table(info->table); - return(NULL); + ABC_FREE(info->page); + ABC_FREE(info); + st_free_table(info->table); + return(NULL); } info->page[0].mintermsP = info->max; info->index = 1; infoTop = gatherInfoAux(node,info,parity); if (infoTop == NULL) { - ABC_FREE(info->page); - st_free_table(info->table); - ABC_FREE(info); - return(NULL); + ABC_FREE(info->page); + st_free_table(info->table); + ABC_FREE(info); + return(NULL); } if (Cudd_IsComplement(node)) { - info->minterms = infoTop->mintermsN; + info->minterms = infoTop->mintermsN; } else { - info->minterms = infoTop->mintermsP; + info->minterms = infoTop->mintermsP; } infoTop->functionRef = 1; @@ -988,36 +1016,36 @@ computeSavings( ** count is set equal to the function reference count so that the ** search will continue from it when it is retrieved. */ item = (LocalQueueItem *) - cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); if (item == NULL) - return(0); - (void) st_lookup(info->table, (char *)node, (char **)&infoN); + return(0); + (void) st_lookup(info->table, (const char *)node, (char **)&infoN); item->localRef = infoN->functionRef; /* Process the queue. */ while (queue->first != NULL) { - item = (LocalQueueItem *) queue->first; - node = item->node; - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); - if (node == skip) continue; - (void) st_lookup(info->table, (char *)node, (char **)&infoN); - if (item->localRef != infoN->functionRef) { - /* This node is shared. */ - continue; - } - savings++; - if (!cuddIsConstant(cuddT(node))) { - item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), - cuddI(dd,cuddT(node)->index)); - if (item == NULL) return(0); - item->localRef++; - } - if (!Cudd_IsConstant(cuddE(node))) { - item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), - cuddI(dd,Cudd_Regular(cuddE(node))->index)); - if (item == NULL) return(0); - item->localRef++; - } + item = (LocalQueueItem *) queue->first; + node = item->node; + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + if (node == skip) continue; + (void) st_lookup(info->table, (const char *)node, (char **)&infoN); + if (item->localRef != infoN->functionRef) { + /* This node is shared. */ + continue; + } + savings++; + if (!cuddIsConstant(cuddT(node))) { + item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (item == NULL) return(0); + item->localRef++; + } + if (!Cudd_IsConstant(cuddE(node))) { + item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (item == NULL) return(0); + item->localRef++; + } } #ifdef DD_DEBUG @@ -1060,45 +1088,43 @@ updateRefs( ** when it is retrieved. */ item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); if (item == NULL) - return(0); - (void) st_lookup(info->table, (char *)node, (char **)&infoN); + return(0); + (void) st_lookup(info->table, (const char *)node, (char **)&infoN); infoN->functionRef = 0; if (skip != NULL) { - /* Increase the function reference count of the node to be skipped - ** by 1 to account for the node pointing to it that will be created. */ - skip = Cudd_Regular(skip); - (void) st_lookup(info->table, (char *)skip, (char **)&infoN); - infoN->functionRef++; + /* Increase the function reference count of the node to be skipped + ** by 1 to account for the node pointing to it that will be created. */ + skip = Cudd_Regular(skip); + (void) st_lookup(info->table, (const char *)skip, (char **)&infoN); + infoN->functionRef++; } /* Process the queue. */ while (queue->first != NULL) { - item = (LocalQueueItem *) queue->first; - node = item->node; - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); - (void) st_lookup(info->table, (char *)node, (char **)&infoN); - if (infoN->functionRef != 0) { - /* This node is shared or must be skipped. */ - continue; - } - savings++; - if (!cuddIsConstant(cuddT(node))) { - item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), - cuddI(dd,cuddT(node)->index)); - if (item == NULL) return(0); - (void) st_lookup(info->table, (char *)cuddT(node), - (char **)&infoN); - infoN->functionRef--; - } - if (!Cudd_IsConstant(cuddE(node))) { - item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), - cuddI(dd,Cudd_Regular(cuddE(node))->index)); - if (item == NULL) return(0); - (void) st_lookup(info->table, (char *)Cudd_Regular(cuddE(node)), - (char **)&infoN); - infoN->functionRef--; - } + item = (LocalQueueItem *) queue->first; + node = item->node; + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + (void) st_lookup(info->table, (const char *)node, (char **)&infoN); + if (infoN->functionRef != 0) { + /* This node is shared or must be skipped. */ + continue; + } + savings++; + if (!cuddIsConstant(cuddT(node))) { + item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (item == NULL) return(0); + (void) st_lookup(info->table, (const char *)cuddT(node), (char **)&infoN); + infoN->functionRef--; + } + if (!Cudd_IsConstant(cuddE(node))) { + item = (LocalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (item == NULL) return(0); + (void) st_lookup(info->table, (const char *)Cudd_Regular(cuddE(node)), (char **)&infoN); + infoN->functionRef--; + } } #ifdef DD_DEBUG @@ -1142,88 +1168,88 @@ UAmarkNodes( #if 0 (void) printf("initial size = %d initial minterms = %g\n", - info->size, info->minterms); + info->size, info->minterms); #endif queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); if (queue == NULL) { - return(0); + return(0); } localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), - dd->initSlots); + dd->initSlots); if (localQueue == NULL) { - cuddLevelQueueQuit(queue); - return(0); + cuddLevelQueueQuit(queue); + return(0); } node = Cudd_Regular(f); item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); if (item == NULL) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); } if (Cudd_IsComplement(f)) { - item->impactP = 0.0; - item->impactN = 1.0; + item->impactP = 0.0; + item->impactN = 1.0; } else { - item->impactP = 1.0; - item->impactN = 0.0; + item->impactP = 1.0; + item->impactN = 0.0; } while (queue->first != NULL) { - /* If the size of the subset is below the threshold, quit. */ - if (info->size <= threshold) - break; - item = (GlobalQueueItem *) queue->first; - node = item->node; - node = Cudd_Regular(node); - (void) st_lookup(info->table, (char *)node, (char **)&infoN); - if (safe && infoN->parity == 3) { + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; + node = Cudd_Regular(node); + (void) st_lookup(info->table, (const char *)node, (char **)&infoN); + if (safe && infoN->parity == 3) { + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; + } + impactP = item->impactP; + impactN = item->impactN; + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,NULL,info,localQueue); + if (savings == 0) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); - continue; - } - impactP = item->impactP; - impactN = item->impactN; - numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; - savings = computeSavings(dd,node,NULL,info,localQueue); - if (savings == 0) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); - } - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); #if 0 - (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", - node, impactP, impactN, numOnset, savings); + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); #endif - if ((1 - numOnset / info->minterms) > - quality * (1 - (double) savings / info->size)) { - infoN->replace = TRUE; - info->size -= savings; - info->minterms -=numOnset; + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = TRUE; + info->size -= savings; + info->minterms -=numOnset; #if 0 - (void) printf("replace: new size = %d new minterms = %g\n", - info->size, info->minterms); + (void) printf("replace: new size = %d new minterms = %g\n", + info->size, info->minterms); #endif - savings -= updateRefs(dd,node,NULL,info,localQueue); - assert(savings == 0); - continue; - } - if (!cuddIsConstant(cuddT(node))) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), - cuddI(dd,cuddT(node)->index)); - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; - } - if (!Cudd_IsConstant(cuddE(node))) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), - cuddI(dd,Cudd_Regular(cuddE(node))->index)); - if (Cudd_IsComplement(cuddE(node))) { - item->impactP += impactN/2.0; - item->impactN += impactP/2.0; - } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; + savings -= updateRefs(dd,node,NULL,info,localQueue); + assert(savings == 0); + continue; + } + if (!cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + if (!Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } } - } } cuddLevelQueueQuit(queue); @@ -1257,28 +1283,28 @@ UAbuildSubset( NodeData *infoN; if (Cudd_IsConstant(node)) - return(node); + return(node); N = Cudd_Regular(node); - if (st_lookup(info->table, (char *)N, (char **)&infoN)) { - if (infoN->replace == TRUE) { - return(info->zero); - } - if (N == node ) { - if (infoN->resultP != NULL) { - return(infoN->resultP); + if (st_lookup(info->table, (const char *)N, (char **)&infoN)) { + if (infoN->replace == TRUE) { + return(info->zero); } - } else { - if (infoN->resultN != NULL) { - return(infoN->resultN); + if (N == node ) { + if (infoN->resultP != NULL) { + return(infoN->resultP); + } + } else { + if (infoN->resultN != NULL) { + return(infoN->resultN); + } } - } } else { - (void) fprintf(dd->err, - "Something is wrong, ought to be in info table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + (void) fprintf(dd->err, + "Something is wrong, ought to be in info table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node)); @@ -1286,42 +1312,42 @@ UAbuildSubset( t = UAbuildSubset(dd, Nt, info); if (t == NULL) { - return(NULL); + return(NULL); } cuddRef(t); e = UAbuildSubset(dd, Ne, info); if (e == NULL) { - Cudd_RecursiveDeref(dd,t); - return(NULL); + Cudd_RecursiveDeref(dd,t); + return(NULL); } cuddRef(e); if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - r = Cudd_Not(r); + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); } else { - r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - Cudd_RecursiveDeref(dd, t); - return(NULL); - } + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } } cuddDeref(t); cuddDeref(e); if (N == node) { - infoN->resultP = r; + infoN->resultP = r; } else { - infoN->resultN = r; + infoN->resultN = r; } return(r); @@ -1363,277 +1389,266 @@ RAmarkNodes( #if 0 (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n", - info->size, info->minterms); + info->size, info->minterms); #endif queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); if (queue == NULL) { - return(0); + return(0); } localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), - dd->initSlots); + dd->initSlots); if (localQueue == NULL) { - cuddLevelQueueQuit(queue); - return(0); + cuddLevelQueueQuit(queue); + return(0); } /* Enqueue regular pointer to root and initialize impact. */ node = Cudd_Regular(f); item = (GlobalQueueItem *) - cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); if (item == NULL) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); } if (Cudd_IsComplement(f)) { - item->impactP = 0.0; - item->impactN = 1.0; + item->impactP = 0.0; + item->impactN = 1.0; } else { - item->impactP = 1.0; - item->impactN = 0.0; + item->impactP = 1.0; + item->impactN = 0.0; } /* The nodes retrieved here are guaranteed to be non-terminal. ** The initial node is not terminal because constant nodes are ** dealt with in the calling procedure. Subsequent nodes are inserted ** only if they are not terminal. */ while (queue->first != NULL) { - /* If the size of the subset is below the threshold, quit. */ - if (info->size <= threshold) - break; - item = (GlobalQueueItem *) queue->first; - node = item->node; -#ifdef DD_DEBUG - assert(item->impactP >= 0 && item->impactP <= 1.0); - assert(item->impactN >= 0 && item->impactN <= 1.0); - assert(!Cudd_IsComplement(node)); - assert(!Cudd_IsConstant(node)); -#endif - if (!st_lookup(info->table, (char *)node, (char **)&infoN)) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); - } + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; #ifdef DD_DEBUG - assert(infoN->parity >= 1 && infoN->parity <= 3); + assert(item->impactP >= 0 && item->impactP <= 1.0); + assert(item->impactN >= 0 && item->impactN <= 1.0); + assert(!Cudd_IsComplement(node)); + assert(!Cudd_IsConstant(node)); #endif - if (infoN->parity == 3) { - /* This node can be reached through paths of different parity. - ** It is not safe to replace it, because remapping will give - ** an incorrect result, while replacement by 0 may cause node - ** splitting. */ - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); - continue; - } - T = cuddT(node); - E = cuddE(node); - shared = NULL; - impactP = item->impactP; - impactN = item->impactN; - if (Cudd_bddLeq(dd,T,E)) { - /* Here we know that E is regular. */ -#ifdef DD_DEBUG - assert(!Cudd_IsComplement(E)); -#endif - (void) st_lookup(info->table, (char *)T, (char **)&infoT); - (void) st_lookup(info->table, (char *)E, (char **)&infoE); - if (infoN->parity == 1) { - impact = impactP; - minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; - if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { - savings = 1 + computeSavings(dd,E,NULL,info,localQueue); - if (savings == 1) { + if (!st_lookup(info->table, (const char *)node, (char **)&infoN)) { cuddLevelQueueQuit(queue); cuddLevelQueueQuit(localQueue); return(0); - } - } else { - savings = 1; } - replace = REPLACE_E; - } else { #ifdef DD_DEBUG - assert(infoN->parity == 2); + assert(infoN->parity >= 1 && infoN->parity <= 3); #endif - impact = impactN; - minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; - if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { - savings = 1 + computeSavings(dd,T,NULL,info,localQueue); - if (savings == 1) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); - } - } else { - savings = 1; - } - replace = REPLACE_T; + if (infoN->parity == 3) { + /* This node can be reached through paths of different parity. + ** It is not safe to replace it, because remapping will give + ** an incorrect result, while replacement by 0 may cause node + ** splitting. */ + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; } - numOnset = impact * minterms; - } else if (Cudd_bddLeq(dd,E,T)) { - /* Here E may be complemented. */ - DdNode *Ereg = Cudd_Regular(E); - (void) st_lookup(info->table, (char *)T, (char **)&infoT); - (void) st_lookup(info->table, (char *)Ereg, (char **)&infoE); - if (infoN->parity == 1) { - impact = impactP; - minterms = infoT->mintermsP/2.0 - - ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; - if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { - savings = 1 + computeSavings(dd,T,NULL,info,localQueue); - if (savings == 1) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + T = cuddT(node); + E = cuddE(node); + shared = NULL; + impactP = item->impactP; + impactN = item->impactN; + if (Cudd_bddLeq(dd,T,E)) { + /* Here we know that E is regular. */ +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(E)); +#endif + (void) st_lookup(info->table, (const char *)T, (char **)&infoT); + (void) st_lookup(info->table, (const char *)E, (char **)&infoE); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; } - } else { - savings = 1; - } - replace = REPLACE_T; - } else { + numOnset = impact * minterms; + } else if (Cudd_bddLeq(dd,E,T)) { + /* Here E may be complemented. */ + DdNode *Ereg = Cudd_Regular(E); + (void) st_lookup(info->table, (const char *)T, (char **)&infoT); + (void) st_lookup(info->table, (const char *)Ereg, (char **)&infoE); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoT->mintermsP/2.0 - + ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } else { #ifdef DD_DEBUG - assert(infoN->parity == 2); + assert(infoN->parity == 2); #endif - impact = impactN; - minterms = ((E == Ereg) ? infoE->mintermsN : - infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; - if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { - savings = 1 + computeSavings(dd,E,NULL,info,localQueue); - if (savings == 1) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + impact = impactN; + minterms = ((E == Ereg) ? infoE->mintermsN : + infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; } + numOnset = impact * minterms; } else { - savings = 1; - } - replace = REPLACE_E; - } - numOnset = impact * minterms; - } else { - DdNode *Ereg = Cudd_Regular(E); - DdNode *TT = cuddT(T); - DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); - if (T->index == Ereg->index && TT == ET) { - shared = TT; - replace = REPLACE_TT; - } else { - DdNode *TE = cuddE(T); - DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); - if (T->index == Ereg->index && TE == EE) { - shared = TE; - replace = REPLACE_TE; - } else { - replace = REPLACE_N; - } - } - numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; - savings = computeSavings(dd,node,shared,info,localQueue); - if (shared != NULL) { - NodeData *infoS; - (void) st_lookup(info->table, (char *)Cudd_Regular(shared), - (char **)&infoS); - if (Cudd_IsComplement(shared)) { - numOnset -= (infoS->mintermsN * impactP + - infoS->mintermsP * impactN)/2.0; - } else { - numOnset -= (infoS->mintermsP * impactP + - infoS->mintermsN * impactN)/2.0; - } - savings--; + DdNode *Ereg = Cudd_Regular(E); + DdNode *TT = cuddT(T); + DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TT == ET) { + shared = TT; + replace = REPLACE_TT; + } else { + DdNode *TE = cuddE(T); + DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TE == EE) { + shared = TE; + replace = REPLACE_TE; + } else { + replace = REPLACE_N; + } + } + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,shared,info,localQueue); + if (shared != NULL) { + NodeData *infoS; + (void) st_lookup(info->table, (const char *)Cudd_Regular(shared), (char **)&infoS); + if (Cudd_IsComplement(shared)) { + numOnset -= (infoS->mintermsN * impactP + + infoS->mintermsP * impactN)/2.0; + } else { + numOnset -= (infoS->mintermsP * impactP + + infoS->mintermsN * impactN)/2.0; + } + savings--; + } } - } - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); #if 0 - if (replace == REPLACE_T || replace == REPLACE_E) - (void) printf("node %p: impact = %g numOnset = %g savings %d\n", - node, impact, numOnset, savings); - else - (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", - node, impactP, impactN, numOnset, savings); + if (replace == REPLACE_T || replace == REPLACE_E) + (void) printf("node %p: impact = %g numOnset = %g savings %d\n", + node, impact, numOnset, savings); + else + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); #endif - if ((1 - numOnset / info->minterms) > - quality * (1 - (double) savings / info->size)) { - infoN->replace = replace; - info->size -= savings; - info->minterms -=numOnset; + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = (char) replace; + info->size -= savings; + info->minterms -=numOnset; #if 0 - (void) printf("remap(%d): new size = %d new minterms = %g\n", - replace, info->size, info->minterms); + (void) printf("remap(%d): new size = %d new minterms = %g\n", + replace, info->size, info->minterms); #endif - if (replace == REPLACE_N) { - savings -= updateRefs(dd,node,NULL,info,localQueue); - } else if (replace == REPLACE_T) { - savings -= updateRefs(dd,node,E,info,localQueue); - } else if (replace == REPLACE_E) { - savings -= updateRefs(dd,node,T,info,localQueue); - } else { + if (replace == REPLACE_N) { + savings -= updateRefs(dd,node,NULL,info,localQueue); + } else if (replace == REPLACE_T) { + savings -= updateRefs(dd,node,E,info,localQueue); + } else if (replace == REPLACE_E) { + savings -= updateRefs(dd,node,T,info,localQueue); + } else { #ifdef DD_DEBUG - assert(replace == REPLACE_TT || replace == REPLACE_TE); + assert(replace == REPLACE_TT || replace == REPLACE_TE); #endif - savings -= updateRefs(dd,node,shared,info,localQueue) - 1; - } - assert(savings == 0); - } else { - replace = NOTHING; - } - if (replace == REPLACE_N) continue; - if ((replace == REPLACE_E || replace == NOTHING) && - !cuddIsConstant(cuddT(node))) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), - cuddI(dd,cuddT(node)->index)); - if (replace == REPLACE_E) { - item->impactP += impactP; - item->impactN += impactN; - } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; - } - } - if ((replace == REPLACE_T || replace == NOTHING) && - !Cudd_IsConstant(cuddE(node))) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), - cuddI(dd,Cudd_Regular(cuddE(node))->index)); - if (Cudd_IsComplement(cuddE(node))) { - if (replace == REPLACE_T) { - item->impactP += impactN; - item->impactN += impactP; + savings -= updateRefs(dd,node,shared,info,localQueue) - 1; + } + assert(savings == 0); } else { - item->impactP += impactN/2.0; - item->impactN += impactP/2.0; + replace = NOTHING; } - } else { - if (replace == REPLACE_T) { - item->impactP += impactP; - item->impactN += impactN; - } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; - } - } - } - if ((replace == REPLACE_TT || replace == REPLACE_TE) && - !Cudd_IsConstant(shared)) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), - cuddI(dd,Cudd_Regular(shared)->index)); - if (Cudd_IsComplement(shared)) { - if (replace == REPLACE_T) { - item->impactP += impactN; - item->impactN += impactP; - } else { - item->impactP += impactN/2.0; - item->impactN += impactP/2.0; + if (replace == REPLACE_N) continue; + if ((replace == REPLACE_E || replace == NOTHING) && + !cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (replace == REPLACE_E) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } } - } else { - if (replace == REPLACE_T) { - item->impactP += impactP; - item->impactN += impactN; - } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; + if ((replace == REPLACE_T || replace == NOTHING) && + !Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } } + if ((replace == REPLACE_TT || replace == REPLACE_TE) && + !Cudd_IsConstant(shared)) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), + cuddI(dd,Cudd_Regular(shared)->index)); + if (Cudd_IsComplement(shared)) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactP; + item->impactN += impactN; + } } } - } cuddLevelQueueQuit(queue); cuddLevelQueueQuit(localQueue); @@ -1678,278 +1693,277 @@ BAmarkNodes( #if 0 (void) fprintf(dd->out,"initial size = %d initial minterms = %g\n", - info->size, info->minterms); + info->size, info->minterms); #endif queue = cuddLevelQueueInit(dd->size,sizeof(GlobalQueueItem),info->size); if (queue == NULL) { - return(0); + return(0); } localQueue = cuddLevelQueueInit(dd->size,sizeof(LocalQueueItem), - dd->initSlots); + dd->initSlots); if (localQueue == NULL) { - cuddLevelQueueQuit(queue); - return(0); + cuddLevelQueueQuit(queue); + return(0); } /* Enqueue regular pointer to root and initialize impact. */ node = Cudd_Regular(f); item = (GlobalQueueItem *) - cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); + cuddLevelQueueEnqueue(queue,node,cuddI(dd,node->index)); if (item == NULL) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); } if (Cudd_IsComplement(f)) { - item->impactP = 0.0; - item->impactN = 1.0; + item->impactP = 0.0; + item->impactN = 1.0; } else { - item->impactP = 1.0; - item->impactN = 0.0; + item->impactP = 1.0; + item->impactN = 0.0; } /* The nodes retrieved here are guaranteed to be non-terminal. ** The initial node is not terminal because constant nodes are ** dealt with in the calling procedure. Subsequent nodes are inserted ** only if they are not terminal. */ while (queue->first != NULL) { - /* If the size of the subset is below the threshold, quit. */ - if (info->size <= threshold) - break; - item = (GlobalQueueItem *) queue->first; - node = item->node; + /* If the size of the subset is below the threshold, quit. */ + if (info->size <= threshold) + break; + item = (GlobalQueueItem *) queue->first; + node = item->node; #ifdef DD_DEBUG - assert(item->impactP >= 0 && item->impactP <= 1.0); - assert(item->impactN >= 0 && item->impactN <= 1.0); - assert(!Cudd_IsComplement(node)); - assert(!Cudd_IsConstant(node)); + assert(item->impactP >= 0 && item->impactP <= 1.0); + assert(item->impactN >= 0 && item->impactN <= 1.0); + assert(!Cudd_IsComplement(node)); + assert(!Cudd_IsConstant(node)); #endif - if (!st_lookup(info->table, (char *)node, (char **)&infoN)) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); - } - quality = infoN->care ? quality1 : quality0; -#ifdef DD_DEBUG - assert(infoN->parity >= 1 && infoN->parity <= 3); -#endif - if (infoN->parity == 3) { - /* This node can be reached through paths of different parity. - ** It is not safe to replace it, because remapping will give - ** an incorrect result, while replacement by 0 may cause node - ** splitting. */ - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); - continue; - } - T = cuddT(node); - E = cuddE(node); - shared = NULL; - impactP = item->impactP; - impactN = item->impactN; - if (Cudd_bddLeq(dd,T,E)) { - /* Here we know that E is regular. */ -#ifdef DD_DEBUG - assert(!Cudd_IsComplement(E)); -#endif - (void) st_lookup(info->table, (char *)T, (char **)&infoT); - (void) st_lookup(info->table, (char *)E, (char **)&infoE); - if (infoN->parity == 1) { - impact = impactP; - minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; - if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { - savings = 1 + computeSavings(dd,E,NULL,info,localQueue); - if (savings == 1) { + if (!st_lookup(info->table, (const char *)node, (char **)&infoN)) { cuddLevelQueueQuit(queue); cuddLevelQueueQuit(localQueue); return(0); - } - } else { - savings = 1; } - replace = REPLACE_E; - } else { + quality = infoN->care ? quality1 : quality0; #ifdef DD_DEBUG - assert(infoN->parity == 2); + assert(infoN->parity >= 1 && infoN->parity <= 3); #endif - impact = impactN; - minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; - if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { - savings = 1 + computeSavings(dd,T,NULL,info,localQueue); - if (savings == 1) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); - } - } else { - savings = 1; - } - replace = REPLACE_T; + if (infoN->parity == 3) { + /* This node can be reached through paths of different parity. + ** It is not safe to replace it, because remapping will give + ** an incorrect result, while replacement by 0 may cause node + ** splitting. */ + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + continue; } - numOnset = impact * minterms; - } else if (Cudd_bddLeq(dd,E,T)) { - /* Here E may be complemented. */ - DdNode *Ereg = Cudd_Regular(E); - (void) st_lookup(info->table, (char *)T, (char **)&infoT); - (void) st_lookup(info->table, (char *)Ereg, (char **)&infoE); - if (infoN->parity == 1) { - impact = impactP; - minterms = infoT->mintermsP/2.0 - - ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; - if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { - savings = 1 + computeSavings(dd,T,NULL,info,localQueue); - if (savings == 1) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + T = cuddT(node); + E = cuddE(node); + shared = NULL; + impactP = item->impactP; + impactN = item->impactN; + if (Cudd_bddLeq(dd,T,E)) { + /* Here we know that E is regular. */ +#ifdef DD_DEBUG + assert(!Cudd_IsComplement(E)); +#endif + (void) st_lookup(info->table, (const char *)T, (char **)&infoT); + (void) st_lookup(info->table, (const char *)E, (char **)&infoE); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoE->mintermsP/2.0 - infoT->mintermsP/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; + } else { +#ifdef DD_DEBUG + assert(infoN->parity == 2); +#endif + impact = impactN; + minterms = infoT->mintermsN/2.0 - infoE->mintermsN/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; } - } else { - savings = 1; - } - replace = REPLACE_T; - } else { + numOnset = impact * minterms; + } else if (Cudd_bddLeq(dd,E,T)) { + /* Here E may be complemented. */ + DdNode *Ereg = Cudd_Regular(E); + (void) st_lookup(info->table, (const char *)T, (char **)&infoT); + (void) st_lookup(info->table, (const char *)Ereg, (char **)&infoE); + if (infoN->parity == 1) { + impact = impactP; + minterms = infoT->mintermsP/2.0 - + ((E == Ereg) ? infoE->mintermsP : infoE->mintermsN)/2.0; + if (infoT->functionRef == 1 && !Cudd_IsConstant(T)) { + savings = 1 + computeSavings(dd,T,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_T; + } else { #ifdef DD_DEBUG - assert(infoN->parity == 2); + assert(infoN->parity == 2); #endif - impact = impactN; - minterms = ((E == Ereg) ? infoE->mintermsN : - infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; - if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { - savings = 1 + computeSavings(dd,E,NULL,info,localQueue); - if (savings == 1) { - cuddLevelQueueQuit(queue); - cuddLevelQueueQuit(localQueue); - return(0); + impact = impactN; + minterms = ((E == Ereg) ? infoE->mintermsN : + infoE->mintermsP)/2.0 - infoT->mintermsN/2.0; + if (infoE->functionRef == 1 && !Cudd_IsConstant(E)) { + savings = 1 + computeSavings(dd,E,NULL,info,localQueue); + if (savings == 1) { + cuddLevelQueueQuit(queue); + cuddLevelQueueQuit(localQueue); + return(0); + } + } else { + savings = 1; + } + replace = REPLACE_E; } + numOnset = impact * minterms; } else { - savings = 1; - } - replace = REPLACE_E; - } - numOnset = impact * minterms; - } else { - DdNode *Ereg = Cudd_Regular(E); - DdNode *TT = cuddT(T); - DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); - if (T->index == Ereg->index && TT == ET) { - shared = TT; - replace = REPLACE_TT; - } else { - DdNode *TE = cuddE(T); - DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); - if (T->index == Ereg->index && TE == EE) { - shared = TE; - replace = REPLACE_TE; - } else { - replace = REPLACE_N; - } - } - numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; - savings = computeSavings(dd,node,shared,info,localQueue); - if (shared != NULL) { - NodeData *infoS; - (void) st_lookup(info->table, (char *)Cudd_Regular(shared), - (char **)&infoS); - if (Cudd_IsComplement(shared)) { - numOnset -= (infoS->mintermsN * impactP + - infoS->mintermsP * impactN)/2.0; - } else { - numOnset -= (infoS->mintermsP * impactP + - infoS->mintermsN * impactN)/2.0; - } - savings--; + DdNode *Ereg = Cudd_Regular(E); + DdNode *TT = cuddT(T); + DdNode *ET = Cudd_NotCond(cuddT(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TT == ET) { + shared = TT; + replace = REPLACE_TT; + } else { + DdNode *TE = cuddE(T); + DdNode *EE = Cudd_NotCond(cuddE(Ereg), Cudd_IsComplement(E)); + if (T->index == Ereg->index && TE == EE) { + shared = TE; + replace = REPLACE_TE; + } else { + replace = REPLACE_N; + } + } + numOnset = infoN->mintermsP * impactP + infoN->mintermsN * impactN; + savings = computeSavings(dd,node,shared,info,localQueue); + if (shared != NULL) { + NodeData *infoS; + (void) st_lookup(info->table, (const char *)Cudd_Regular(shared), (char **)&infoS); + if (Cudd_IsComplement(shared)) { + numOnset -= (infoS->mintermsN * impactP + + infoS->mintermsP * impactN)/2.0; + } else { + numOnset -= (infoS->mintermsP * impactP + + infoS->mintermsN * impactN)/2.0; + } + savings--; + } } - } - cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); + cuddLevelQueueDequeue(queue,cuddI(dd,node->index)); #if 0 - if (replace == REPLACE_T || replace == REPLACE_E) - (void) printf("node %p: impact = %g numOnset = %g savings %d\n", - node, impact, numOnset, savings); - else - (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", - node, impactP, impactN, numOnset, savings); + if (replace == REPLACE_T || replace == REPLACE_E) + (void) printf("node %p: impact = %g numOnset = %g savings %d\n", + node, impact, numOnset, savings); + else + (void) printf("node %p: impact = %g/%g numOnset = %g savings %d\n", + node, impactP, impactN, numOnset, savings); #endif - if ((1 - numOnset / info->minterms) > - quality * (1 - (double) savings / info->size)) { - infoN->replace = replace; - info->size -= savings; - info->minterms -=numOnset; + if ((1 - numOnset / info->minterms) > + quality * (1 - (double) savings / info->size)) { + infoN->replace = (char) replace; + info->size -= savings; + info->minterms -=numOnset; #if 0 - (void) printf("remap(%d): new size = %d new minterms = %g\n", - replace, info->size, info->minterms); + (void) printf("remap(%d): new size = %d new minterms = %g\n", + replace, info->size, info->minterms); #endif - if (replace == REPLACE_N) { - savings -= updateRefs(dd,node,NULL,info,localQueue); - } else if (replace == REPLACE_T) { - savings -= updateRefs(dd,node,E,info,localQueue); - } else if (replace == REPLACE_E) { - savings -= updateRefs(dd,node,T,info,localQueue); - } else { + if (replace == REPLACE_N) { + savings -= updateRefs(dd,node,NULL,info,localQueue); + } else if (replace == REPLACE_T) { + savings -= updateRefs(dd,node,E,info,localQueue); + } else if (replace == REPLACE_E) { + savings -= updateRefs(dd,node,T,info,localQueue); + } else { #ifdef DD_DEBUG - assert(replace == REPLACE_TT || replace == REPLACE_TE); + assert(replace == REPLACE_TT || replace == REPLACE_TE); #endif - savings -= updateRefs(dd,node,shared,info,localQueue) - 1; - } - assert(savings == 0); - } else { - replace = NOTHING; - } - if (replace == REPLACE_N) continue; - if ((replace == REPLACE_E || replace == NOTHING) && - !cuddIsConstant(cuddT(node))) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), - cuddI(dd,cuddT(node)->index)); - if (replace == REPLACE_E) { - item->impactP += impactP; - item->impactN += impactN; - } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; - } - } - if ((replace == REPLACE_T || replace == NOTHING) && - !Cudd_IsConstant(cuddE(node))) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), - cuddI(dd,Cudd_Regular(cuddE(node))->index)); - if (Cudd_IsComplement(cuddE(node))) { - if (replace == REPLACE_T) { - item->impactP += impactN; - item->impactN += impactP; - } else { - item->impactP += impactN/2.0; - item->impactN += impactP/2.0; - } - } else { - if (replace == REPLACE_T) { - item->impactP += impactP; - item->impactN += impactN; + savings -= updateRefs(dd,node,shared,info,localQueue) - 1; + } + assert(savings == 0); } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; - } + replace = NOTHING; } - } - if ((replace == REPLACE_TT || replace == REPLACE_TE) && - !Cudd_IsConstant(shared)) { - item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), - cuddI(dd,Cudd_Regular(shared)->index)); - if (Cudd_IsComplement(shared)) { - if (replace == REPLACE_T) { - item->impactP += impactN; - item->impactN += impactP; - } else { - item->impactP += impactN/2.0; - item->impactN += impactP/2.0; + if (replace == REPLACE_N) continue; + if ((replace == REPLACE_E || replace == NOTHING) && + !cuddIsConstant(cuddT(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,cuddT(node), + cuddI(dd,cuddT(node)->index)); + if (replace == REPLACE_E) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } } - } else { - if (replace == REPLACE_T) { - item->impactP += impactP; - item->impactN += impactN; - } else { - item->impactP += impactP/2.0; - item->impactN += impactN/2.0; + if ((replace == REPLACE_T || replace == NOTHING) && + !Cudd_IsConstant(cuddE(node))) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(cuddE(node)), + cuddI(dd,Cudd_Regular(cuddE(node))->index)); + if (Cudd_IsComplement(cuddE(node))) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } } + if ((replace == REPLACE_TT || replace == REPLACE_TE) && + !Cudd_IsConstant(shared)) { + item = (GlobalQueueItem *) cuddLevelQueueEnqueue(queue,Cudd_Regular(shared), + cuddI(dd,Cudd_Regular(shared)->index)); + if (Cudd_IsComplement(shared)) { + if (replace == REPLACE_T) { + item->impactP += impactN; + item->impactN += impactP; + } else { + item->impactP += impactN/2.0; + item->impactN += impactP/2.0; + } + } else { + if (replace == REPLACE_T) { + item->impactP += impactP; + item->impactN += impactN; + } else { + item->impactP += impactP/2.0; + item->impactN += impactN/2.0; + } + } } } - } cuddLevelQueueQuit(queue); cuddLevelQueueQuit(localQueue); @@ -1982,124 +1996,124 @@ RAbuildSubset( NodeData *infoN; if (Cudd_IsConstant(node)) - return(node); + return(node); N = Cudd_Regular(node); Nt = Cudd_NotCond(cuddT(N), Cudd_IsComplement(node)); Ne = Cudd_NotCond(cuddE(N), Cudd_IsComplement(node)); - if (st_lookup(info->table, (char *)N, (char **)&infoN)) { - if (N == node ) { - if (infoN->resultP != NULL) { - return(infoN->resultP); - } - } else { - if (infoN->resultN != NULL) { - return(infoN->resultN); - } - } - if (infoN->replace == REPLACE_T) { - r = RAbuildSubset(dd, Ne, info); - return(r); - } else if (infoN->replace == REPLACE_E) { - r = RAbuildSubset(dd, Nt, info); - return(r); - } else if (infoN->replace == REPLACE_N) { - return(info->zero); - } else if (infoN->replace == REPLACE_TT) { - DdNode *Ntt = Cudd_NotCond(cuddT(cuddT(N)), - Cudd_IsComplement(node)); - int index = cuddT(N)->index; - DdNode *e = info->zero; - DdNode *t = RAbuildSubset(dd, Ntt, info); - if (t == NULL) { - return(NULL); - } - cuddRef(t); - if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - r = Cudd_Not(r); + if (st_lookup(info->table, (const char *)N, (char **)&infoN)) { + if (N == node ) { + if (infoN->resultP != NULL) { + return(infoN->resultP); + } } else { - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - } - cuddDeref(t); - return(r); - } else if (infoN->replace == REPLACE_TE) { - DdNode *Nte = Cudd_NotCond(cuddE(cuddT(N)), - Cudd_IsComplement(node)); - int index = cuddT(N)->index; - DdNode *t = info->one; - DdNode *e = RAbuildSubset(dd, Nte, info); - if (e == NULL) { - return(NULL); + if (infoN->resultN != NULL) { + return(infoN->resultN); + } } - cuddRef(e); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - return(NULL); + if (infoN->replace == REPLACE_T) { + r = RAbuildSubset(dd, Ne, info); + return(r); + } else if (infoN->replace == REPLACE_E) { + r = RAbuildSubset(dd, Nt, info); + return(r); + } else if (infoN->replace == REPLACE_N) { + return(info->zero); + } else if (infoN->replace == REPLACE_TT) { + DdNode *Ntt = Cudd_NotCond(cuddT(cuddT(N)), + Cudd_IsComplement(node)); + int index = cuddT(N)->index; + e = info->zero; + t = RAbuildSubset(dd, Ntt, info); + if (t == NULL) { + return(NULL); + } + cuddRef(t); + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + } + cuddDeref(t); + return(r); + } else if (infoN->replace == REPLACE_TE) { + DdNode *Nte = Cudd_NotCond(cuddE(cuddT(N)), + Cudd_IsComplement(node)); + int index = cuddT(N)->index; + t = info->one; + e = RAbuildSubset(dd, Nte, info); + if (e == NULL) { + return(NULL); + } + cuddRef(e); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + r =Cudd_Not(r); + cuddDeref(e); + return(r); } - r =Cudd_Not(r); - cuddDeref(e); - return(r); - } } else { - (void) fprintf(dd->err, - "Something is wrong, ought to be in info table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + (void) fprintf(dd->err, + "Something is wrong, ought to be in info table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } t = RAbuildSubset(dd, Nt, info); if (t == NULL) { - return(NULL); + return(NULL); } cuddRef(t); e = RAbuildSubset(dd, Ne, info); if (e == NULL) { - Cudd_RecursiveDeref(dd,t); - return(NULL); + Cudd_RecursiveDeref(dd,t); + return(NULL); } cuddRef(e); if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - r = Cudd_Not(r); + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + r = Cudd_Not(r); } else { - r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - Cudd_RecursiveDeref(dd, t); - return(NULL); - } + r = (t == e) ? t : cuddUniqueInter(dd, N->index, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); + } } cuddDeref(t); cuddDeref(e); if (N == node) { - infoN->resultP = r; + infoN->resultP = r; } else { - infoN->resultN = r; + infoN->resultN = r; } return(r); @@ -2137,61 +2151,63 @@ BAapplyBias( one = DD_ONE(dd); zero = Cudd_Not(one); - if (!st_lookup(info->table, (char *) f, (char **)&infoF)) - return(CARE_ERROR); + if (!st_lookup(info->table, (const char *)f, (char **)&infoF)) + return(CARE_ERROR); if (f == one) return(TOTAL_CARE); if (b == zero) return(infoF->care); if (infoF->care == TOTAL_CARE) return(TOTAL_CARE); if ((f->ref != 1 || Cudd_Regular(b)->ref != 1) && - (res = cuddHashTableLookup2(cache,f,b)) != NULL) { - if (res->ref == 0) { - cache->manager->dead++; - cache->manager->constants.dead++; - } - return(infoF->care); + (res = cuddHashTableLookup2(cache,f,b)) != NULL) { + if (res->ref == 0) { + cache->manager->dead++; + cache->manager->constants.dead++; + } + return(infoF->care); } topf = dd->perm[f->index]; B = Cudd_Regular(b); topb = cuddI(dd,B->index); if (topf <= topb) { - Ft = cuddT(f); Fe = cuddE(f); + Ft = cuddT(f); Fe = cuddE(f); } else { - Ft = Fe = f; + Ft = Fe = f; } if (topb <= topf) { - /* We know that b is not constant because f is not. */ - Bt = cuddT(B); Be = cuddE(B); - if (Cudd_IsComplement(b)) { - Bt = Cudd_Not(Bt); - Be = Cudd_Not(Be); - } + /* We know that b is not constant because f is not. */ + Bt = cuddT(B); Be = cuddE(B); + if (Cudd_IsComplement(b)) { + Bt = Cudd_Not(Bt); + Be = Cudd_Not(Be); + } } else { - Bt = Be = b; + Bt = Be = b; } careT = BAapplyBias(dd, Ft, Bt, info, cache); if (careT == CARE_ERROR) - return(CARE_ERROR); + return(CARE_ERROR); careE = BAapplyBias(dd, Cudd_Regular(Fe), Be, info, cache); if (careE == CARE_ERROR) - return(CARE_ERROR); + return(CARE_ERROR); if (careT == TOTAL_CARE && careE == TOTAL_CARE) { - infoF->care = TOTAL_CARE; + infoF->care = TOTAL_CARE; } else { - infoF->care = CARE; + infoF->care = CARE; } if (f->ref != 1 || Cudd_Regular(b)->ref != 1) { - ptrint fanout = (ptrint) f->ref * Cudd_Regular(b)->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert2(cache,f,b,one,fanout)) { - return(CARE_ERROR); - } + ptrint fanout = (ptrint) f->ref * Cudd_Regular(b)->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert2(cache,f,b,one,fanout)) { + return(CARE_ERROR); + } } return(infoF->care); } /* end of BAapplyBias */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddBddAbs.c b/src/bdd/cudd/cuddBddAbs.c index 80d24ca4..a3892af1 100644 --- a/src/bdd/cudd/cuddBddAbs.c +++ b/src/bdd/cudd/cuddBddAbs.c @@ -7,31 +7,58 @@ Synopsis [Quantification functions for BDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_bddExistAbstract() - <li> Cudd_bddXorExistAbstract() - <li> Cudd_bddUnivAbstract() - <li> Cudd_bddBooleanDiff() - <li> Cudd_bddVarIsDependent() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddExistAbstractRecur() - <li> cuddBddXorExistAbstractRecur() - <li> cuddBddBooleanDiffRecur() - </ul> - Static procedures included in this module: - <ul> - <li> bddCheckPositiveCube() - </ul> - ] + <ul> + <li> Cudd_bddExistAbstract() + <li> Cudd_bddXorExistAbstract() + <li> Cudd_bddUnivAbstract() + <li> Cudd_bddBooleanDiff() + <li> Cudd_bddVarIsDependent() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddBddExistAbstractRecur() + <li> cuddBddXorExistAbstractRecur() + <li> cuddBddBooleanDiffRecur() + </ul> + Static procedures included in this module: + <ul> + <li> bddCheckPositiveCube() + </ul> + ] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -42,6 +69,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -62,7 +90,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.26 2004/08/13 18:04:46 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -76,7 +104,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddBddAbs.c,v 1.1.1.1 2003/02/24 22:23:51 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int bddCheckPositiveCube ARGS((DdManager *manager, DdNode *cube)); +static int bddCheckPositiveCube (DdManager *manager, DdNode *cube); /**AutomaticEnd***************************************************************/ @@ -108,14 +136,14 @@ Cudd_bddExistAbstract( if (bddCheckPositiveCube(manager, cube) == 0) { (void) fprintf(manager->err, - "Error: Can only abstract positive cubes\n"); - manager->errorCode = CUDD_INVALID_ARG; + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; return(NULL); } do { - manager->reordered = 0; - res = cuddBddExistAbstractRecur(manager, f, cube); + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, f, cube); } while (manager->reordered == 1); return(res); @@ -148,14 +176,14 @@ Cudd_bddXorExistAbstract( if (bddCheckPositiveCube(manager, cube) == 0) { (void) fprintf(manager->err, - "Error: Can only abstract positive cubes\n"); - manager->errorCode = CUDD_INVALID_ARG; + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; return(NULL); } do { - manager->reordered = 0; - res = cuddBddXorExistAbstractRecur(manager, f, g, cube); + manager->reordered = 0; + res = cuddBddXorExistAbstractRecur(manager, f, g, cube); } while (manager->reordered == 1); return(res); @@ -181,18 +209,18 @@ Cudd_bddUnivAbstract( DdNode * f, DdNode * cube) { - DdNode *res; + DdNode *res; if (bddCheckPositiveCube(manager, cube) == 0) { - (void) fprintf(manager->err, - "Error: Can only abstract positive cubes\n"); - manager->errorCode = CUDD_INVALID_ARG; - return(NULL); + (void) fprintf(manager->err, + "Error: Can only abstract positive cubes\n"); + manager->errorCode = CUDD_INVALID_ARG; + return(NULL); } do { - manager->reordered = 0; - res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube); + manager->reordered = 0; + res = cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube); } while (manager->reordered == 1); if (res != NULL) res = Cudd_Not(res); @@ -229,8 +257,8 @@ Cudd_bddBooleanDiff( var = manager->vars[x]; do { - manager->reordered = 0; - res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var); + manager->reordered = 0; + res = cuddBddBooleanDiffRecur(manager, Cudd_Regular(f), var); } while (manager->reordered == 1); return(res); @@ -254,13 +282,13 @@ Cudd_bddBooleanDiff( ******************************************************************************/ int Cudd_bddVarIsDependent( - DdManager *dd, /* manager */ - DdNode *f, /* function */ - DdNode *var /* variable */) + DdManager *dd, /* manager */ + DdNode *f, /* function */ + DdNode *var /* variable */) { DdNode *F, *res, *zero, *ft, *fe; unsigned topf, level; - DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *); + DD_CTFP cacheOp; int retval; zero = Cudd_Not(DD_ONE(dd)); @@ -274,14 +302,13 @@ Cudd_bddVarIsDependent( /* Check terminal case. If topf > index of var, f does not depend on var. ** Therefore, var is not dependent in f. */ if (topf > level) { - return(0); + return(0); } - cacheOp = - (DdNode *(*)(DdManager *, DdNode *, DdNode *)) Cudd_bddVarIsDependent; + cacheOp = (DD_CTFP) Cudd_bddVarIsDependent; res = cuddCacheLookup2(dd,cacheOp,f,var); if (res != NULL) { - return(res != zero); + return(res != zero); } /* Compute cofactors. */ @@ -289,10 +316,10 @@ Cudd_bddVarIsDependent( fe = Cudd_NotCond(cuddE(F), f != F); if (topf == level) { - retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe)); + retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe)); } else { - retval = Cudd_bddVarIsDependent(dd,ft,var) && - Cudd_bddVarIsDependent(dd,fe,var); + retval = Cudd_bddVarIsDependent(dd,ft,var) && + Cudd_bddVarIsDependent(dd,fe,var); } cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval)); @@ -327,13 +354,13 @@ cuddBddExistAbstractRecur( DdNode * f, DdNode * cube) { - DdNode *F, *T, *E, *res, *res1, *res2, *one; + DdNode *F, *T, *E, *res, *res1, *res2, *one; statLine(manager); one = DD_ONE(manager); F = Cudd_Regular(f); - /* Cube is guaranteed to be a cube at this point. */ + /* Cube is guaranteed to be a cube at this point. */ if (cube == one || F == one) { return(f); } @@ -341,78 +368,78 @@ cuddBddExistAbstractRecur( /* Abstract a variable that does not appear in f. */ while (manager->perm[F->index] > manager->perm[cube->index]) { - cube = cuddT(cube); - if (cube == one) return(f); + cube = cuddT(cube); + if (cube == one) return(f); } /* Check the cache. */ if (F->ref != 1 && (res = cuddCacheLookup2(manager, Cudd_bddExistAbstract, f, cube)) != NULL) { - return(res); + return(res); } /* Compute the cofactors of f. */ T = cuddT(F); E = cuddE(F); if (f != F) { - T = Cudd_Not(T); E = Cudd_Not(E); + T = Cudd_Not(T); E = Cudd_Not(E); } /* If the two indices are the same, so are their levels. */ if (F->index == cube->index) { - if (T == one || E == one || T == Cudd_Not(E)) { - return(one); - } - res1 = cuddBddExistAbstractRecur(manager, T, cuddT(cube)); - if (res1 == NULL) return(NULL); - if (res1 == one) { - if (F->ref != 1) - cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, one); - return(one); - } + if (T == one || E == one || T == Cudd_Not(E)) { + return(one); + } + res1 = cuddBddExistAbstractRecur(manager, T, cuddT(cube)); + if (res1 == NULL) return(NULL); + if (res1 == one) { + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, one); + return(one); + } cuddRef(res1); - res2 = cuddBddExistAbstractRecur(manager, E, cuddT(cube)); - if (res2 == NULL) { - Cudd_IterDerefBdd(manager,res1); - return(NULL); - } + res2 = cuddBddExistAbstractRecur(manager, E, cuddT(cube)); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager,res1); + return(NULL); + } cuddRef(res2); - res = cuddBddAndRecur(manager, Cudd_Not(res1), Cudd_Not(res2)); - if (res == NULL) { + res = cuddBddAndRecur(manager, Cudd_Not(res1), Cudd_Not(res2)); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + res = Cudd_Not(res); + cuddRef(res); Cudd_IterDerefBdd(manager, res1); Cudd_IterDerefBdd(manager, res2); - return(NULL); - } - res = Cudd_Not(res); - cuddRef(res); - Cudd_IterDerefBdd(manager, res1); - Cudd_IterDerefBdd(manager, res2); - if (F->ref != 1) - cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); - cuddDeref(res); + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); + cuddDeref(res); return(res); } else { /* if (cuddI(manager,F->index) < cuddI(manager,cube->index)) */ - res1 = cuddBddExistAbstractRecur(manager, T, cube); - if (res1 == NULL) return(NULL); + res1 = cuddBddExistAbstractRecur(manager, T, cube); + if (res1 == NULL) return(NULL); cuddRef(res1); - res2 = cuddBddExistAbstractRecur(manager, E, cube); - if (res2 == NULL) { - Cudd_IterDerefBdd(manager, res1); - return(NULL); - } + res2 = cuddBddExistAbstractRecur(manager, E, cube); + if (res2 == NULL) { + Cudd_IterDerefBdd(manager, res1); + return(NULL); + } cuddRef(res2); - /* ITE takes care of possible complementation of res1 and of the + /* ITE takes care of possible complementation of res1 and of the ** case in which res1 == res2. */ - res = cuddBddIteRecur(manager, manager->vars[F->index], res1, res2); - if (res == NULL) { - Cudd_IterDerefBdd(manager, res1); - Cudd_IterDerefBdd(manager, res2); - return(NULL); - } - cuddDeref(res1); - cuddDeref(res2); - if (F->ref != 1) - cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); + res = cuddBddIteRecur(manager, manager->vars[F->index], res1, res2); + if (res == NULL) { + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); + if (F->ref != 1) + cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res); return(res); - } + } } /* end of cuddBddExistAbstractRecur */ @@ -448,39 +475,39 @@ cuddBddXorExistAbstractRecur( /* Terminal cases. */ if (f == g) { - return(zero); + return(zero); } if (f == Cudd_Not(g)) { - return(one); + return(one); } if (cube == one) { - return(cuddBddXorRecur(manager, f, g)); + return(cuddBddXorRecur(manager, f, g)); } if (f == one) { - return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube)); + return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube)); } if (g == one) { - return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube)); + return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube)); } if (f == zero) { - return(cuddBddExistAbstractRecur(manager, g, cube)); + return(cuddBddExistAbstractRecur(manager, g, cube)); } if (g == zero) { - return(cuddBddExistAbstractRecur(manager, f, cube)); + return(cuddBddExistAbstractRecur(manager, f, cube)); } /* At this point f, g, and cube are not constant. */ if (f > g) { /* Try to increase cache efficiency. */ - DdNode *tmp = f; - f = g; - g = tmp; + DdNode *tmp = f; + f = g; + g = tmp; } /* Check cache. */ r = cuddCacheLookup(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube); if (r != NULL) { - return(r); + return(r); } /* Here we can skip the use of cuddI, because the operands are known @@ -494,38 +521,38 @@ cuddBddXorExistAbstractRecur( topcube = manager->perm[cube->index]; if (topcube < top) { - return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube))); + return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube))); } /* Now, topcube >= top. */ if (topf == top) { - index = F->index; - fv = cuddT(F); - fnv = cuddE(F); - if (Cudd_IsComplement(f)) { - fv = Cudd_Not(fv); - fnv = Cudd_Not(fnv); - } + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } } else { - index = G->index; - fv = fnv = f; + index = G->index; + fv = fnv = f; } if (topg == top) { - gv = cuddT(G); - gnv = cuddE(G); - if (Cudd_IsComplement(g)) { - gv = Cudd_Not(gv); - gnv = Cudd_Not(gnv); - } + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } } else { - gv = gnv = g; + gv = gnv = g; } if (topcube == top) { - Cube = cuddT(cube); + Cube = cuddT(cube); } else { - Cube = cube; + Cube = cube; } t = cuddBddXorExistAbstractRecur(manager, fv, gv, Cube); @@ -535,53 +562,53 @@ cuddBddXorExistAbstractRecur( ** the else branch if t is 1. */ if (t == one && topcube == top) { - cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, one); - return(one); + cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, one); + return(one); } cuddRef(t); e = cuddBddXorExistAbstractRecur(manager, fnv, gnv, Cube); if (e == NULL) { - Cudd_IterDerefBdd(manager, t); - return(NULL); - } - cuddRef(e); - - if (topcube == top) { /* abstract */ - r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); - if (r == NULL) { Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); return(NULL); } - r = Cudd_Not(r); - cuddRef(r); - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - cuddDeref(r); - } else if (t == e) { - r = t; - cuddDeref(t); - cuddDeref(e); - } else { - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + cuddRef(e); + + if (topcube == top) { /* abstract */ + r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e)); if (r == NULL) { - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - return(NULL); + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); } r = Cudd_Not(r); - } else { - r = cuddUniqueInter(manager,(int)index,t,e); - if (r == NULL) { + cuddRef(r); Cudd_IterDerefBdd(manager, t); Cudd_IterDerefBdd(manager, e); - return(NULL); + cuddDeref(r); + } else if (t == e) { + r = t; + cuddDeref(t); + cuddDeref(e); + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } } - } - cuddDeref(e); - cuddDeref(t); + cuddDeref(e); + cuddDeref(t); } cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, r); return (r); @@ -613,15 +640,15 @@ cuddBddBooleanDiffRecur( statLine(manager); if (cuddI(manager,f->index) > manager->perm[var->index]) { - /* f does not depend on var. */ - return(Cudd_Not(DD_ONE(manager))); + /* f does not depend on var. */ + return(Cudd_Not(DD_ONE(manager))); } /* From now on, f is non-constant. */ /* If the two indices are the same, so are their levels. */ if (f->index == var->index) { - res = cuddBddXorRecur(manager, cuddT(f), cuddE(f)); + res = cuddBddXorRecur(manager, cuddT(f), cuddE(f)); return(res); } @@ -630,7 +657,7 @@ cuddBddBooleanDiffRecur( /* Check the cache. */ res = cuddCacheLookup2(manager, cuddBddBooleanDiffRecur, f, var); if (res != NULL) { - return(res); + return(res); } /* Compute the cofactors of f. */ @@ -641,17 +668,17 @@ cuddBddBooleanDiffRecur( cuddRef(res1); res2 = cuddBddBooleanDiffRecur(manager, Cudd_Regular(E), var); if (res2 == NULL) { - Cudd_IterDerefBdd(manager, res1); - return(NULL); + Cudd_IterDerefBdd(manager, res1); + return(NULL); } cuddRef(res2); /* ITE takes care of possible complementation of res1 and of the ** case in which res1 == res2. */ res = cuddBddIteRecur(manager, manager->vars[f->index], res1, res2); if (res == NULL) { - Cudd_IterDerefBdd(manager, res1); - Cudd_IterDerefBdd(manager, res2); - return(NULL); + Cudd_IterDerefBdd(manager, res1); + Cudd_IterDerefBdd(manager, res2); + return(NULL); } cuddDeref(res1); cuddDeref(res2); @@ -690,5 +717,7 @@ bddCheckPositiveCube( } /* end of bddCheckPositiveCube */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddBddCorr.c b/src/bdd/cudd/cuddBddCorr.c index f3f017b0..32d5d97c 100644 --- a/src/bdd/cudd/cuddBddCorr.c +++ b/src/bdd/cudd/cuddBddCorr.c @@ -7,26 +7,53 @@ Synopsis [Correlation between BDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_bddCorrelation() - <li> Cudd_bddCorrelationWeights() - </ul> - Static procedures included in this module: - <ul> - <li> bddCorrelationAux() - <li> bddCorrelationWeightsAux() - <li> CorrelCompare() - <li> CorrelHash() - <li> CorrelCleanUp() - </ul> - ] + <ul> + <li> Cudd_bddCorrelation() + <li> Cudd_bddCorrelationWeights() + </ul> + Static procedures included in this module: + <ul> + <li> bddCorrelationAux() + <li> bddCorrelationWeightsAux() + <li> CorrelCompare() + <li> CorrelHash() + <li> CorrelCleanUp() + </ul> + ] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -37,6 +64,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -62,17 +90,20 @@ typedef struct hashEntry { /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddBddCorr.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddBddCorr.c,v 1.14 2004/08/13 18:04:46 fabio Exp $"; #endif #ifdef CORREL_STATS -static int num_calls; +static int num_calls; #endif /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -80,14 +111,18 @@ static int num_calls; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static double bddCorrelationAux ARGS((DdManager *dd, DdNode *f, DdNode *g, st_table *table)); -static double bddCorrelationWeightsAux ARGS((DdManager *dd, DdNode *f, DdNode *g, double *prob, st_table *table)); -static int CorrelCompare ARGS((const char *key1, const char *key2)); -static int CorrelHash ARGS((const char *key, int modulus)); -static enum st_retval CorrelCleanUp ARGS((char *key, char *value, char *arg)); +static double bddCorrelationAux (DdManager *dd, DdNode *f, DdNode *g, st_table *table); +static double bddCorrelationWeightsAux (DdManager *dd, DdNode *f, DdNode *g, double *prob, st_table *table); +static int CorrelCompare (const char *key1, const char *key2); +static int CorrelHash (const char *key, int modulus); +static enum st_retval CorrelCleanUp (char *key, char *value, char *arg); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif + /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -116,7 +151,7 @@ Cudd_bddCorrelation( { st_table *table; - double correlation; + double correlation; #ifdef CORREL_STATS num_calls = 0; @@ -125,7 +160,7 @@ Cudd_bddCorrelation( table = st_init_table(CorrelCompare,CorrelHash); if (table == NULL) return((double)CUDD_OUT_OF_MEM); correlation = bddCorrelationAux(manager,f,g,table); - st_foreach(table, (ST_PFSR)CorrelCleanUp, NIL(char)); + st_foreach(table, CorrelCleanUp, NIL(char)); st_free_table(table); return(correlation); @@ -159,7 +194,7 @@ Cudd_bddCorrelationWeights( { st_table *table; - double correlation; + double correlation; #ifdef CORREL_STATS num_calls = 0; @@ -168,7 +203,7 @@ Cudd_bddCorrelationWeights( table = st_init_table(CorrelCompare,CorrelHash); if (table == NULL) return((double)CUDD_OUT_OF_MEM); correlation = bddCorrelationWeightsAux(manager,f,g,prob,table); - st_foreach(table, (ST_PFSR)CorrelCleanUp, NIL(char)); + st_foreach(table, CorrelCleanUp, NIL(char)); st_free_table(table); return(correlation); @@ -205,9 +240,9 @@ bddCorrelationAux( DdNode * g, st_table * table) { - DdNode *Fv, *Fnv, *G, *Gv, *Gnv; - double min, *pmin, min1, min2, *dummy; - HashEntry *entry; + DdNode *Fv, *Fnv, *G, *Gv, *Gnv; + double min, *pmin, min1, min2, *dummy; + HashEntry *entry; unsigned int topF, topG; statLine(dd); @@ -224,19 +259,19 @@ bddCorrelationAux( ** (f' EXNOR g') = (f EXNOR g). */ if (f > g) { - DdNode *tmp = f; - f = g; g = tmp; + DdNode *tmp = f; + f = g; g = tmp; } if (Cudd_IsComplement(f)) { - f = Cudd_Not(f); - g = Cudd_Not(g); + f = Cudd_Not(f); + g = Cudd_Not(g); } /* From now on, f is regular. */ entry = ABC_ALLOC(HashEntry,1); if (entry == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); } entry->f = f; entry->g = g; @@ -244,10 +279,10 @@ bddCorrelationAux( ** correlation(f,g') = 1 - correlation(f,g) ** to minimize the risk of cancellation. */ - if (st_lookup(table, (char *)entry, (char **)&dummy)) { - min = *dummy; - ABC_FREE(entry); - return(min); + if (st_lookup(table, (const char *)entry, (char **)&dummy)) { + min = *dummy; + ABC_FREE(entry); + return(min); } G = Cudd_Regular(g); @@ -256,33 +291,33 @@ bddCorrelationAux( if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; } if (g != G) { - Gv = Cudd_Not(Gv); - Gnv = Cudd_Not(Gnv); + Gv = Cudd_Not(Gv); + Gnv = Cudd_Not(Gnv); } min1 = bddCorrelationAux(dd, Fv, Gv, table) / 2.0; if (min1 == (double)CUDD_OUT_OF_MEM) { - ABC_FREE(entry); - return(CUDD_OUT_OF_MEM); + ABC_FREE(entry); + return(CUDD_OUT_OF_MEM); } min2 = bddCorrelationAux(dd, Fnv, Gnv, table) / 2.0; if (min2 == (double)CUDD_OUT_OF_MEM) { - ABC_FREE(entry); - return(CUDD_OUT_OF_MEM); + ABC_FREE(entry); + return(CUDD_OUT_OF_MEM); } min = (min1+min2); pmin = ABC_ALLOC(double,1); if (pmin == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return((double)CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); } *pmin = min; if (st_insert(table,(char *)entry, (char *)pmin) == ST_OUT_OF_MEM) { - ABC_FREE(entry); - ABC_FREE(pmin); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(entry); + ABC_FREE(pmin); + return((double)CUDD_OUT_OF_MEM); } return(min); @@ -308,10 +343,10 @@ bddCorrelationWeightsAux( double * prob, st_table * table) { - DdNode *Fv, *Fnv, *G, *Gv, *Gnv; - double min, *pmin, min1, min2, *dummy; - HashEntry *entry; - int topF, topG, index; + DdNode *Fv, *Fnv, *G, *Gv, *Gnv; + double min, *pmin, min1, min2, *dummy; + HashEntry *entry; + int topF, topG, index; statLine(dd); #ifdef CORREL_STATS @@ -327,19 +362,19 @@ bddCorrelationWeightsAux( ** (f' EXNOR g') = (f EXNOR g). */ if (f > g) { - DdNode *tmp = f; - f = g; g = tmp; + DdNode *tmp = f; + f = g; g = tmp; } if (Cudd_IsComplement(f)) { - f = Cudd_Not(f); - g = Cudd_Not(g); + f = Cudd_Not(f); + g = Cudd_Not(g); } /* From now on, f is regular. */ entry = ABC_ALLOC(HashEntry,1); if (entry == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return((double)CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); } entry->f = f; entry->g = g; @@ -347,51 +382,51 @@ bddCorrelationWeightsAux( ** correlation(f,g') = 1 - correlation(f,g) ** to minimize the risk of cancellation. */ - if (st_lookup(table, (char *)entry, (char **)&dummy)) { - min = *dummy; - ABC_FREE(entry); - return(min); + if (st_lookup(table, (const char *)entry, (char **)&dummy)) { + min = *dummy; + ABC_FREE(entry); + return(min); } G = Cudd_Regular(g); topF = cuddI(dd,f->index); topG = cuddI(dd,G->index); if (topF <= topG) { - Fv = cuddT(f); Fnv = cuddE(f); - index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); + index = f->index; } else { - Fv = Fnv = f; - index = G->index; + Fv = Fnv = f; + index = G->index; } if (topG <= topF) { Gv = cuddT(G); Gnv = cuddE(G); } else { Gv = Gnv = G; } if (g != G) { - Gv = Cudd_Not(Gv); - Gnv = Cudd_Not(Gnv); + Gv = Cudd_Not(Gv); + Gnv = Cudd_Not(Gnv); } min1 = bddCorrelationWeightsAux(dd, Fv, Gv, prob, table) * prob[index]; if (min1 == (double)CUDD_OUT_OF_MEM) { - ABC_FREE(entry); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(entry); + return((double)CUDD_OUT_OF_MEM); } min2 = bddCorrelationWeightsAux(dd, Fnv, Gnv, prob, table) * (1.0 - prob[index]); if (min2 == (double)CUDD_OUT_OF_MEM) { - ABC_FREE(entry); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(entry); + return((double)CUDD_OUT_OF_MEM); } min = (min1+min2); pmin = ABC_ALLOC(double,1); if (pmin == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return((double)CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); } *pmin = min; if (st_insert(table,(char *)entry, (char *)pmin) == ST_OUT_OF_MEM) { - ABC_FREE(entry); - ABC_FREE(pmin); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(entry); + ABC_FREE(pmin); + return((double)CUDD_OUT_OF_MEM); } return(min); @@ -440,10 +475,10 @@ CorrelHash( const char * key, int modulus) { - const HashEntry *entry; + HashEntry *entry; int val = 0; - entry = (const HashEntry *) key; + entry = (HashEntry *) key; #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 val = ((int) ((long)entry->f))*997 + ((int) ((long)entry->g)); #else @@ -471,7 +506,7 @@ CorrelCleanUp( char * value, char * arg) { - double *d; + double *d; HashEntry *entry; entry = (HashEntry *) key; @@ -482,5 +517,7 @@ CorrelCleanUp( } /* end of CorrelCleanUp */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddBddIte.c b/src/bdd/cudd/cuddBddIte.c index 92d1171b..1b152f02 100644 --- a/src/bdd/cudd/cuddBddIte.c +++ b/src/bdd/cudd/cuddBddIte.c @@ -7,40 +7,68 @@ Synopsis [BDD ITE function and satellites.] Description [External procedures included in this module: - <ul> + <ul> <li> Cudd_bddIte() - <li> Cudd_bddIteConstant() - <li> Cudd_bddIntersect() - <li> Cudd_bddAnd() - <li> Cudd_bddOr() - <li> Cudd_bddNand() - <li> Cudd_bddNor() - <li> Cudd_bddXor() - <li> Cudd_bddXnor() - <li> Cudd_bddLeq() - </ul> + <li> Cudd_bddIteConstant() + <li> Cudd_bddIntersect() + <li> Cudd_bddAnd() + <li> Cudd_bddAndLimit() + <li> Cudd_bddOr() + <li> Cudd_bddNand() + <li> Cudd_bddNor() + <li> Cudd_bddXor() + <li> Cudd_bddXnor() + <li> Cudd_bddLeq() + </ul> Internal procedures included in this module: - <ul> - <li> cuddBddIteRecur() - <li> cuddBddIntersectRecur() - <li> cuddBddAndRecur() - <li> cuddBddXorRecur() - </ul> + <ul> + <li> cuddBddIteRecur() + <li> cuddBddIntersectRecur() + <li> cuddBddAndRecur() + <li> cuddBddXorRecur() + </ul> Static procedures included in this module: - <ul> - <li> bddVarToConst() - <li> bddVarToCanonical() - <li> bddVarToCanonicalSimple() - </ul>] + <ul> + <li> bddVarToConst() + <li> bddVarToCanonical() + <li> bddVarToCanonicalSimple() + </ul>] SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -51,6 +79,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -71,7 +100,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddBddIte.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddBddIte.c,v 1.24 2004/08/13 18:04:46 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -85,9 +114,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddBddIte.c,v 1.1.1.1 2003/02/24 22:23:51 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void bddVarToConst ARGS((DdNode *f, DdNode **gp, DdNode **hp, DdNode *one)); -static int bddVarToCanonical ARGS((DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)); -static int bddVarToCanonicalSimple ARGS((DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)); +static void bddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one); +static int bddVarToCanonical (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp); +static int bddVarToCanonicalSimple (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp); /**AutomaticEnd***************************************************************/ @@ -120,8 +149,8 @@ Cudd_bddIte( DdNode *res; do { - dd->reordered = 0; - res = cuddBddIteRecur(dd,f,g,h); + dd->reordered = 0; + res = cuddBddIteRecur(dd,f,g,h); } while (dd->reordered == 1); return(res); @@ -148,85 +177,85 @@ Cudd_bddIteConstant( DdNode * g, DdNode * h) { - DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; - DdNode *one = DD_ONE(dd); - DdNode *zero = Cudd_Not(one); - int comple; + DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + int comple; unsigned int topf, topg, toph, v; statLine(dd); /* Trivial cases. */ - if (f == one) /* ITE(1,G,H) => G */ - return(g); + if (f == one) /* ITE(1,G,H) => G */ + return(g); - if (f == zero) /* ITE(0,G,H) => H */ - return(h); + if (f == zero) /* ITE(0,G,H) => H */ + return(h); /* f now not a constant. */ - bddVarToConst(f, &g, &h, one); /* possibly convert g or h */ - /* to constants */ + bddVarToConst(f, &g, &h, one); /* possibly convert g or h */ + /* to constants */ - if (g == h) /* ITE(F,G,G) => G */ - return(g); + if (g == h) /* ITE(F,G,G) => G */ + return(g); if (Cudd_IsConstant(g) && Cudd_IsConstant(h)) - return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */ - /* => DD_NON_CONSTANT */ + return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */ + /* => DD_NON_CONSTANT */ if (g == Cudd_Not(h)) - return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */ - /* if F != G and F != G' */ + return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */ + /* if F != G and F != G' */ comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph); /* Cache lookup. */ r = cuddConstantLookup(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h); if (r != NULL) { - return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT)); + return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT)); } v = ddMin(topg, toph); /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */ if (topf < v && cuddT(f) == one && cuddE(f) == zero) { - return(DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } /* Compute cofactors. */ if (topf <= v) { - v = ddMin(topf, v); /* v = top_var(F,G,H) */ - Fv = cuddT(f); Fnv = cuddE(f); + v = ddMin(topf, v); /* v = top_var(F,G,H) */ + Fv = cuddT(f); Fnv = cuddE(f); } else { - Fv = Fnv = f; + Fv = Fnv = f; } if (topg == v) { - Gv = cuddT(g); Gnv = cuddE(g); + Gv = cuddT(g); Gnv = cuddE(g); } else { - Gv = Gnv = g; + Gv = Gnv = g; } if (toph == v) { - H = Cudd_Regular(h); - Hv = cuddT(H); Hnv = cuddE(H); - if (Cudd_IsComplement(h)) { - Hv = Cudd_Not(Hv); - Hnv = Cudd_Not(Hnv); - } + H = Cudd_Regular(h); + Hv = cuddT(H); Hnv = cuddE(H); + if (Cudd_IsComplement(h)) { + Hv = Cudd_Not(Hv); + Hnv = Cudd_Not(Hnv); + } } else { - Hv = Hnv = h; + Hv = Hnv = h; } /* Recursion. */ t = Cudd_bddIteConstant(dd, Fv, Gv, Hv); if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) { - cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); - return(DD_NON_CONSTANT); + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv); if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) { - cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); - return(DD_NON_CONSTANT); + cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, DD_NON_CONSTANT); + return(DD_NON_CONSTANT); } cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t); return(Cudd_NotCond(t,comple)); @@ -258,8 +287,8 @@ Cudd_bddIntersect( DdNode *res; do { - dd->reordered = 0; - res = cuddBddIntersectRecur(dd,f,g); + dd->reordered = 0; + res = cuddBddIntersectRecur(dd,f,g); } while (dd->reordered == 1); return(res); @@ -290,8 +319,8 @@ Cudd_bddAnd( DdNode *res; do { - dd->reordered = 0; - res = cuddBddAndRecur(dd,f,g); + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); } while (dd->reordered == 1); return(res); @@ -300,6 +329,42 @@ Cudd_bddAnd( /**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 <code>limit</code> are + required.] + + SideEffects [None] + + SeeAlso [Cudd_bddAnd] + +******************************************************************************/ +DdNode * +Cudd_bddAndLimit( + DdManager * dd, + DdNode * f, + DdNode * g, + unsigned int limit) +{ + DdNode *res; + unsigned int saveLimit = dd->maxLive; + + dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit; + do { + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); + } while (dd->reordered == 1); + dd->maxLive = saveLimit; + return(res); + +} /* end of Cudd_bddAndLimit */ + + +/**Function******************************************************************** + Synopsis [Computes the disjunction of two BDDs f and g.] Description [Computes the disjunction of two BDDs f and g. Returns a @@ -321,8 +386,8 @@ Cudd_bddOr( DdNode *res; do { - dd->reordered = 0; - res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); } while (dd->reordered == 1); res = Cudd_NotCond(res,res != NULL); return(res); @@ -353,8 +418,8 @@ Cudd_bddNand( DdNode *res; do { - dd->reordered = 0; - res = cuddBddAndRecur(dd,f,g); + dd->reordered = 0; + res = cuddBddAndRecur(dd,f,g); } while (dd->reordered == 1); res = Cudd_NotCond(res,res != NULL); return(res); @@ -385,8 +450,8 @@ Cudd_bddNor( DdNode *res; do { - dd->reordered = 0; - res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); + dd->reordered = 0; + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g)); } while (dd->reordered == 1); return(res); @@ -416,8 +481,8 @@ Cudd_bddXor( DdNode *res; do { - dd->reordered = 0; - res = cuddBddXorRecur(dd,f,g); + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,g); } while (dd->reordered == 1); return(res); @@ -447,8 +512,8 @@ Cudd_bddXnor( DdNode *res; do { - dd->reordered = 0; - res = cuddBddXorRecur(dd,f,Cudd_Not(g)); + dd->reordered = 0; + res = cuddBddXorRecur(dd,f,Cudd_Not(g)); } while (dd->reordered == 1); return(res); @@ -481,20 +546,20 @@ Cudd_bddLeq( if (f == g) return(1); if (Cudd_IsComplement(g)) { - /* Special case: if f is regular and g is complemented, - ** f(1,...,1) = 1 > 0 = g(1,...,1). - */ - if (!Cudd_IsComplement(f)) return(0); - /* Both are complemented: Swap and complement because - ** f <= g <=> g' <= f' and we want the second argument to be regular. - */ - tmp = g; - g = Cudd_Not(f); - f = Cudd_Not(tmp); + /* Special case: if f is regular and g is complemented, + ** f(1,...,1) = 1 > 0 = g(1,...,1). + */ + if (!Cudd_IsComplement(f)) return(0); + /* Both are complemented: Swap and complement because + ** f <= g <=> g' <= f' and we want the second argument to be regular. + */ + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); } else if (Cudd_IsComplement(f) && g < f) { - tmp = g; - g = Cudd_Not(f); - f = Cudd_Not(tmp); + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); } /* Now g is regular and, if f is not regular, f < g. */ @@ -508,10 +573,9 @@ Cudd_bddLeq( /* Here neither f nor g is constant. */ /* Check cache. */ - tmp = cuddCacheLookup2(dd,(DdNode * (*)(DdManager *, DdNode *, - DdNode *))Cudd_bddLeq,f,g); + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g); if (tmp != NULL) { - return(tmp == one); + return(tmp == one); } /* Compute cofactors. */ @@ -519,18 +583,18 @@ Cudd_bddLeq( topf = dd->perm[F->index]; topg = dd->perm[g->index]; if (topf <= topg) { - fv = cuddT(F); fvn = cuddE(F); - if (f != F) { - fv = Cudd_Not(fv); - fvn = Cudd_Not(fvn); - } + fv = cuddT(F); fvn = cuddE(F); + if (f != F) { + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); + } } else { - fv = fvn = f; + fv = fvn = f; } if (topg <= topf) { - gv = cuddT(g); gvn = cuddE(g); + gv = cuddT(g); gvn = cuddE(g); } else { - gv = gvn = g; + gv = gvn = g; } /* Recursive calls. Since we want to maximize the probability of @@ -541,7 +605,7 @@ Cudd_bddLeq( res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv); /* Store result in cache and return. */ - cuddCacheInsert2(dd,(DdNode * (*)(DdManager *, DdNode *, DdNode *))Cudd_bddLeq,f,g,(res ? one : zero)); + cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero)); return(res); } /* end of Cudd_bddLeq */ @@ -572,52 +636,52 @@ cuddBddIteRecur( DdNode * g, DdNode * h) { - DdNode *one, *zero, *res; - DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; + DdNode *one, *zero, *res; + DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e; unsigned int topf, topg, toph, v; - int index = 0; // Suppress "might be used uninitialized" - int comple; + int index; + int comple; statLine(dd); /* Terminal cases. */ /* One variable cases. */ - if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */ - return(g); + if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */ + return(g); - if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */ - return(h); + if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */ + return(h); /* From now on, f is known not to be a constant. */ - if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ - if (h == zero) { /* ITE(F,1,0) = F */ - return(f); - } else { - res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h)); - return(Cudd_NotCond(res,res != NULL)); - } + if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ + if (h == zero) { /* ITE(F,1,0) = F */ + return(f); + } else { + res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h)); + return(Cudd_NotCond(res,res != NULL)); + } } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ - if (h == one) { /* ITE(F,0,1) = !F */ - return(Cudd_Not(f)); - } else { - res = cuddBddAndRecur(dd,Cudd_Not(f),h); - return(res); - } + if (h == one) { /* ITE(F,0,1) = !F */ + return(Cudd_Not(f)); + } else { + res = cuddBddAndRecur(dd,Cudd_Not(f),h); + return(res); + } } if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ - res = cuddBddAndRecur(dd,f,g); - return(res); + res = cuddBddAndRecur(dd,f,g); + return(res); } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ - res = cuddBddAndRecur(dd,f,Cudd_Not(g)); - return(Cudd_NotCond(res,res != NULL)); + res = cuddBddAndRecur(dd,f,Cudd_Not(g)); + return(Cudd_NotCond(res,res != NULL)); } /* Check remaining one variable case. */ - if (g == h) { /* ITE(F,G,G) = G */ - return(g); + if (g == h) { /* ITE(F,G,G) = G */ + return(g); } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */ - res = cuddBddXorRecur(dd,f,h); - return(res); + res = cuddBddXorRecur(dd,f,h); + return(res); } /* From here, there are no constants. */ @@ -629,40 +693,40 @@ cuddBddIteRecur( /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */ if (topf < v && cuddT(f) == one && cuddE(f) == zero) { - r = cuddUniqueInter(dd, (int) f->index, g, h); - return(Cudd_NotCond(r,comple && r != NULL)); + r = cuddUniqueInter(dd, (int) f->index, g, h); + return(Cudd_NotCond(r,comple && r != NULL)); } /* Check cache. */ r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h); if (r != NULL) { - return(Cudd_NotCond(r,comple)); + return(Cudd_NotCond(r,comple)); } /* Compute cofactors. */ if (topf <= v) { - v = ddMin(topf, v); /* v = top_var(F,G,H) */ - index = f->index; - Fv = cuddT(f); Fnv = cuddE(f); + v = ddMin(topf, v); /* v = top_var(F,G,H) */ + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); } else { - Fv = Fnv = f; + Fv = Fnv = f; } if (topg == v) { - index = g->index; - Gv = cuddT(g); Gnv = cuddE(g); + index = g->index; + Gv = cuddT(g); Gnv = cuddE(g); } else { - Gv = Gnv = g; + Gv = Gnv = g; } if (toph == v) { - H = Cudd_Regular(h); - index = H->index; - Hv = cuddT(H); Hnv = cuddE(H); - if (Cudd_IsComplement(h)) { - Hv = Cudd_Not(Hv); - Hnv = Cudd_Not(Hnv); - } + H = Cudd_Regular(h); + index = H->index; + Hv = cuddT(H); Hnv = cuddE(H); + if (Cudd_IsComplement(h)) { + Hv = Cudd_Not(Hv); + Hnv = Cudd_Not(Hnv); + } } else { - Hv = Hnv = h; + Hv = Hnv = h; } /* Recursive step. */ @@ -672,16 +736,16 @@ cuddBddIteRecur( e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv); if (e == NULL) { - Cudd_IterDerefBdd(dd,t); - return(NULL); + Cudd_IterDerefBdd(dd,t); + return(NULL); } cuddRef(e); r = (t == e) ? t : cuddUniqueInter(dd,index,t,e); if (r == NULL) { - Cudd_IterDerefBdd(dd,t); - Cudd_IterDerefBdd(dd,e); - return(NULL); + Cudd_IterDerefBdd(dd,t); + Cudd_IterDerefBdd(dd,e); + return(NULL); } cuddDeref(t); cuddDeref(e); @@ -739,27 +803,27 @@ cuddBddIntersectRecur( /* Compute cofactors. */ if (topf <= topg) { - index = F->index; - fv = cuddT(F); - fnv = cuddE(F); - if (Cudd_IsComplement(f)) { - fv = Cudd_Not(fv); - fnv = Cudd_Not(fnv); - } + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } } else { - index = G->index; - fv = fnv = f; + index = G->index; + fv = fnv = f; } if (topg <= topf) { - gv = cuddT(G); - gnv = cuddE(G); - if (Cudd_IsComplement(g)) { - gv = Cudd_Not(gv); - gnv = Cudd_Not(gnv); - } + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } } else { - gv = gnv = g; + gv = gnv = g; } /* Compute partial results. */ @@ -767,33 +831,33 @@ cuddBddIntersectRecur( if (t == NULL) return(NULL); cuddRef(t); if (t != zero) { - e = zero; + e = zero; } else { - e = cuddBddIntersectRecur(dd,fnv,gnv); - if (e == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); - } + e = cuddBddIntersectRecur(dd,fnv,gnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } cuddRef(e); if (t == e) { /* both equal zero */ - res = t; + res = t; } else if (Cudd_IsComplement(t)) { - res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e)); - if (res == NULL) { - Cudd_IterDerefBdd(dd, t); - Cudd_IterDerefBdd(dd, e); - return(NULL); - } - res = Cudd_Not(res); + res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (res == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + res = Cudd_Not(res); } else { - res = cuddUniqueInter(dd,(int)index,t,e); - if (res == NULL) { - Cudd_IterDerefBdd(dd, t); - Cudd_IterDerefBdd(dd, e); - return(NULL); - } + res = cuddUniqueInter(dd,(int)index,t,e); + if (res == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } } cuddDeref(e); cuddDeref(t); @@ -835,31 +899,31 @@ cuddBddAndRecur( F = Cudd_Regular(f); G = Cudd_Regular(g); if (F == G) { - if (f == g) return(f); - else return(Cudd_Not(one)); + if (f == g) return(f); + else return(Cudd_Not(one)); } if (F == one) { - if (f == one) return(g); - else return(f); + if (f == one) return(g); + else return(f); } if (G == one) { - if (g == one) return(f); - else return(g); + if (g == one) return(f); + else return(g); } /* At this point f and g are not constant. */ if (f > g) { /* Try to increase cache efficiency. */ - DdNode *tmp = f; - f = g; - g = tmp; - F = Cudd_Regular(f); - G = Cudd_Regular(g); + DdNode *tmp = f; + f = g; + g = tmp; + F = Cudd_Regular(f); + G = Cudd_Regular(g); } /* Check cache. */ if (F->ref != 1 || G->ref != 1) { - r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g); - if (r != NULL) return(r); + r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g); + if (r != NULL) return(r); } /* Here we can skip the use of cuddI, because the operands are known @@ -870,27 +934,27 @@ cuddBddAndRecur( /* Compute cofactors. */ if (topf <= topg) { - index = F->index; - fv = cuddT(F); - fnv = cuddE(F); - if (Cudd_IsComplement(f)) { - fv = Cudd_Not(fv); - fnv = Cudd_Not(fnv); - } + index = F->index; + fv = cuddT(F); + fnv = cuddE(F); + if (Cudd_IsComplement(f)) { + fv = Cudd_Not(fv); + fnv = Cudd_Not(fnv); + } } else { - index = G->index; - fv = fnv = f; + index = G->index; + fv = fnv = f; } if (topg <= topf) { - gv = cuddT(G); - gnv = cuddE(G); - if (Cudd_IsComplement(g)) { - gv = Cudd_Not(gv); - gnv = Cudd_Not(gnv); - } + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } } else { - gv = gnv = g; + gv = gnv = g; } t = cuddBddAndRecur(manager, fv, gv); @@ -899,35 +963,35 @@ cuddBddAndRecur( e = cuddBddAndRecur(manager, fnv, gnv); if (e == NULL) { - Cudd_IterDerefBdd(manager, t); - return(NULL); + Cudd_IterDerefBdd(manager, t); + return(NULL); } cuddRef(e); if (t == e) { - r = t; - } else { - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); - if (r == NULL) { - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - return(NULL); - } - r = Cudd_Not(r); + r = t; } else { - r = cuddUniqueInter(manager,(int)index,t,e); - if (r == NULL) { - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - return(NULL); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } } } - } cuddDeref(e); cuddDeref(t); if (F->ref != 1 || G->ref != 1) - cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r); + cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r); return(r); } /* end of cuddBddAndRecur */ @@ -964,15 +1028,15 @@ cuddBddXorRecur( if (f == g) return(zero); if (f == Cudd_Not(g)) return(one); if (f > g) { /* Try to increase cache efficiency and simplify tests. */ - DdNode *tmp = f; - f = g; - g = tmp; + DdNode *tmp = f; + f = g; + g = tmp; } if (g == zero) return(f); if (g == one) return(Cudd_Not(f)); if (Cudd_IsComplement(f)) { - f = Cudd_Not(f); - g = Cudd_Not(g); + f = Cudd_Not(f); + g = Cudd_Not(g); } /* Now the first argument is regular. */ if (f == one) return(Cudd_Not(g)); @@ -992,23 +1056,23 @@ cuddBddXorRecur( /* Compute cofactors. */ if (topf <= topg) { - index = f->index; - fv = cuddT(f); - fnv = cuddE(f); + index = f->index; + fv = cuddT(f); + fnv = cuddE(f); } else { - index = G->index; - fv = fnv = f; + index = G->index; + fv = fnv = f; } if (topg <= topf) { - gv = cuddT(G); - gnv = cuddE(G); - if (Cudd_IsComplement(g)) { - gv = Cudd_Not(gv); - gnv = Cudd_Not(gnv); - } + gv = cuddT(G); + gnv = cuddE(G); + if (Cudd_IsComplement(g)) { + gv = Cudd_Not(gv); + gnv = Cudd_Not(gnv); + } } else { - gv = gnv = g; + gv = gnv = g; } t = cuddBddXorRecur(manager, fv, gv); @@ -1017,31 +1081,31 @@ cuddBddXorRecur( e = cuddBddXorRecur(manager, fnv, gnv); if (e == NULL) { - Cudd_IterDerefBdd(manager, t); - return(NULL); + Cudd_IterDerefBdd(manager, t); + return(NULL); } cuddRef(e); if (t == e) { - r = t; - } else { - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); - if (r == NULL) { - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - return(NULL); - } - r = Cudd_Not(r); + r = t; } else { - r = cuddUniqueInter(manager,(int)index,t,e); - if (r == NULL) { - Cudd_IterDerefBdd(manager, t); - Cudd_IterDerefBdd(manager, e); - return(NULL); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } } } - } cuddDeref(e); cuddDeref(t); cuddCacheInsert2(manager, Cudd_bddXor, f, g, r); @@ -1078,14 +1142,14 @@ bddVarToConst( DdNode *h = *hp; if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ - *gp = one; + *gp = one; } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */ - *gp = Cudd_Not(one); + *gp = Cudd_Not(one); } if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ - *hp = Cudd_Not(one); + *hp = Cudd_Not(one); } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */ - *hp = one; + *hp = one; } } /* end of bddVarToConst */ @@ -1112,10 +1176,10 @@ bddVarToCanonical( unsigned int * topgp, unsigned int * tophp) { - register DdNode *F, *G, *H, *r, *f, *g, *h; - register unsigned int topf, topg, toph; - DdNode *one = dd->one; - int comple, change; + register DdNode *F, *G, *H, *r, *f, *g, *h; + register unsigned int topf, topg, toph; + DdNode *one = dd->one; + int comple, change; f = *fp; g = *gp; @@ -1129,56 +1193,56 @@ bddVarToCanonical( change = 0; - if (G == one) { /* ITE(F,c,H) */ - if ((topf > toph) || (topf == toph && f > h)) { - r = h; - h = f; - f = r; /* ITE(F,1,H) = ITE(H,1,F) */ - if (g != one) { /* g == zero */ - f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */ - h = Cudd_Not(h); + if (G == one) { /* ITE(F,c,H) */ + if ((topf > toph) || (topf == toph && f > h)) { + r = h; + h = f; + f = r; /* ITE(F,1,H) = ITE(H,1,F) */ + if (g != one) { /* g == zero */ + f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */ + h = Cudd_Not(h); + } + change = 1; } - change = 1; - } - } else if (H == one) { /* ITE(F,G,c) */ - if ((topf > topg) || (topf == topg && f > g)) { - r = g; - g = f; - f = r; /* ITE(F,G,0) = ITE(G,F,0) */ - if (h == one) { - f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */ - g = Cudd_Not(g); + } else if (H == one) { /* ITE(F,G,c) */ + if ((topf > topg) || (topf == topg && f > g)) { + r = g; + g = f; + f = r; /* ITE(F,G,0) = ITE(G,F,0) */ + if (h == one) { + f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */ + g = Cudd_Not(g); + } + change = 1; + } + } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */ + if ((topf > topg) || (topf == topg && f > g)) { + r = f; + f = g; + g = r; + h = Cudd_Not(r); + change = 1; } - change = 1; - } - } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */ - if ((topf > topg) || (topf == topg && f > g)) { - r = f; - f = g; - g = r; - h = Cudd_Not(r); - change = 1; - } } /* adjust pointers so that the first 2 arguments to ITE are regular */ if (Cudd_IsComplement(f) != 0) { /* ITE(!F,G,H) = ITE(F,H,G) */ - f = Cudd_Not(f); - r = g; - g = h; - h = r; - change = 1; + f = Cudd_Not(f); + r = g; + g = h; + h = r; + change = 1; } comple = 0; if (Cudd_IsComplement(g) != 0) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ - g = Cudd_Not(g); - h = Cudd_Not(h); - change = 1; - comple = 1; + g = Cudd_Not(g); + h = Cudd_Not(h); + change = 1; + comple = 1; } if (change != 0) { - *fp = f; - *gp = g; - *hp = h; + *fp = f; + *gp = g; + *hp = h; } *topfp = cuddI(dd,f->index); *topgp = cuddI(dd,g->index); @@ -1214,8 +1278,8 @@ bddVarToCanonicalSimple( unsigned int * topgp, unsigned int * tophp) { - register DdNode *r, *f, *g, *h; - int comple, change; + register DdNode *r, *f, *g, *h; + int comple, change; f = *fp; g = *gp; @@ -1224,24 +1288,24 @@ bddVarToCanonicalSimple( change = 0; /* adjust pointers so that the first 2 arguments to ITE are regular */ - if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */ - f = Cudd_Not(f); - r = g; - g = h; - h = r; - change = 1; + if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */ + f = Cudd_Not(f); + r = g; + g = h; + h = r; + change = 1; } comple = 0; - if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ - g = Cudd_Not(g); - h = Cudd_Not(h); - change = 1; - comple = 1; + if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */ + g = Cudd_Not(g); + h = Cudd_Not(h); + change = 1; + comple = 1; } if (change) { - *fp = f; - *gp = g; - *hp = h; + *fp = f; + *gp = g; + *hp = h; } /* Here we can skip the use of cuddI, because the operands are known @@ -1255,5 +1319,7 @@ bddVarToCanonicalSimple( } /* end of bddVarToCanonicalSimple */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddBridge.c b/src/bdd/cudd/cuddBridge.c index da0b4379..d0f96a2f 100644 --- a/src/bdd/cudd/cuddBridge.c +++ b/src/bdd/cudd/cuddBridge.c @@ -8,48 +8,76 @@ different managers.] Description [External procedures included in this file: - <ul> - <li> Cudd_addBddThreshold() - <li> Cudd_addBddStrictThreshold() - <li> Cudd_addBddInterval() - <li> Cudd_addBddIthBit() - <li> Cudd_BddToAdd() - <li> Cudd_addBddPattern() - <li> Cudd_bddTransfer() - </ul> - Internal procedures included in this file: - <ul> - <li> cuddBddTransfer() - <li> cuddAddBddDoPattern() - </ul> - Static procedures included in this file: - <ul> - <li> addBddDoThreshold() - <li> addBddDoStrictThreshold() - <li> addBddDoInterval() - <li> addBddDoIthBit() - <li> ddBddToAddRecur() - <li> cuddBddTransferRecur() - </ul> - ] + <ul> + <li> Cudd_addBddThreshold() + <li> Cudd_addBddStrictThreshold() + <li> Cudd_addBddInterval() + <li> Cudd_addBddIthBit() + <li> Cudd_BddToAdd() + <li> Cudd_addBddPattern() + <li> Cudd_bddTransfer() + </ul> + Internal procedures included in this file: + <ul> + <li> cuddBddTransfer() + <li> cuddAddBddDoPattern() + </ul> + Static procedures included in this file: + <ul> + <li> addBddDoThreshold() + <li> addBddDoStrictThreshold() + <li> addBddDoInterval() + <li> addBddDoIthBit() + <li> ddBddToAddRecur() + <li> cuddBddTransferRecur() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -70,7 +98,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.19 2008/04/25 06:42:55 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -78,21 +106,29 @@ static char rcsid[] DD_UNUSED = "$Id: cuddBridge.c,v 1.1.1.1 2003/02/24 22:23:51 /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + /**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * addBddDoThreshold ARGS((DdManager *dd, DdNode *f, DdNode *val)); -static DdNode * addBddDoStrictThreshold ARGS((DdManager *dd, DdNode *f, DdNode *val)); -static DdNode * addBddDoInterval ARGS((DdManager *dd, DdNode *f, DdNode *l, DdNode *u)); -static DdNode * addBddDoIthBit ARGS((DdManager *dd, DdNode *f, DdNode *index)); -static DdNode * ddBddToAddRecur ARGS((DdManager *dd, DdNode *B)); -static DdNode * cuddBddTransferRecur ARGS((DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table)); +static DdNode * addBddDoThreshold (DdManager *dd, DdNode *f, DdNode *val); +static DdNode * addBddDoStrictThreshold (DdManager *dd, DdNode *f, DdNode *val); +static DdNode * addBddDoInterval (DdManager *dd, DdNode *f, DdNode *l, DdNode *u); +static DdNode * addBddDoIthBit (DdManager *dd, DdNode *f, DdNode *index); +static DdNode * ddBddToAddRecur (DdManager *dd, DdNode *B); +static DdNode * cuddBddTransferRecur (DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif + /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -128,13 +164,13 @@ Cudd_addBddThreshold( cuddRef(val); do { - dd->reordered = 0; - res = addBddDoThreshold(dd, f, val); + dd->reordered = 0; + res = addBddDoThreshold(dd, f, val); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd, val); - return(NULL); + Cudd_RecursiveDeref(dd, val); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, val); @@ -173,13 +209,13 @@ Cudd_addBddStrictThreshold( cuddRef(val); do { - dd->reordered = 0; - res = addBddDoStrictThreshold(dd, f, val); + dd->reordered = 0; + res = addBddDoStrictThreshold(dd, f, val); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd, val); - return(NULL); + Cudd_RecursiveDeref(dd, val); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, val); @@ -223,20 +259,20 @@ Cudd_addBddInterval( cuddRef(l); u = cuddUniqueConst(dd,upper); if (u == NULL) { - Cudd_RecursiveDeref(dd,l); - return(NULL); + Cudd_RecursiveDeref(dd,l); + return(NULL); } cuddRef(u); do { - dd->reordered = 0; - res = addBddDoInterval(dd, f, l, u); + dd->reordered = 0; + res = addBddDoInterval(dd, f, l, u); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd, l); - Cudd_RecursiveDeref(dd, u); - return(NULL); + Cudd_RecursiveDeref(dd, l); + Cudd_RecursiveDeref(dd, u); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, l); @@ -280,13 +316,13 @@ Cudd_addBddIthBit( cuddRef(index); do { - dd->reordered = 0; - res = addBddDoIthBit(dd, f, index); + dd->reordered = 0; + res = addBddDoIthBit(dd, f, index); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd, index); - return(NULL); + Cudd_RecursiveDeref(dd, index); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, index); @@ -317,8 +353,8 @@ Cudd_BddToAdd( DdNode *res; do { - dd->reordered = 0; - res = ddBddToAddRecur(dd, B); + dd->reordered = 0; + res = ddBddToAddRecur(dd, B); } while (dd->reordered ==1); return(res); @@ -347,8 +383,8 @@ Cudd_addBddPattern( DdNode *res; do { - dd->reordered = 0; - res = cuddAddBddDoPattern(dd, f); + dd->reordered = 0; + res = cuddAddBddDoPattern(dd, f); } while (dd->reordered == 1); return(res); @@ -377,8 +413,8 @@ Cudd_bddTransfer( { DdNode *res; do { - ddDestination->reordered = 0; - res = cuddBddTransfer(ddSource, ddDestination, f); + ddDestination->reordered = 0; + res = cuddBddTransfer(ddSource, ddDestination, f); } while (ddDestination->reordered == 1); return(res); @@ -414,7 +450,7 @@ cuddBddTransfer( st_generator *gen = NULL; DdNode *key, *value; - table = st_init_table(st_ptrcmp, st_ptrhash);; + table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) goto failure; res = cuddBddTransferRecur(ddS, ddD, f, table); if (res != NULL) cuddRef(res); @@ -424,8 +460,8 @@ cuddBddTransfer( ** reordering. */ gen = st_init_gen(table); if (gen == NULL) goto failure; - while (st_gen(gen, (const char **) &key, (char **) &value)) { - Cudd_RecursiveDeref(ddD, value); + while (st_gen(gen, (const char **)&key, (char **)&value)) { + Cudd_RecursiveDeref(ddD, value); } st_free_gen(gen); gen = NULL; st_free_table(table); table = NULL; @@ -434,8 +470,8 @@ cuddBddTransfer( return(res); failure: + /* No need to free gen because it is always NULL here. */ if (table != NULL) st_free_table(table); - if (gen != NULL) st_free_gen(gen); return(NULL); } /* end of cuddBddTransfer */ @@ -465,7 +501,7 @@ cuddAddBddDoPattern( statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { - return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd))); + return(Cudd_NotCond(DD_ONE(dd),f == DD_ZERO(dd))); } /* Check cache. */ @@ -482,25 +518,25 @@ cuddAddBddDoPattern( E = cuddAddBddDoPattern(dd,fvn); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - cuddRef(E); - if (Cudd_IsComplement(T)) { - res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); - if (res == NULL) { Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); return(NULL); } - res = Cudd_Not(res); + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); } else { - res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); - if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } } cuddDeref(T); cuddDeref(E); @@ -543,7 +579,7 @@ addBddDoThreshold( statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { - return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(val))); + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(val))); } /* Check cache. */ @@ -560,25 +596,25 @@ addBddDoThreshold( E = addBddDoThreshold(dd,fvn,val); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - cuddRef(E); - if (Cudd_IsComplement(T)) { - res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); - if (res == NULL) { Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); return(NULL); } - res = Cudd_Not(res); + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); } else { - res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); - if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } } cuddDeref(T); cuddDeref(E); @@ -616,7 +652,7 @@ addBddDoStrictThreshold( statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { - return(Cudd_NotCond(DD_ONE(dd),cuddV(f) <= cuddV(val))); + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) <= cuddV(val))); } /* Check cache. */ @@ -633,25 +669,25 @@ addBddDoStrictThreshold( E = addBddDoStrictThreshold(dd,fvn,val); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - cuddRef(E); - if (Cudd_IsComplement(T)) { - res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); - if (res == NULL) { Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); return(NULL); } - res = Cudd_Not(res); + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); } else { - res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); - if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } } cuddDeref(T); cuddDeref(E); @@ -690,7 +726,7 @@ addBddDoInterval( statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { - return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(l) || cuddV(f) > cuddV(u))); + return(Cudd_NotCond(DD_ONE(dd),cuddV(f) < cuddV(l) || cuddV(f) > cuddV(u))); } /* Check cache. */ @@ -707,25 +743,25 @@ addBddDoInterval( E = addBddDoInterval(dd,fvn,l,u); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - cuddRef(E); - if (Cudd_IsComplement(T)) { - res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); - if (res == NULL) { Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); return(NULL); } - res = Cudd_Not(res); + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); } else { - res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); - if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } } cuddDeref(T); cuddDeref(E); @@ -764,9 +800,9 @@ addBddDoIthBit( statLine(dd); /* Check terminal case. */ if (cuddIsConstant(f)) { - mask = 1 << ((int) cuddV(index)); - value = (int) cuddV(f); - return(Cudd_NotCond(DD_ONE(dd),(value & mask) == 0)); + mask = 1 << ((int) cuddV(index)); + value = (int) cuddV(f); + return(Cudd_NotCond(DD_ONE(dd),(value & mask) == 0)); } /* Check cache. */ @@ -783,25 +819,25 @@ addBddDoIthBit( E = addBddDoIthBit(dd,fvn,index); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - cuddRef(E); - if (Cudd_IsComplement(T)) { - res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); - if (res == NULL) { Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); return(NULL); } - res = Cudd_Not(res); + cuddRef(E); + if (Cudd_IsComplement(T)) { + res = (T == E) ? Cudd_Not(T) : cuddUniqueInter(dd,v,Cudd_Not(T),Cudd_Not(E)); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + res = Cudd_Not(res); } else { - res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); - if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } + res = (T == E) ? T : cuddUniqueInter(dd,v,T,E); + if (res == NULL) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } } cuddDeref(T); cuddDeref(E); @@ -839,24 +875,24 @@ ddBddToAddRecur( one = DD_ONE(dd); if (Cudd_IsConstant(B)) { - if (B == one) { - res = one; - } else { - res = DD_ZERO(dd); - } - return(res); + if (B == one) { + res = one; + } else { + res = DD_ZERO(dd); + } + return(res); } /* Check visited table */ res = cuddCacheLookup1(dd,ddBddToAddRecur,B); if (res != NULL) return(res); if (Cudd_IsComplement(B)) { - complement = 1; - Bt = cuddT(Cudd_Regular(B)); - Be = cuddE(Cudd_Regular(B)); + complement = 1; + Bt = cuddT(Cudd_Regular(B)); + Be = cuddE(Cudd_Regular(B)); } else { - Bt = cuddT(B); - Be = cuddE(B); + Bt = cuddT(B); + Be = cuddE(B); } T = ddBddToAddRecur(dd, Bt); @@ -865,32 +901,32 @@ ddBddToAddRecur( E = ddBddToAddRecur(dd, Be); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); + Cudd_RecursiveDeref(dd, T); + return(NULL); } cuddRef(E); /* No need to check for T == E, because it is guaranteed not to happen. */ res = cuddUniqueInter(dd, (int) Cudd_Regular(B)->index, T, E); if (res == NULL) { - Cudd_RecursiveDeref(dd ,T); - Cudd_RecursiveDeref(dd ,E); - return(NULL); + Cudd_RecursiveDeref(dd ,T); + Cudd_RecursiveDeref(dd ,E); + return(NULL); } cuddDeref(T); cuddDeref(E); if (complement) { - cuddRef(res); - res1 = cuddAddCmplRecur(dd, res); - if (res1 == NULL) { + cuddRef(res); + res1 = cuddAddCmplRecur(dd, res); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(res1); Cudd_RecursiveDeref(dd, res); - return(NULL); - } - cuddRef(res1); - Cudd_RecursiveDeref(dd, res); - res = res1; - cuddDeref(res); + res = res1; + cuddDeref(res); } /* Store result. */ @@ -922,7 +958,7 @@ cuddBddTransferRecur( { DdNode *ft, *fe, *t, *e, *var, *res; DdNode *one, *zero; - int index; + int index; int comple = 0; statLine(ddD); @@ -937,8 +973,8 @@ cuddBddTransferRecur( /* Now f is a regular pointer to a non-constant node. */ /* Check the cache. */ - if(st_lookup(table, (char *)f, (char **) &res)) - return(Cudd_NotCond(res,comple)); + if (st_lookup(table, (const char *)f, (char **)&res)) + return(Cudd_NotCond(res,comple)); /* Recursive step. */ index = f->index; @@ -960,27 +996,29 @@ cuddBddTransferRecur( zero = Cudd_Not(one); var = cuddUniqueInter(ddD,index,one,zero); if (var == NULL) { - Cudd_RecursiveDeref(ddD, t); - Cudd_RecursiveDeref(ddD, e); + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); return(NULL); } res = cuddBddIteRecur(ddD,var,t,e); if (res == NULL) { - Cudd_RecursiveDeref(ddD, t); - Cudd_RecursiveDeref(ddD, e); - return(NULL); + Cudd_RecursiveDeref(ddD, t); + Cudd_RecursiveDeref(ddD, e); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(ddD, t); Cudd_RecursiveDeref(ddD, e); if (st_add_direct(table, (char *) f, (char *) res) == ST_OUT_OF_MEM) { - Cudd_RecursiveDeref(ddD, res); - return(NULL); + Cudd_RecursiveDeref(ddD, res); + return(NULL); } return(Cudd_NotCond(res,comple)); } /* end of cuddBddTransferRecur */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddCache.c b/src/bdd/cudd/cuddCache.c index d66a8606..d9722ee9 100644 --- a/src/bdd/cudd/cuddCache.c +++ b/src/bdd/cudd/cuddCache.c @@ -7,41 +7,69 @@ Synopsis [Functions for cache insertion and lookup.] Description [Internal procedures included in this module: - <ul> - <li> cuddInitCache() - <li> cuddCacheInsert() - <li> cuddCacheInsert2() - <li> cuddCacheLookup() - <li> cuddCacheLookupZdd() - <li> cuddCacheLookup2() - <li> cuddCacheLookup2Zdd() - <li> cuddConstantLookup() - <li> cuddCacheProfile() - <li> cuddCacheResize() - <li> cuddCacheFlush() - <li> cuddComputeFloorLog2() - </ul> - Static procedures included in this module: - <ul> - </ul> ] + <ul> + <li> cuddInitCache() + <li> cuddCacheInsert() + <li> cuddCacheInsert2() + <li> cuddCacheLookup() + <li> cuddCacheLookupZdd() + <li> cuddCacheLookup2() + <li> cuddCacheLookup2Zdd() + <li> cuddConstantLookup() + <li> cuddCacheProfile() + <li> cuddCacheResize() + <li> cuddCacheFlush() + <li> cuddComputeFloorLog2() + </ul> + Static procedures included in this module: + <ul> + </ul> ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -65,7 +93,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddCache.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddCache.c,v 1.34 2009/02/19 16:17:50 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -123,8 +151,8 @@ cuddInitCache( cacheSize = 1 << logSize; unique->acache = ABC_ALLOC(DdCache,cacheSize+1); if (unique->acache == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } /* If the size of the cache entry is a power of 2, we want to ** enforce alignment to that power of two. This happens when @@ -145,8 +173,8 @@ cuddInitCache( unique->maxCacheHard = maxCacheSize; /* If cacheSlack is non-negative, we can resize. */ unique->cacheSlack = (int) ddMin(maxCacheSize, - DD_MAX_CACHE_TO_SLOTS_RATIO*unique->slots) - - 2 * (int) cacheSize; + DD_MAX_CACHE_TO_SLOTS_RATIO*unique->slots) - + 2 * (int) cacheSize; Cudd_SetMinHit(unique,DD_MIN_HIT); /* Initialize to avoid division by 0 and immediate resizing. */ unique->cacheMisses = (double) (int) (cacheSize * unique->minHit + 1); @@ -163,10 +191,10 @@ cuddInitCache( /* Initialize the cache */ for (i = 0; (unsigned) i < cacheSize; i++) { - unique->cache[i].h = 0; /* unused slots */ - unique->cache[i].data = NULL; /* invalid entry */ + unique->cache[i].h = 0; /* unused slots */ + unique->cache[i].data = NULL; /* invalid entry */ #ifdef DD_CACHE_PROFILE - unique->cache[i].count = 0; + unique->cache[i].count = 0; #endif } @@ -235,7 +263,7 @@ cuddCacheInsert( void cuddCacheInsert2( DdManager * table, - DdNode * (*op)(DdManager *, DdNode *, DdNode *), + DD_CTFP op, DdNode * f, DdNode * g, DdNode * data) @@ -277,7 +305,7 @@ cuddCacheInsert2( void cuddCacheInsert1( DdManager * table, - DdNode * (*op)(DdManager *, DdNode *), + DD_CTFP1 op, DdNode * f, DdNode * data) { @@ -343,21 +371,21 @@ cuddCacheLookup( posn = ddCHash2(uh,uf,ug,table->cacheShift); en = &cache[posn]; if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && - en->h==uh) { - data = Cudd_Regular(en->data); - table->cacheHits++; - if (data->ref == 0) { - cuddReclaim(table,data); - } - return(en->data); + en->h==uh) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); } /* Cache miss: decide whether to resize. */ table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -405,21 +433,21 @@ cuddCacheLookupZdd( posn = ddCHash2(uh,uf,ug,table->cacheShift); en = &cache[posn]; if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug && - en->h==uh) { - data = Cudd_Regular(en->data); - table->cacheHits++; - if (data->ref == 0) { - cuddReclaimZdd(table,data); - } - return(en->data); + en->h==uh) { + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); } /* Cache miss: decide whether to resize. */ table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -443,7 +471,7 @@ cuddCacheLookupZdd( DdNode * cuddCacheLookup2( DdManager * table, - DdNode * (*op)(DdManager *, DdNode *, DdNode *), + DD_CTFP op, DdNode * f, DdNode * g) { @@ -461,20 +489,20 @@ cuddCacheLookup2( posn = ddCHash2(op,f,g,table->cacheShift); en = &cache[posn]; if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) { - data = Cudd_Regular(en->data); - table->cacheHits++; - if (data->ref == 0) { - cuddReclaim(table,data); - } - return(en->data); + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); } /* Cache miss: decide whether to resize. */ table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -497,7 +525,7 @@ cuddCacheLookup2( DdNode * cuddCacheLookup1( DdManager * table, - DdNode * (*op)(DdManager *, DdNode *), + DD_CTFP1 op, DdNode * f) { int posn; @@ -514,20 +542,20 @@ cuddCacheLookup1( posn = ddCHash2(op,f,f,table->cacheShift); en = &cache[posn]; if (en->data != NULL && en->f==f && en->h==(ptruint)op) { - data = Cudd_Regular(en->data); - table->cacheHits++; - if (data->ref == 0) { - cuddReclaim(table,data); - } - return(en->data); + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaim(table,data); + } + return(en->data); } /* Cache miss: decide whether to resize. */ table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -551,7 +579,7 @@ cuddCacheLookup1( DdNode * cuddCacheLookup2Zdd( DdManager * table, - DdNode * (*op)(DdManager *, DdNode *, DdNode *), + DD_CTFP op, DdNode * f, DdNode * g) { @@ -569,20 +597,20 @@ cuddCacheLookup2Zdd( posn = ddCHash2(op,f,g,table->cacheShift); en = &cache[posn]; if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) { - data = Cudd_Regular(en->data); - table->cacheHits++; - if (data->ref == 0) { - cuddReclaimZdd(table,data); - } - return(en->data); + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); } /* Cache miss: decide whether to resize. */ table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -605,7 +633,7 @@ cuddCacheLookup2Zdd( DdNode * cuddCacheLookup1Zdd( DdManager * table, - DdNode * (*op)(DdManager *, DdNode *), + DD_CTFP1 op, DdNode * f) { int posn; @@ -622,20 +650,20 @@ cuddCacheLookup1Zdd( posn = ddCHash2(op,f,f,table->cacheShift); en = &cache[posn]; if (en->data != NULL && en->f==f && en->h==(ptruint)op) { - data = Cudd_Regular(en->data); - table->cacheHits++; - if (data->ref == 0) { - cuddReclaimZdd(table,data); - } - return(en->data); + data = Cudd_Regular(en->data); + table->cacheHits++; + if (data->ref == 0) { + cuddReclaimZdd(table,data); + } + return(en->data); } /* Cache miss: decide whether to resize. */ table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -688,8 +716,8 @@ cuddConstantLookup( * referenced, but only tested for being a constant. */ if (en->data != NULL && - en->f == (DdNodePtr)uf && en->g == (DdNodePtr)ug && en->h == uh) { - table->cacheHits++; + en->f == (DdNodePtr)uf && en->g == (DdNodePtr)ug && en->h == uh) { + table->cacheHits++; return(en->data); } @@ -697,8 +725,8 @@ cuddConstantLookup( table->cacheMisses++; if (table->cacheSlack >= 0 && - table->cacheHits > table->cacheMisses * table->minHit) { - cuddCacheResize(table); + table->cacheHits > table->cacheMisses * table->minHit) { + cuddCacheResize(table); } return(NULL); @@ -746,46 +774,46 @@ cuddCacheProfile( hystogramQ = ABC_ALLOC(double, nbins); if (hystogramQ == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } hystogramR = ABC_ALLOC(double, nbins); if (hystogramR == NULL) { - ABC_FREE(hystogramQ); - table->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(hystogramQ); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < nbins; i++) { - hystogramQ[i] = 0; - hystogramR[i] = 0; + hystogramQ[i] = 0; + hystogramR[i] = 0; } for (i = 0; i < slots; i++) { - thiscount = (long) cache[i].count; - if (thiscount > max) { - max = thiscount; - imax = i; - } - if (thiscount < min) { - min = thiscount; - imin = i; - } - if (thiscount == 0) { - nzeroes++; - } - count = (double) thiscount; - mean += count; - meansq += count * count; - totalcount += count; - expected += count * (double) i; - bin = (i * nbins) / slots; - hystogramQ[bin] += (double) thiscount; - bin = i % nbins; - hystogramR[bin] += (double) thiscount; + thiscount = (long) cache[i].count; + if (thiscount > max) { + max = thiscount; + imax = i; + } + if (thiscount < min) { + min = thiscount; + imin = i; + } + if (thiscount == 0) { + nzeroes++; + } + count = (double) thiscount; + mean += count; + meansq += count * count; + totalcount += count; + expected += count * (double) i; + bin = (i * nbins) / slots; + hystogramQ[bin] += (double) thiscount; + bin = i % nbins; + hystogramR[bin] += (double) thiscount; } mean /= (double) slots; meansq /= (double) slots; - + /* Compute the standard deviation from both the data and the ** theoretical model for a random distribution. */ stddev = sqrt(meansq - mean*mean); @@ -803,43 +831,43 @@ cuddCacheProfile( if (retval == EOF) return(0); exUsed = 100.0 * (1.0 - exp(-totalcount / (double) slots)); retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n", - 100.0 - (double) nzeroes * 100.0 / (double) slots, - exUsed); + 100.0 - (double) nzeroes * 100.0 / (double) slots, + exUsed); if (retval == EOF) return(0); if (totalcount > 0) { - expected /= totalcount; - retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); - if (retval == EOF) return(0); - retval = fprintf(fp," (expected bin value = %g)\nBy quotient:", - expected); - if (retval == EOF) return(0); - for (i = nbins - 1; i>=0; i--) { - retval = fprintf(fp," %.0f", hystogramQ[i]); + expected /= totalcount; + retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); if (retval == EOF) return(0); - } - retval = fprintf(fp,"\nBy residue: "); - if (retval == EOF) return(0); - for (i = nbins - 1; i>=0; i--) { - retval = fprintf(fp," %.0f", hystogramR[i]); + retval = fprintf(fp," (expected bin value = %g)\nBy quotient:", + expected); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp," %.0f", hystogramQ[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\nBy residue: "); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp," %.0f", hystogramR[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\n"); if (retval == EOF) return(0); - } - retval = fprintf(fp,"\n"); - if (retval == EOF) return(0); } ABC_FREE(hystogramQ); ABC_FREE(hystogramR); #else for (i = 0; i < slots; i++) { - nzeroes += cache[i].h == 0; + nzeroes += cache[i].h == 0; } exUsed = 100.0 * - (1.0 - exp(-(table->cacheinserts - table->cacheLastInserts) / - (double) slots)); + (1.0 - exp(-(table->cacheinserts - table->cacheLastInserts) / + (double) slots)); retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n", - 100.0 - (double) nzeroes * 100.0 / (double) slots, - exUsed); + 100.0 - (double) nzeroes * 100.0 / (double) slots, + exUsed); if (retval == EOF) return(0); #endif return(1); @@ -868,8 +896,8 @@ cuddCacheResize( unsigned int slots, oldslots; double offset; int moved = 0; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; #ifndef DD_CACHE_PROFILE ptruint misalignment; DdNodePtr *mem; @@ -882,11 +910,11 @@ cuddCacheResize( #ifdef DD_VERBOSE (void) fprintf(table->err,"Resizing the cache from %d to %d entries\n", - oldslots, slots); + oldslots, slots); (void) fprintf(table->err, - "\thits = %g\tmisses = %g\thit ratio = %5.3f\n", - table->cacheHits, table->cacheMisses, - table->cacheHits / (table->cacheHits + table->cacheMisses)); + "\thits = %g\tmisses = %g\thit ratio = %5.3f\n", + table->cacheHits, table->cacheMisses, + table->cacheHits / (table->cacheHits + table->cacheMisses)); #endif saveHandler = MMoutOfMemory; @@ -896,14 +924,14 @@ cuddCacheResize( /* If we fail to allocate the new table we just give up. */ if (cache == NULL) { #ifdef DD_VERBOSE - (void) fprintf(table->err,"Resizing failed. Giving up.\n"); + (void) fprintf(table->err,"Resizing failed. Giving up.\n"); #endif - table->cacheSlots = oldslots; - table->acache = oldacache; - /* Do not try to resize again. */ - table->maxCacheHard = oldslots - 1; - table->cacheSlack = - (int)(oldslots + 1); - return; + table->cacheSlots = oldslots; + table->acache = oldacache; + /* Do not try to resize again. */ + table->maxCacheHard = oldslots - 1; + table->cacheSlack = - (int) (oldslots + 1); + return; } /* If the size of the cache entry is a power of 2, we want to ** enforce alignment to that power of two. This happens when @@ -923,28 +951,28 @@ cuddCacheResize( /* Clear new cache. */ for (i = 0; (unsigned) i < slots; i++) { - cache[i].data = NULL; - cache[i].h = 0; + cache[i].data = NULL; + cache[i].h = 0; #ifdef DD_CACHE_PROFILE - cache[i].count = 0; + cache[i].count = 0; #endif } /* Copy from old cache to new one. */ for (i = 0; (unsigned) i < oldslots; i++) { - old = &oldcache[i]; - if (old->data != NULL) { - posn = ddCHash2(old->h,old->f,old->g,shift); - entry = &cache[posn]; - entry->f = old->f; - entry->g = old->g; - entry->h = old->h; - entry->data = old->data; + old = &oldcache[i]; + if (old->data != NULL) { + posn = ddCHash2(old->h,old->f,old->g,shift); + entry = &cache[posn]; + entry->f = old->f; + entry->g = old->g; + entry->h = old->h; + entry->data = old->data; #ifdef DD_CACHE_PROFILE - entry->count = 1; + entry->count = 1; #endif - moved++; - } + moved++; + } } ABC_FREE(oldacache); @@ -983,8 +1011,8 @@ cuddCacheFlush( slots = table->cacheSlots; cache = table->cache; for (i = 0; i < slots; i++) { - table->cachedeletions += cache[i].data != NULL; - cache[i].data = NULL; + table->cachedeletions += cache[i].data != NULL; + cache[i].data = NULL; } table->cacheLastInserts = table->cacheinserts; @@ -1014,8 +1042,8 @@ cuddComputeFloorLog2( assert(value > 0); #endif while (value > 1) { - floorLog++; - value >>= 1; + floorLog++; + value >>= 1; } return(floorLog); @@ -1024,5 +1052,7 @@ cuddComputeFloorLog2( /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddCheck.c b/src/bdd/cudd/cuddCheck.c index 92c0f5e1..5526aaf2 100644 --- a/src/bdd/cudd/cuddCheck.c +++ b/src/bdd/cudd/cuddCheck.c @@ -7,30 +7,57 @@ Synopsis [Functions to check consistency of data structures.] Description [External procedures included in this module: - <ul> - <li> Cudd_DebugCheck() - <li> Cudd_CheckKeys() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddHeapProfile() - <li> cuddPrintNode() - <li> cuddPrintVarGroups() - </ul> - Static procedures included in this module: - <ul> - <li> debugFindParent() - </ul> - ] + <ul> + <li> Cudd_DebugCheck() + <li> Cudd_CheckKeys() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddHeapProfile() + <li> cuddPrintNode() + <li> cuddPrintVarGroups() + </ul> + Static procedures included in this module: + <ul> + <li> debugFindParent() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -40,6 +67,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -60,7 +88,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddCheck.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddCheck.c,v 1.35 2009/03/08 02:49:01 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -74,9 +102,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddCheck.c,v 1.1.1.1 2003/02/24 22:23:51 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void debugFindParent ARGS((DdManager *table, DdNode *node)); +static void debugFindParent (DdManager *table, DdNode *node); #if 0 -static void debugCheckParent ARGS((DdManager *table, DdNode *node)); +static void debugCheckParent (DdManager *table, DdNode *node); #endif /**AutomaticEnd***************************************************************/ @@ -115,232 +143,233 @@ Cudd_DebugCheck( DdManager * table) { unsigned int i; - int j,count; - int slots; - DdNodePtr *nodelist; - DdNode *f; - DdNode *sentinel = &(table->sentinel); - st_table *edgeTable; /* stores internal ref count for each node */ - st_generator *gen; - int flag = 0; - int totalNode; - int deadNode; - int index; - - - edgeTable = st_init_table(st_ptrcmp, st_ptrhash);; + int j,count; + int slots; + DdNodePtr *nodelist; + DdNode *f; + DdNode *sentinel = &(table->sentinel); + st_table *edgeTable; /* stores internal ref count for each node */ + st_generator *gen; + int flag = 0; + int totalNode; + int deadNode; + int index; + + + edgeTable = st_init_table(st_ptrcmp,st_ptrhash); if (edgeTable == NULL) return(CUDD_OUT_OF_MEM); /* Check the BDD/ADD subtables. */ for (i = 0; i < (unsigned) table->size; i++) { - index = table->invperm[i]; - if (i != (unsigned) table->perm[index]) { - (void) fprintf(table->err, - "Permutation corrupted: invperm[%d] = %d\t perm[%d] = %d\n", - i, index, index, table->perm[index]); - } - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; - - totalNode = 0; - deadNode = 0; - for (j = 0; j < slots; j++) { /* for each subtable slot */ - f = nodelist[j]; - while (f != sentinel) { - totalNode++; - if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { - if ((int) f->index != index) { - (void) fprintf(table->err, - "Error: node has illegal index\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if ((unsigned) cuddI(table,cuddT(f)->index) <= i || - (unsigned) cuddI(table,Cudd_Regular(cuddE(f))->index) - <= i) { - (void) fprintf(table->err, - "Error: node has illegal children\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if (Cudd_Regular(cuddT(f)) != cuddT(f)) { - (void) fprintf(table->err, - "Error: node has illegal form\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if (cuddT(f) == cuddE(f)) { - (void) fprintf(table->err, - "Error: node has identical children\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if (cuddT(f)->ref == 0 || Cudd_Regular(cuddE(f))->ref == 0) { + index = table->invperm[i]; + if (i != (unsigned) table->perm[index]) { (void) fprintf(table->err, - "Error: live node has dead children\n"); - cuddPrintNode(f,table->err); - flag =1; - } - /* Increment the internal reference count for the - ** then child of the current node. - */ - if (st_lookup(edgeTable,(char *)cuddT(f),(char **)&count)) { - count++; - } else { - count = 1; - } - if (st_insert(edgeTable,(char *)cuddT(f), - (char *)(long)count) == ST_OUT_OF_MEM) { - st_free_table(edgeTable); - return(CUDD_OUT_OF_MEM); - } - - /* Increment the internal reference count for the - ** else child of the current node. - */ - if (st_lookup(edgeTable,(char *)Cudd_Regular(cuddE(f)),(char **)&count)) { - count++; - } else { - count = 1; - } - if (st_insert(edgeTable,(char *)Cudd_Regular(cuddE(f)), - (char *)(long)count) == ST_OUT_OF_MEM) { - st_free_table(edgeTable); - return(CUDD_OUT_OF_MEM); - } - } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { - deadNode++; + "Permutation corrupted: invperm[%u] = %d\t perm[%d] = %d\n", + i, index, index, table->perm[index]); + } + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { /* for each subtable slot */ + f = nodelist[j]; + while (f != sentinel) { + totalNode++; + if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { + if ((int) f->index != index) { + (void) fprintf(table->err, + "Error: node has illegal index\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if ((unsigned) cuddI(table,cuddT(f)->index) <= i || + (unsigned) cuddI(table,Cudd_Regular(cuddE(f))->index) + <= i) { + (void) fprintf(table->err, + "Error: node has illegal children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (Cudd_Regular(cuddT(f)) != cuddT(f)) { + (void) fprintf(table->err, + "Error: node has illegal form\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f) == cuddE(f)) { + (void) fprintf(table->err, + "Error: node has identical children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f)->ref == 0 || Cudd_Regular(cuddE(f))->ref == 0) { + (void) fprintf(table->err, + "Error: live node has dead children\n"); + cuddPrintNode(f,table->err); + flag =1; + } + /* Increment the internal reference count for the + ** then child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddT(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + + /* Increment the internal reference count for the + ** else child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)Cudd_Regular(cuddE(f)), + &count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)Cudd_Regular(cuddE(f)), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { + deadNode++; #if 0 - debugCheckParent(table,f); + debugCheckParent(table,f); #endif - } else { - fprintf(table->err, - "Error: node has illegal Then or Else pointers\n"); - cuddPrintNode(f,table->err); + } else { + fprintf(table->err, + "Error: node has illegal Then or Else pointers\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + + f = f->next; + } /* for each element of the collision list */ + } /* for each subtable slot */ + + if ((unsigned) totalNode != table->subtables[i].keys) { + fprintf(table->err,"Error: wrong number of total nodes\n"); flag = 1; } - - f = f->next; - } /* for each element of the collision list */ - } /* for each subtable slot */ - - if ((unsigned) totalNode != table->subtables[i].keys) { - fprintf(table->err,"Error: wrong number of total nodes\n"); - flag = 1; - } - if ((unsigned) deadNode != table->subtables[i].dead) { - fprintf(table->err,"Error: wrong number of dead nodes\n"); - flag = 1; - } - } /* for each BDD/ADD subtable */ + if ((unsigned) deadNode != table->subtables[i].dead) { + fprintf(table->err,"Error: wrong number of dead nodes\n"); + flag = 1; + } + } /* for each BDD/ADD subtable */ /* Check the ZDD subtables. */ for (i = 0; i < (unsigned) table->sizeZ; i++) { - index = table->invpermZ[i]; - if (i != (unsigned) table->permZ[index]) { - (void) fprintf(table->err, - "Permutation corrupted: invpermZ[%d] = %d\t permZ[%d] = %d in ZDD\n", - i, index, index, table->permZ[index]); - } - nodelist = table->subtableZ[i].nodelist; - slots = table->subtableZ[i].slots; - - totalNode = 0; - deadNode = 0; - for (j = 0; j < slots; j++) { /* for each subtable slot */ - f = nodelist[j]; - while (f != NULL) { - totalNode++; - if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { - if ((int) f->index != index) { - (void) fprintf(table->err, - "Error: ZDD node has illegal index\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if (Cudd_IsComplement(cuddT(f)) || - Cudd_IsComplement(cuddE(f))) { - (void) fprintf(table->err, - "Error: ZDD node has complemented children\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if ((unsigned) cuddIZ(table,cuddT(f)->index) <= i || - (unsigned) cuddIZ(table,cuddE(f)->index) <= i) { - (void) fprintf(table->err, - "Error: ZDD node has illegal children\n"); - cuddPrintNode(f,table->err); - cuddPrintNode(cuddT(f),table->err); - cuddPrintNode(cuddE(f),table->err); - flag = 1; - } - if (cuddT(f) == DD_ZERO(table)) { + index = table->invpermZ[i]; + if (i != (unsigned) table->permZ[index]) { (void) fprintf(table->err, - "Error: ZDD node has zero then child\n"); - cuddPrintNode(f,table->err); - flag = 1; - } - if (cuddT(f)->ref == 0 || cuddE(f)->ref == 0) { - (void) fprintf(table->err, - "Error: ZDD live node has dead children\n"); - cuddPrintNode(f,table->err); - flag =1; - } - /* Increment the internal reference count for the - ** then child of the current node. - */ - if (st_lookup(edgeTable,(char *)cuddT(f),(char **)&count)) { - count++; - } else { - count = 1; - } - if (st_insert(edgeTable,(char *)cuddT(f), - (char *)(long)count) == ST_OUT_OF_MEM) { - st_free_table(edgeTable); - return(CUDD_OUT_OF_MEM); - } - - /* Increment the internal reference count for the - ** else child of the current node. - */ - if (st_lookup(edgeTable,(char *)cuddE(f),(char **)&count)) { - count++; - } else { - count = 1; - } - if (st_insert(edgeTable,(char *)cuddE(f), - (char *)(long)count) == ST_OUT_OF_MEM) { - st_free_table(edgeTable); - table->errorCode = CUDD_MEMORY_OUT; - return(CUDD_OUT_OF_MEM); - } - } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { - deadNode++; + "Permutation corrupted: invpermZ[%u] = %d\t permZ[%d] = %d in ZDD\n", + i, index, index, table->permZ[index]); + } + nodelist = table->subtableZ[i].nodelist; + slots = table->subtableZ[i].slots; + + totalNode = 0; + deadNode = 0; + for (j = 0; j < slots; j++) { /* for each subtable slot */ + f = nodelist[j]; + while (f != NULL) { + totalNode++; + if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) { + if ((int) f->index != index) { + (void) fprintf(table->err, + "Error: ZDD node has illegal index\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (Cudd_IsComplement(cuddT(f)) || + Cudd_IsComplement(cuddE(f))) { + (void) fprintf(table->err, + "Error: ZDD node has complemented children\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if ((unsigned) cuddIZ(table,cuddT(f)->index) <= i || + (unsigned) cuddIZ(table,cuddE(f)->index) <= i) { + (void) fprintf(table->err, + "Error: ZDD node has illegal children\n"); + cuddPrintNode(f,table->err); + cuddPrintNode(cuddT(f),table->err); + cuddPrintNode(cuddE(f),table->err); + flag = 1; + } + if (cuddT(f) == DD_ZERO(table)) { + (void) fprintf(table->err, + "Error: ZDD node has zero then child\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + if (cuddT(f)->ref == 0 || cuddE(f)->ref == 0) { + (void) fprintf(table->err, + "Error: ZDD live node has dead children\n"); + cuddPrintNode(f,table->err); + flag =1; + } + /* Increment the internal reference count for the + ** then child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddT(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + return(CUDD_OUT_OF_MEM); + } + + /* Increment the internal reference count for the + ** else child of the current node. + */ + if (st_lookup_int(edgeTable,(char *)cuddE(f),&count)) { + count++; + } else { + count = 1; + } + if (st_insert(edgeTable,(char *)cuddE(f), + (char *)(long)count) == ST_OUT_OF_MEM) { + st_free_table(edgeTable); + table->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); + } + } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) { + deadNode++; #if 0 - debugCheckParent(table,f); + debugCheckParent(table,f); #endif - } else { + } else { + fprintf(table->err, + "Error: ZDD node has illegal Then or Else pointers\n"); + cuddPrintNode(f,table->err); + flag = 1; + } + + f = f->next; + } /* for each element of the collision list */ + } /* for each subtable slot */ + + if ((unsigned) totalNode != table->subtableZ[i].keys) { fprintf(table->err, - "Error: ZDD node has illegal Then or Else pointers\n"); - cuddPrintNode(f,table->err); + "Error: wrong number of total nodes in ZDD\n"); flag = 1; } - - f = f->next; - } /* for each element of the collision list */ - } /* for each subtable slot */ - - if ((unsigned) totalNode != table->subtableZ[i].keys) { - fprintf(table->err, - "Error: wrong number of total nodes in ZDD\n"); - flag = 1; - } - if ((unsigned) deadNode != table->subtableZ[i].dead) { - fprintf(table->err, - "Error: wrong number of dead nodes in ZDD\n"); - flag = 1; - } - } /* for each ZDD subtable */ + if ((unsigned) deadNode != table->subtableZ[i].dead) { + fprintf(table->err, + "Error: wrong number of dead nodes in ZDD\n"); + flag = 1; + } + } /* for each ZDD subtable */ /* Check the constant table. */ nodelist = table->constants.nodelist; @@ -349,50 +378,50 @@ Cudd_DebugCheck( totalNode = 0; deadNode = 0; for (j = 0; j < slots; j++) { - f = nodelist[j]; - while (f != NULL) { - totalNode++; - if (f->ref != 0) { - if (f->index != CUDD_CONST_INDEX) { - fprintf(table->err,"Error: node has illegal index\n"); + f = nodelist[j]; + while (f != NULL) { + totalNode++; + if (f->ref != 0) { + if (f->index != CUDD_CONST_INDEX) { + fprintf(table->err,"Error: node has illegal index\n"); #if SIZEOF_VOID_P == 8 - fprintf(table->err, - " node 0x%lx, id = %d, ref = %d, value = %g\n", - (unsigned long)f,f->index,f->ref,cuddV(f)); + fprintf(table->err, + " node 0x%lx, id = %u, ref = %u, value = %g\n", + (ptruint)f,f->index,f->ref,cuddV(f)); #else - fprintf(table->err, - " node 0x%x, id = %d, ref = %d, value = %g\n", - (unsigned)f,f->index,f->ref,cuddV(f)); + fprintf(table->err, + " node 0x%x, id = %hu, ref = %hu, value = %g\n", + (ptruint)f,f->index,f->ref,cuddV(f)); #endif - flag = 1; - } - } else { - deadNode++; + flag = 1; + } + } else { + deadNode++; + } + f = f->next; } - f = f->next; - } } if ((unsigned) totalNode != table->constants.keys) { - (void) fprintf(table->err, - "Error: wrong number of total nodes in constants\n"); - flag = 1; + (void) fprintf(table->err, + "Error: wrong number of total nodes in constants\n"); + flag = 1; } if ((unsigned) deadNode != table->constants.dead) { - (void) fprintf(table->err, - "Error: wrong number of dead nodes in constants\n"); - flag = 1; + (void) fprintf(table->err, + "Error: wrong number of dead nodes in constants\n"); + flag = 1; } gen = st_init_gen(edgeTable); - while (st_gen(gen,(const char **)&f,(char **)&count)) { - if (count > (int)(f->ref) && f->ref != DD_MAXREF) { + while (st_gen(gen, (const char **)&f, (char **)&count)) { + if (count > (int)(f->ref) && f->ref != DD_MAXREF) { #if SIZEOF_VOID_P == 8 - fprintf(table->err,"ref count error at node 0x%lx, count = %d, id = %d, ref = %d, then = 0x%lx, else = 0x%lx\n",(unsigned long)f,count,f->index,f->ref,(unsigned long)cuddT(f),(unsigned long)cuddE(f)); + 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)); #else - fprintf(table->err,"ref count error at node 0x%x, count = %d, id = %d, ref = %d, then = 0x%x, else = 0x%x\n",(unsigned)f,count,f->index,f->ref,(unsigned)cuddT(f),(unsigned)cuddE(f)); + 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)); #endif - debugFindParent(table,f); - flag = 1; - } + debugFindParent(table,f); + flag = 1; + } } st_free_gen(gen); st_free_table(edgeTable); @@ -449,80 +478,80 @@ Cudd_CheckKeys( size = table->size; for (i = 0; i < size; i++) { - subtable = &(table->subtables[i]); - nodelist = subtable->nodelist; - keys = subtable->keys; - dead = subtable->dead; - totalKeys += keys; - slots = subtable->slots; - shift = subtable->shift; - logSlots = sizeof(int) * 8 - shift; - if (((slots >> logSlots) << logSlots) != slots) { - (void) fprintf(table->err, - "Unique table %d is not the right power of 2\n", i); - (void) fprintf(table->err, - " slots = %u shift = %d\n", slots, shift); - } - totalSlots += slots; - totalDead += dead; - for (j = 0; (unsigned) j < slots; j++) { - node = nodelist[j]; - if (node != sentinel) { - nonEmpty++; - } - while (node != sentinel) { - keys--; - if (node->ref == 0) { - dead--; + subtable = &(table->subtables[i]); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + slots = subtable->slots; + shift = subtable->shift; + logSlots = sizeof(int) * 8 - shift; + if (((slots >> logSlots) << logSlots) != slots) { + (void) fprintf(table->err, + "Unique table %d is not the right power of 2\n", i); + (void) fprintf(table->err, + " slots = %u shift = %d\n", slots, shift); } - node = node->next; + totalSlots += slots; + totalDead += dead; + for (j = 0; (unsigned) j < slots; j++) { + node = nodelist[j]; + if (node != sentinel) { + nonEmpty++; + } + while (node != sentinel) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } } - } - if (keys != 0) { - (void) fprintf(table->err, "Wrong number of keys found \ + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ in unique table %d (difference=%d)\n", i, keys); - count++; - } - if (dead != 0) { - (void) fprintf(table->err, "Wrong number of dead found \ + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ in unique table no. %d (difference=%d)\n", i, dead); - } - } /* for each BDD/ADD subtable */ + } + } /* for each BDD/ADD subtable */ /* Check the ZDD subtables. */ size = table->sizeZ; for (i = 0; i < size; i++) { - subtable = &(table->subtableZ[i]); - nodelist = subtable->nodelist; - keys = subtable->keys; - dead = subtable->dead; - totalKeys += keys; - totalSlots += subtable->slots; - totalDead += dead; - for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - if (node != NULL) { - nonEmpty++; - } - while (node != NULL) { - keys--; - if (node->ref == 0) { - dead--; - } - node = node->next; + subtable = &(table->subtableZ[i]); + nodelist = subtable->nodelist; + keys = subtable->keys; + dead = subtable->dead; + totalKeys += keys; + totalSlots += subtable->slots; + totalDead += dead; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + if (node != NULL) { + nonEmpty++; + } + while (node != NULL) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; + } } - } - if (keys != 0) { - (void) fprintf(table->err, "Wrong number of keys found \ + if (keys != 0) { + (void) fprintf(table->err, "Wrong number of keys found \ in ZDD unique table no. %d (difference=%d)\n", i, keys); - count++; - } - if (dead != 0) { - (void) fprintf(table->err, "Wrong number of dead found \ + count++; + } + if (dead != 0) { + (void) fprintf(table->err, "Wrong number of dead found \ in ZDD unique table no. %d (difference=%d)\n", i, dead); - } - } /* for each ZDD subtable */ + } + } /* for each ZDD subtable */ /* Check the constant table. */ subtable = &(table->constants); @@ -533,43 +562,43 @@ in ZDD unique table no. %d (difference=%d)\n", i, dead); totalSlots += subtable->slots; totalDead += dead; for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - if (node != NULL) { - nonEmpty++; - } - while (node != NULL) { - keys--; - if (node->ref == 0) { - dead--; + node = nodelist[j]; + if (node != NULL) { + nonEmpty++; + } + while (node != NULL) { + keys--; + if (node->ref == 0) { + dead--; + } + node = node->next; } - node = node->next; - } } if (keys != 0) { - (void) fprintf(table->err, "Wrong number of keys found \ + (void) fprintf(table->err, "Wrong number of keys found \ in the constant table (difference=%d)\n", keys); - count++; + count++; } if (dead != 0) { - (void) fprintf(table->err, "Wrong number of dead found \ + (void) fprintf(table->err, "Wrong number of dead found \ in the constant table (difference=%d)\n", dead); } if ((unsigned) totalKeys != table->keys + table->keysZ) { - (void) fprintf(table->err, "Wrong number of total keys found \ -(difference=%d)\n", totalKeys-table->keys); + (void) fprintf(table->err, "Wrong number of total keys found \ +(difference=%d)\n", (int) (totalKeys-table->keys)); } if ((unsigned) totalSlots != table->slots) { - (void) fprintf(table->err, "Wrong number of total slots found \ -(difference=%d)\n", totalSlots-table->slots); + (void) fprintf(table->err, "Wrong number of total slots found \ +(difference=%d)\n", (int) (totalSlots-table->slots)); } if (table->minDead != (unsigned) (table->gcFrac * table->slots)) { - (void) fprintf(table->err, "Wrong number of minimum dead found \ -(%d vs. %d)\n", table->minDead, - (unsigned) (table->gcFrac * (double) table->slots)); + (void) fprintf(table->err, "Wrong number of minimum dead found \ +(%u vs. %u)\n", table->minDead, + (unsigned) (table->gcFrac * (double) table->slots)); } if ((unsigned) totalDead != table->dead + table->deadZ) { - (void) fprintf(table->err, "Wrong number of total dead found \ -(difference=%d)\n", totalDead-table->dead); + (void) fprintf(table->err, "Wrong number of total dead found \ +(difference=%d)\n", (int) (totalDead-table->dead)); } (void)printf("Average length of non-empty lists = %g\n", (double) table->keys / (double) nonEmpty); @@ -612,51 +641,51 @@ cuddHeapProfile( { int ntables = dd->size; DdSubtable *subtables = dd->subtables; - int i, /* loop index */ - nodes, /* live nodes in i-th layer */ - retval, /* return value of fprintf */ - largest = -1, /* index of the table with most live nodes */ - maxnodes = -1, /* maximum number of live nodes in a table */ - nonempty = 0; /* number of tables with live nodes */ + int i, /* loop index */ + nodes, /* live nodes in i-th layer */ + retval, /* return value of fprintf */ + largest = -1, /* index of the table with most live nodes */ + maxnodes = -1, /* maximum number of live nodes in a table */ + nonempty = 0; /* number of tables with live nodes */ /* Print header. */ #if SIZEOF_VOID_P == 8 retval = fprintf(dd->out,"*** DD heap profile for 0x%lx ***\n", - (unsigned long) dd); + (ptruint) dd); #else retval = fprintf(dd->out,"*** DD heap profile for 0x%x ***\n", - (unsigned) dd); + (ptruint) dd); #endif if (retval == EOF) return 0; /* Print number of live nodes for each nonempty table. */ for (i=0; i<ntables; i++) { - nodes = subtables[i].keys - subtables[i].dead; - if (nodes) { - nonempty++; - retval = fprintf(dd->out,"%5d: %5d nodes\n", i, nodes); - if (retval == EOF) return 0; - if (nodes > maxnodes) { - maxnodes = nodes; - largest = i; + nodes = subtables[i].keys - subtables[i].dead; + if (nodes) { + nonempty++; + retval = fprintf(dd->out,"%5d: %5d nodes\n", i, nodes); + if (retval == EOF) return 0; + if (nodes > maxnodes) { + maxnodes = nodes; + largest = i; + } } } - } nodes = dd->constants.keys - dd->constants.dead; if (nodes) { - nonempty++; - retval = fprintf(dd->out,"const: %5d nodes\n", nodes); - if (retval == EOF) return 0; - if (nodes > maxnodes) { - maxnodes = nodes; - largest = CUDD_CONST_INDEX; - } + nonempty++; + retval = fprintf(dd->out,"const: %5d nodes\n", nodes); + if (retval == EOF) return 0; + if (nodes > maxnodes) { + maxnodes = nodes; + largest = CUDD_CONST_INDEX; + } } /* Print summary. */ retval = fprintf(dd->out,"Summary: %d tables, %d non-empty, largest: %d ", - ntables+1, nonempty, largest); + ntables+1, nonempty, largest); if (retval == EOF) return 0; retval = fprintf(dd->out,"(with %d nodes)\n", maxnodes); if (retval == EOF) return 0; @@ -684,9 +713,9 @@ cuddPrintNode( { f = Cudd_Regular(f); #if SIZEOF_VOID_P == 8 - (void) fprintf(fp," node 0x%lx, id = %d, ref = %d, then = 0x%lx, else = 0x%lx\n",(unsigned long)f,f->index,f->ref,(unsigned long)cuddT(f),(unsigned long)cuddE(f)); + (void) fprintf(fp," node 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); #else - (void) fprintf(fp," node 0x%x, id = %d, ref = %d, then = 0x%x, else = 0x%x\n",(unsigned)f,f->index,f->ref,(unsigned)cuddT(f),(unsigned)cuddE(f)); + (void) fprintf(fp," node 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); #endif } /* end of cuddPrintNode */ @@ -728,32 +757,32 @@ cuddPrintVarGroups( assert(root->younger == NULL || root->younger->elder == root); assert(root->elder == NULL || root->elder->younger == root); if (zdd) { - level = dd->permZ[root->index]; + level = dd->permZ[root->index]; } else { - level = dd->perm[root->index]; + level = dd->perm[root->index]; } if (!silent) (void) printf("(%d",level); if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) { - if (!silent) (void) printf(","); + if (!silent) (void) printf(","); } else { - node = root->child; - while (node != NULL) { - assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); - assert(node->parent == root); - cuddPrintVarGroups(dd,node,zdd,silent); - node = node->younger; - } + node = root->child; + while (node != NULL) { + assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size)); + assert(node->parent == root); + cuddPrintVarGroups(dd,node,zdd,silent); + node = node->younger; + } } if (!silent) { - (void) printf("%d", level + root->size - 1); - if (root->flags != MTR_DEFAULT) { - (void) printf("|"); - if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); - if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); - if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); - } - (void) printf(")"); - if (root->parent == NULL) (void) printf("\n"); + (void) printf("%d", (int) (level + root->size - 1)); + if (root->flags != MTR_DEFAULT) { + (void) printf("|"); + if (MTR_TEST(root,MTR_FIXED)) (void) printf("F"); + if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N"); + if (MTR_TEST(root,MTR_SOFT)) (void) printf("S"); + } + (void) printf(")"); + if (root->parent == NULL) (void) printf("\n"); } assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0); return; @@ -783,29 +812,29 @@ debugFindParent( DdNode * node) { int i,j; - int slots; - DdNodePtr *nodelist; - DdNode *f; - + int slots; + DdNodePtr *nodelist; + DdNode *f; + for (i = 0; i < cuddI(table,node->index); i++) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; - for (j=0;j<slots;j++) { - f = nodelist[j]; - while (f != NULL) { - if (cuddT(f) == node || Cudd_Regular(cuddE(f)) == node) { + for (j=0;j<slots;j++) { + f = nodelist[j]; + while (f != NULL) { + if (cuddT(f) == node || Cudd_Regular(cuddE(f)) == node) { #if SIZEOF_VOID_P == 8 - (void) fprintf(table->out,"parent is at 0x%lx, id = %d, ref = %d, then = 0x%lx, else = 0x%lx\n", - (unsigned long)f,f->index,f->ref,(unsigned long)cuddT(f),(unsigned long)cuddE(f)); + (void) fprintf(table->out,"parent is at 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n", + (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); #else - (void) fprintf(table->out,"parent is at 0x%x, id = %d, ref = %d, then = 0x%x, else = 0x%x\n", - (unsigned)f,f->index,f->ref,(unsigned)cuddT(f),(unsigned)cuddE(f)); + (void) fprintf(table->out,"parent is at 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n", + (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f)); #endif + } + f = f->next; + } } - f = f->next; - } - } } } /* end of debugFindParent */ @@ -830,27 +859,29 @@ debugCheckParent( DdNode * node) { int i,j; - int slots; - DdNode **nodelist,*f; - - for (i = 0; i < cuddI(table,node->index); i++) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; + int slots; + DdNode **nodelist,*f; - for (j=0;j<slots;j++) { - f = nodelist[j]; - while (f != NULL) { - if ((Cudd_Regular(cuddE(f)) == node || cuddT(f) == node) && f->ref != 0) { - (void) fprintf(table->err, - "error with zero ref count\n"); - (void) fprintf(table->err,"parent is 0x%x, id = %d, ref = %d, then = 0x%x, else = 0x%x\n",f,f->index,f->ref,cuddT(f),cuddE(f)); - (void) fprintf(table->err,"child is 0x%x, id = %d, ref = %d, then = 0x%x, else = 0x%x\n",node,node->index,node->ref,cuddT(node),cuddE(node)); - } - f = f->next; + for (i = 0; i < cuddI(table,node->index); i++) { + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + + for (j=0;j<slots;j++) { + f = nodelist[j]; + while (f != NULL) { + if ((Cudd_Regular(cuddE(f)) == node || cuddT(f) == node) && f->ref != 0) { + (void) fprintf(table->err, + "error with zero ref count\n"); + (void) fprintf(table->err,"parent is 0x%x, id = %u, ref = %u, then = 0x%x, else = 0x%x\n",f,f->index,f->ref,cuddT(f),cuddE(f)); + (void) fprintf(table->err,"child is 0x%x, id = %u, ref = %u, then = 0x%x, else = 0x%x\n",node,node->index,node->ref,cuddT(node),cuddE(node)); + } + f = f->next; + } } } - } } #endif + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddClip.c b/src/bdd/cudd/cuddClip.c index 23331339..028474fe 100644 --- a/src/bdd/cudd/cuddClip.c +++ b/src/bdd/cudd/cuddClip.c @@ -7,29 +7,56 @@ Synopsis [Clipping functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_bddClippingAnd() - <li> Cudd_bddClippingAndAbstract() - </ul> + <ul> + <li> Cudd_bddClippingAnd() + <li> Cudd_bddClippingAndAbstract() + </ul> Internal procedures included in this module: - <ul> - <li> cuddBddClippingAnd() - <li> cuddBddClippingAndAbstract() - </ul> + <ul> + <li> cuddBddClippingAnd() + <li> cuddBddClippingAndAbstract() + </ul> Static procedures included in this module: - <ul> - <li> cuddBddClippingAndRecur() - <li> cuddBddClipAndAbsRecur() - </ul> + <ul> + <li> cuddBddClippingAndRecur() + <li> cuddBddClipAndAbsRecur() + </ul> SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -40,6 +67,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -59,7 +87,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.8 2004/08/13 18:04:47 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -73,8 +101,8 @@ static char rcsid[] DD_UNUSED = "$Id: cuddClip.c,v 1.1.1.1 2003/02/24 22:23:51 w /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * cuddBddClippingAndRecur ARGS((DdManager *manager, DdNode *f, DdNode *g, int distance, int direction)); -static DdNode * cuddBddClipAndAbsRecur ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int distance, int direction)); +static DdNode * cuddBddClippingAndRecur (DdManager *manager, DdNode *f, DdNode *g, int distance, int direction); +static DdNode * cuddBddClipAndAbsRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube, int distance, int direction); /**AutomaticEnd***************************************************************/ @@ -108,8 +136,8 @@ Cudd_bddClippingAnd( DdNode *res; do { - dd->reordered = 0; - res = cuddBddClippingAnd(dd,f,g,maxDepth,direction); + dd->reordered = 0; + res = cuddBddClippingAnd(dd,f,g,maxDepth,direction); } while (dd->reordered == 1); return(res); @@ -143,8 +171,8 @@ Cudd_bddClippingAndAbstract( DdNode *res; do { - dd->reordered = 0; - res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction); + dd->reordered = 0; + res = cuddBddClippingAndAbstract(dd,f,g,cube,maxDepth,direction); } while (dd->reordered == 1); return(res); @@ -248,7 +276,7 @@ cuddBddClippingAndRecur( DdNode *F, *ft, *fe, *G, *gt, *ge; DdNode *one, *zero, *r, *t, *e; unsigned int topf, topg, index; - DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *); + DD_CTFP cacheOp; statLine(manager); one = DD_ONE(manager); @@ -259,15 +287,15 @@ cuddBddClippingAndRecur( if (f == g || g == one) return(f); if (f == one) return(g); if (distance == 0) { - /* One last attempt at returning the right result. We sort of - ** cheat by calling Cudd_bddLeq. */ - if (Cudd_bddLeq(manager,f,g)) return(f); - if (Cudd_bddLeq(manager,g,f)) return(g); - if (direction == 1) { - if (Cudd_bddLeq(manager,f,Cudd_Not(g)) || - Cudd_bddLeq(manager,g,Cudd_Not(f))) return(zero); - } - return(Cudd_NotCond(one,(direction == 0))); + /* One last attempt at returning the right result. We sort of + ** cheat by calling Cudd_bddLeq. */ + if (Cudd_bddLeq(manager,f,g)) return(f); + if (Cudd_bddLeq(manager,g,f)) return(g); + if (direction == 1) { + if (Cudd_bddLeq(manager,f,Cudd_Not(g)) || + Cudd_bddLeq(manager,g,Cudd_Not(f))) return(zero); + } + return(Cudd_NotCond(one,(direction == 0))); } /* At this point f and g are not constant. */ @@ -276,16 +304,16 @@ cuddBddClippingAndRecur( /* Check cache. Try to increase cache efficiency by sorting the ** pointers. */ if (f > g) { - DdNode *tmp = f; - f = g; g = tmp; + DdNode *tmp = f; + f = g; g = tmp; } F = Cudd_Regular(f); G = Cudd_Regular(g); - cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) - (direction ? Cudd_bddClippingAnd : cuddBddClippingAnd); + cacheOp = (DD_CTFP) + (direction ? Cudd_bddClippingAnd : cuddBddClippingAnd); if (F->ref != 1 || G->ref != 1) { - r = cuddCacheLookup2(manager, cacheOp, f, g); - if (r != NULL) return(r); + r = cuddCacheLookup2(manager, cacheOp, f, g); + if (r != NULL) return(r); } /* Here we can skip the use of cuddI, because the operands are known @@ -296,27 +324,27 @@ cuddBddClippingAndRecur( /* Compute cofactors. */ if (topf <= topg) { - index = F->index; - ft = cuddT(F); - fe = cuddE(F); - if (Cudd_IsComplement(f)) { - ft = Cudd_Not(ft); - fe = Cudd_Not(fe); - } + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } } else { - index = G->index; - ft = fe = f; + index = G->index; + ft = fe = f; } if (topg <= topf) { - gt = cuddT(G); - ge = cuddE(G); - if (Cudd_IsComplement(g)) { - gt = Cudd_Not(gt); - ge = Cudd_Not(ge); - } + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } } else { - gt = ge = g; + gt = ge = g; } t = cuddBddClippingAndRecur(manager, ft, gt, distance, direction); @@ -324,35 +352,35 @@ cuddBddClippingAndRecur( cuddRef(t); e = cuddBddClippingAndRecur(manager, fe, ge, distance, direction); if (e == NULL) { - Cudd_RecursiveDeref(manager, t); - return(NULL); + Cudd_RecursiveDeref(manager, t); + return(NULL); } cuddRef(e); if (t == e) { - r = t; + r = t; } else { - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); - if (r == NULL) { - Cudd_RecursiveDeref(manager, t); - Cudd_RecursiveDeref(manager, e); - return(NULL); - } - r = Cudd_Not(r); - } else { - r = cuddUniqueInter(manager,(int)index,t,e); - if (r == NULL) { - Cudd_RecursiveDeref(manager, t); - Cudd_RecursiveDeref(manager, e); - return(NULL); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } } } - } cuddDeref(e); cuddDeref(t); if (F->ref != 1 || G->ref != 1) - cuddCacheInsert2(manager, cacheOp, f, g, r); + cuddCacheInsert2(manager, cacheOp, f, g, r); return(r); } /* end of cuddBddClippingAndRecur */ @@ -393,15 +421,15 @@ cuddBddClipAndAbsRecur( /* Terminal cases. */ if (f == zero || g == zero || f == Cudd_Not(g)) return(zero); - if (f == one && g == one) return(one); + if (f == one && g == one) return(one); if (cube == one) { - return(cuddBddClippingAndRecur(manager, f, g, distance, direction)); + return(cuddBddClippingAndRecur(manager, f, g, distance, direction)); } if (f == one || f == g) { - return (cuddBddExistAbstractRecur(manager, g, cube)); + return (cuddBddExistAbstractRecur(manager, g, cube)); } if (g == one) { - return (cuddBddExistAbstractRecur(manager, f, cube)); + return (cuddBddExistAbstractRecur(manager, f, cube)); } if (distance == 0) return(Cudd_NotCond(one,(direction == 0))); @@ -410,19 +438,19 @@ cuddBddClipAndAbsRecur( /* Check cache. */ if (f > g) { /* Try to increase cache efficiency. */ - DdNode *tmp = f; - f = g; g = tmp; + DdNode *tmp = f; + f = g; g = tmp; } F = Cudd_Regular(f); G = Cudd_Regular(g); cacheTag = direction ? DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG : - DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG; + DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG; if (F->ref != 1 || G->ref != 1) { - r = cuddCacheLookup(manager, cacheTag, - f, g, cube); - if (r != NULL) { - return(r); - } + r = cuddCacheLookup(manager, cacheTag, + f, g, cube); + if (r != NULL) { + return(r); + } } /* Here we can skip the use of cuddI, because the operands are known @@ -434,39 +462,39 @@ cuddBddClipAndAbsRecur( topcube = manager->perm[cube->index]; if (topcube < top) { - return(cuddBddClipAndAbsRecur(manager, f, g, cuddT(cube), - distance, direction)); + return(cuddBddClipAndAbsRecur(manager, f, g, cuddT(cube), + distance, direction)); } /* Now, topcube >= top. */ if (topf == top) { - index = F->index; - ft = cuddT(F); - fe = cuddE(F); - if (Cudd_IsComplement(f)) { - ft = Cudd_Not(ft); - fe = Cudd_Not(fe); - } + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } } else { - index = G->index; - ft = fe = f; + index = G->index; + ft = fe = f; } if (topg == top) { - gt = cuddT(G); - ge = cuddE(G); - if (Cudd_IsComplement(g)) { - gt = Cudd_Not(gt); - ge = Cudd_Not(ge); - } + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } } else { - gt = ge = g; + gt = ge = g; } if (topcube == top) { - Cube = cuddT(cube); + Cube = cuddT(cube); } else { - Cube = cube; + Cube = cube; } t = cuddBddClipAndAbsRecur(manager, ft, gt, Cube, distance, direction); @@ -476,61 +504,63 @@ cuddBddClipAndAbsRecur( ** the else branch if t is 1. */ if (t == one && topcube == top) { - if (F->ref != 1 || G->ref != 1) - cuddCacheInsert(manager, cacheTag, f, g, cube, one); - return(one); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert(manager, cacheTag, f, g, cube, one); + return(one); } cuddRef(t); e = cuddBddClipAndAbsRecur(manager, fe, ge, Cube, distance, direction); if (e == NULL) { - Cudd_RecursiveDeref(manager, t); - return(NULL); - } - cuddRef(e); - - if (topcube == top) { /* abstract */ - r = cuddBddClippingAndRecur(manager, Cudd_Not(t), Cudd_Not(e), - distance, (direction == 0)); - if (r == NULL) { Cudd_RecursiveDeref(manager, t); - Cudd_RecursiveDeref(manager, e); return(NULL); } - r = Cudd_Not(r); - cuddRef(r); - Cudd_RecursiveDeref(manager, t); - Cudd_RecursiveDeref(manager, e); - cuddDeref(r); - } else if (t == e) { - r = t; - cuddDeref(t); - cuddDeref(e); - } else { - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + cuddRef(e); + + if (topcube == top) { /* abstract */ + r = cuddBddClippingAndRecur(manager, Cudd_Not(t), Cudd_Not(e), + distance, (direction == 0)); if (r == NULL) { - Cudd_RecursiveDeref(manager, t); - Cudd_RecursiveDeref(manager, e); - return(NULL); + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); } r = Cudd_Not(r); - } else { - r = cuddUniqueInter(manager,(int)index,t,e); - if (r == NULL) { + cuddRef(r); Cudd_RecursiveDeref(manager, t); Cudd_RecursiveDeref(manager, e); - return(NULL); + cuddDeref(r); + } else if (t == e) { + r = t; + cuddDeref(t); + cuddDeref(e); + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_RecursiveDeref(manager, t); + Cudd_RecursiveDeref(manager, e); + return(NULL); + } } - } - cuddDeref(e); - cuddDeref(t); + cuddDeref(e); + cuddDeref(t); } if (F->ref != 1 || G->ref != 1) - cuddCacheInsert(manager, cacheTag, f, g, cube, r); + cuddCacheInsert(manager, cacheTag, f, g, cube, r); return (r); } /* end of cuddBddClipAndAbsRecur */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddCof.c b/src/bdd/cudd/cuddCof.c index 26ff330d..004689c2 100644 --- a/src/bdd/cudd/cuddCof.c +++ b/src/bdd/cudd/cuddCof.c @@ -7,34 +7,62 @@ Synopsis [Cofactoring functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_Cofactor() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddGetBranches() - <li> cuddCheckCube() - <li> cuddCofactorRecur() - </ul> - ] + <ul> + <li> Cudd_Cofactor() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddGetBranches() + <li> cuddCheckCube() + <li> cuddCofactorRecur() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -55,7 +83,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddCof.c,v 1.9 2004/08/13 18:04:47 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -101,13 +129,13 @@ Cudd_Cofactor( zero = Cudd_Not(DD_ONE(dd)); if (g == zero || g == DD_ZERO(dd)) { - (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); + (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); } do { - dd->reordered = 0; - res = cuddCofactorRecur(dd,f,g); + dd->reordered = 0; + res = cuddCofactorRecur(dd,f,g); } while (dd->reordered == 1); return(res); @@ -136,13 +164,13 @@ cuddGetBranches( DdNode ** g1, DdNode ** g0) { - DdNode *G = Cudd_Regular(g); + DdNode *G = Cudd_Regular(g); *g1 = cuddT(G); *g0 = cuddE(G); if (Cudd_IsComplement(g)) { - *g1 = Cudd_Not(*g1); - *g0 = Cudd_Not(*g0); + *g1 = Cudd_Not(*g1); + *g0 = Cudd_Not(*g0); } } /* end of cuddGetBranches */ @@ -224,7 +252,7 @@ cuddCofactorRecur( comple = f != F; r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g); if (r != NULL) { - return(Cudd_NotCond(r,comple)); + return(Cudd_NotCond(r,comple)); } topf = dd->perm[F->index]; @@ -237,57 +265,57 @@ cuddCofactorRecur( ** remembers whether we have to complement the result or not. */ if (topf <= topg) { - f1 = cuddT(F); f0 = cuddE(F); + f1 = cuddT(F); f0 = cuddE(F); } else { - f1 = f0 = F; + f1 = f0 = F; } if (topg <= topf) { - g1 = cuddT(G); g0 = cuddE(G); - if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); } + g1 = cuddT(G); g0 = cuddE(G); + if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); } } else { - g1 = g0 = g; + g1 = g0 = g; } zero = Cudd_Not(one); if (topf >= topg) { - if (g0 == zero || g0 == DD_ZERO(dd)) { - r = cuddCofactorRecur(dd, f1, g1); - } else if (g1 == zero || g1 == DD_ZERO(dd)) { - r = cuddCofactorRecur(dd, f0, g0); - } else { - (void) fprintf(dd->out, - "Cudd_Cofactor: Invalid restriction 2\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); - } - if (r == NULL) return(NULL); + if (g0 == zero || g0 == DD_ZERO(dd)) { + r = cuddCofactorRecur(dd, f1, g1); + } else if (g1 == zero || g1 == DD_ZERO(dd)) { + r = cuddCofactorRecur(dd, f0, g0); + } else { + (void) fprintf(dd->out, + "Cudd_Cofactor: Invalid restriction 2\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); + } + if (r == NULL) return(NULL); } else /* if (topf < topg) */ { - t = cuddCofactorRecur(dd, f1, g); - if (t == NULL) return(NULL); + t = cuddCofactorRecur(dd, f1, g); + if (t == NULL) return(NULL); cuddRef(t); e = cuddCofactorRecur(dd, f0, g); - if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - cuddRef(e); - - if (t == e) { - r = t; - } else if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e)); - if (r != NULL) - r = Cudd_Not(r); - } else { - r = cuddUniqueInter(dd,(int)F->index,t,e); - } - if (r == NULL) { - Cudd_RecursiveDeref(dd ,e); - Cudd_RecursiveDeref(dd ,t); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e)); + if (r != NULL) + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(dd,(int)F->index,t,e); + } + if (r == NULL) { + Cudd_RecursiveDeref(dd ,e); + Cudd_RecursiveDeref(dd ,t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(dd,Cudd_Cofactor,F,g,r); @@ -301,5 +329,7 @@ cuddCofactorRecur( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddCompose.c b/src/bdd/cudd/cuddCompose.c index 6fc4fa48..e3b2e556 100644 --- a/src/bdd/cudd/cuddCompose.c +++ b/src/bdd/cudd/cuddCompose.c @@ -7,38 +7,38 @@ Synopsis [Functional composition and variable permutation of DDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_bddCompose() - <li> Cudd_addCompose() - <li> Cudd_addPermute() - <li> Cudd_addSwapVariables() - <li> Cudd_bddPermute() - <li> Cudd_bddVarMap() - <li> Cudd_SetVarMap() - <li> Cudd_bddSwapVariables() - <li> Cudd_bddAdjPermuteX() - <li> Cudd_addVectorCompose() - <li> Cudd_addGeneralVectorCompose() - <li> Cudd_addNonSimCompose() - <li> Cudd_bddVectorCompose() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddComposeRecur() - <li> cuddAddComposeRecur() - </ul> - Static procedures included in this module: - <ul> - <li> cuddAddPermuteRecur() - <li> cuddBddPermuteRecur() - <li> cuddBddVarMapRecur() - <li> cuddAddVectorComposeRecur() - <li> cuddAddGeneralVectorComposeRecur() - <li> cuddAddNonSimComposeRecur() - <li> cuddBddVectorComposeRecur() - <li> ddIsIthAddVar() - <li> ddIsIthAddVarPair() - </ul> + <ul> + <li> Cudd_bddCompose() + <li> Cudd_addCompose() + <li> Cudd_addPermute() + <li> Cudd_addSwapVariables() + <li> Cudd_bddPermute() + <li> Cudd_bddVarMap() + <li> Cudd_SetVarMap() + <li> Cudd_bddSwapVariables() + <li> Cudd_bddAdjPermuteX() + <li> Cudd_addVectorCompose() + <li> Cudd_addGeneralVectorCompose() + <li> Cudd_addNonSimCompose() + <li> Cudd_bddVectorCompose() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddBddComposeRecur() + <li> cuddAddComposeRecur() + </ul> + Static procedures included in this module: + <ul> + <li> cuddAddPermuteRecur() + <li> cuddBddPermuteRecur() + <li> cuddBddVarMapRecur() + <li> cuddAddVectorComposeRecur() + <li> cuddAddGeneralVectorComposeRecur() + <li> cuddAddNonSimComposeRecur() + <li> cuddBddVectorComposeRecur() + <li> ddIsIthAddVar() + <li> ddIsIthAddVarPair() + </ul> The permutation functions use a local cache because the results to be remembered depend on the permutation being applied. Since the permutation is just an array, it cannot be stored in the global @@ -48,10 +48,37 @@ Author [Fabio Somenzi and Kavita Ravi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -62,6 +89,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -79,7 +107,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddCompose.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddCompose.c,v 1.45 2004/08/13 18:04:47 fabio Exp $"; #endif #ifdef DD_DEBUG @@ -102,16 +130,16 @@ static int addGeneralVectorComposeHits; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * cuddAddPermuteRecur ARGS((DdManager *manager, DdHashTable *table, DdNode *node, int *permut)); -static DdNode * cuddBddPermuteRecur ARGS((DdManager *manager, DdHashTable *table, DdNode *node, int *permut)); -static DdNode * cuddBddVarMapRecur ARGS((DdManager *manager, DdNode *f)); -static DdNode * cuddAddVectorComposeRecur ARGS((DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest)); -static DdNode * cuddAddNonSimComposeRecur ARGS((DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub)); -static DdNode * cuddBddVectorComposeRecur ARGS((DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest)); -DD_INLINE static int ddIsIthAddVar ARGS((DdManager *dd, DdNode *f, unsigned int i)); +static DdNode * cuddAddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut); +static DdNode * cuddBddPermuteRecur (DdManager *manager, DdHashTable *table, DdNode *node, int *permut); +static DdNode * cuddBddVarMapRecur (DdManager *manager, DdNode *f); +static DdNode * cuddAddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest); +static DdNode * cuddAddNonSimComposeRecur (DdManager *dd, DdNode *f, DdNode **vector, DdNode *key, DdNode *cube, int lastsub); +static DdNode * cuddBddVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vector, int deepest); +DD_INLINE static int ddIsIthAddVar (DdManager *dd, DdNode *f, unsigned int i); -static DdNode * cuddAddGeneralVectorComposeRecur ARGS((DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest)); -DD_INLINE static int ddIsIthAddVarPair ARGS((DdManager *dd, DdNode *f, DdNode *g, unsigned int i)); +static DdNode * cuddAddGeneralVectorComposeRecur (DdManager *dd, DdHashTable *table, DdNode *f, DdNode **vectorOn, DdNode **vectorOff, int deepest); +DD_INLINE static int ddIsIthAddVarPair (DdManager *dd, DdNode *f, DdNode *g, unsigned int i); /**AutomaticEnd***************************************************************/ @@ -145,12 +173,12 @@ Cudd_bddCompose( DdNode *proj, *res; /* Sanity check. */ - if (v < 0 || v > dd->size) return(NULL); + if (v < 0 || v >= dd->size) return(NULL); proj = dd->vars[v]; do { - dd->reordered = 0; - res = cuddBddComposeRecur(dd,f,g,proj); + dd->reordered = 0; + res = cuddBddComposeRecur(dd,f,g,proj); } while (dd->reordered == 1); return(res); @@ -182,12 +210,12 @@ Cudd_addCompose( DdNode *proj, *res; /* Sanity check. */ - if (v < 0 || v > dd->size) return(NULL); + if (v < 0 || v >= dd->size) return(NULL); proj = dd->vars[v]; do { - dd->reordered = 0; - res = cuddAddComposeRecur(dd,f,g,proj); + dd->reordered = 0; + res = cuddAddComposeRecur(dd,f,g,proj); } while (dd->reordered == 1); return(res); @@ -216,18 +244,18 @@ Cudd_addPermute( DdNode * node, int * permut) { - DdHashTable *table; - DdNode *res; + DdHashTable *table; + DdNode *res; do { - manager->reordered = 0; - table = cuddHashTableInit(manager,1,2); - if (table == NULL) return(NULL); - /* Recursively solve the problem. */ - res = cuddAddPermuteRecur(manager,table,node,permut); - if (res != NULL) cuddRef(res); - /* Dispose of local cache. */ - cuddHashTableQuit(table); + manager->reordered = 0; + table = cuddHashTableInit(manager,1,2); + if (table == NULL) return(NULL); + /* Recursively solve the problem. */ + res = cuddAddPermuteRecur(manager,table,node,permut); + if (res != NULL) cuddRef(res); + /* Dispose of local cache. */ + cuddHashTableQuit(table); } while (manager->reordered == 1); if (res != NULL) cuddDeref(res); @@ -260,20 +288,20 @@ Cudd_addSwapVariables( int n) { DdNode *swapped; - int i, j, k; - int *permut; + int i, j, k; + int *permut; permut = ABC_ALLOC(int,dd->size); if (permut == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < dd->size; i++) permut[i] = i; for (i = 0; i < n; i++) { - j = x[i]->index; - k = y[i]->index; - permut[j] = k; - permut[k] = j; + j = x[i]->index; + k = y[i]->index; + permut[j] = k; + permut[k] = j; } swapped = Cudd_addPermute(dd,f,permut); @@ -306,17 +334,17 @@ Cudd_bddPermute( DdNode * node, int * permut) { - DdHashTable *table; - DdNode *res; + DdHashTable *table; + DdNode *res; do { - manager->reordered = 0; - table = cuddHashTableInit(manager,1,2); - if (table == NULL) return(NULL); - res = cuddBddPermuteRecur(manager,table,node,permut); - if (res != NULL) cuddRef(res); - /* Dispose of local cache. */ - cuddHashTableQuit(table); + manager->reordered = 0; + table = cuddHashTableInit(manager,1,2); + if (table == NULL) return(NULL); + res = cuddBddPermuteRecur(manager,table,node,permut); + if (res != NULL) cuddRef(res); + /* Dispose of local cache. */ + cuddHashTableQuit(table); } while (manager->reordered == 1); @@ -350,8 +378,8 @@ Cudd_bddVarMap( if (manager->map == NULL) return(NULL); do { - manager->reordered = 0; - res = cuddBddVarMapRecur(manager, f); + manager->reordered = 0; + res = cuddBddVarMapRecur(manager, f); } while (manager->reordered == 1); return(res); @@ -394,23 +422,23 @@ Cudd_SetVarMap ( int i; if (manager->map != NULL) { - cuddCacheFlush(manager); + cuddCacheFlush(manager); } else { - manager->map = ABC_ALLOC(int,manager->maxSize); - if (manager->map == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return(0); - } - manager->memused += sizeof(int) * manager->maxSize; + manager->map = ABC_ALLOC(int,manager->maxSize); + if (manager->map == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(0); + } + manager->memused += sizeof(int) * manager->maxSize; } /* Initialize the map to the identity. */ for (i = 0; i < manager->size; i++) { - manager->map[i] = i; + manager->map[i] = i; } /* Create the map. */ for (i = 0; i < n; i++) { - manager->map[x[i]->index] = y[i]->index; - manager->map[y[i]->index] = x[i]->index; + manager->map[x[i]->index] = y[i]->index; + manager->map[y[i]->index] = x[i]->index; } return(1); @@ -441,20 +469,20 @@ Cudd_bddSwapVariables( int n) { DdNode *swapped; - int i, j, k; - int *permut; + int i, j, k; + int *permut; permut = ABC_ALLOC(int,dd->size); if (permut == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < dd->size; i++) permut[i] = i; for (i = 0; i < n; i++) { - j = x[i]->index; - k = y[i]->index; - permut[j] = k; - permut[k] = j; + j = x[i]->index; + k = y[i]->index; + permut[j] = k; + permut[k] = j; } swapped = Cudd_bddPermute(dd,f,permut); @@ -488,20 +516,20 @@ Cudd_bddAdjPermuteX( int n) { DdNode *swapped; - int i, j, k; - int *permut; + int i, j, k; + int *permut; permut = ABC_ALLOC(int,dd->size); if (permut == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < dd->size; i++) permut[i] = i; for (i = 0; i < n-2; i += 3) { - j = x[i]->index; - k = x[i+1]->index; - permut[j] = k; - permut[k] = j; + j = x[i]->index; + k = x[i+1]->index; + permut[j] = k; + permut[k] = j; } swapped = Cudd_bddPermute(dd,B,permut); @@ -537,31 +565,31 @@ Cudd_addVectorCompose( DdNode * f, DdNode ** vector) { - DdHashTable *table; - DdNode *res; - int deepest; + DdHashTable *table; + DdNode *res; + int deepest; int i; do { - dd->reordered = 0; - /* Initialize local cache. */ - table = cuddHashTableInit(dd,1,2); - if (table == NULL) return(NULL); - - /* Find deepest real substitution. */ - for (deepest = dd->size - 1; deepest >= 0; deepest--) { - i = dd->invperm[deepest]; - if (!ddIsIthAddVar(dd,vector[i],i)) { - break; + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (!ddIsIthAddVar(dd,vector[i],i)) { + break; + } } - } - /* Recursively solve the problem. */ - res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest); - if (res != NULL) cuddRef(res); + /* Recursively solve the problem. */ + res = cuddAddVectorComposeRecur(dd,table,f,vector,deepest); + if (res != NULL) cuddRef(res); - /* Dispose of local cache. */ - cuddHashTableQuit(table); + /* Dispose of local cache. */ + cuddHashTableQuit(table); } while (dd->reordered == 1); if (res != NULL) cuddDeref(res); @@ -596,32 +624,32 @@ Cudd_addGeneralVectorCompose( DdNode ** vectorOn, DdNode ** vectorOff) { - DdHashTable *table; - DdNode *res; - int deepest; + DdHashTable *table; + DdNode *res; + int deepest; int i; do { - dd->reordered = 0; - /* Initialize local cache. */ - table = cuddHashTableInit(dd,1,2); - if (table == NULL) return(NULL); - - /* Find deepest real substitution. */ - for (deepest = dd->size - 1; deepest >= 0; deepest--) { - i = dd->invperm[deepest]; - if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) { - break; + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (!ddIsIthAddVarPair(dd,vectorOn[i],vectorOff[i],i)) { + break; + } } - } - /* Recursively solve the problem. */ - res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn, - vectorOff,deepest); - if (res != NULL) cuddRef(res); + /* Recursively solve the problem. */ + res = cuddAddGeneralVectorComposeRecur(dd,table,f,vectorOn, + vectorOff,deepest); + if (res != NULL) cuddRef(res); - /* Dispose of local cache. */ - cuddHashTableQuit(table); + /* Dispose of local cache. */ + cuddHashTableQuit(table); } while (dd->reordered == 1); if (res != NULL) cuddDeref(res); @@ -656,9 +684,9 @@ Cudd_addNonSimCompose( DdNode * f, DdNode ** vector) { - DdNode *cube, *key, *var, *tmp, *piece; - DdNode *res; - int i, lastsub; + DdNode *cube, *key, *var, *tmp, *piece; + DdNode *res; + int i, lastsub; /* The cache entry for this function is composed of three parts: ** f itself, the replacement relation, and the cube of the @@ -675,61 +703,61 @@ Cudd_addNonSimCompose( cube = DD_ONE(dd); cuddRef(cube); for (i = (int) dd->size - 1; i >= 0; i--) { - if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) { - continue; - } - var = Cudd_addIthVar(dd,i); - if (var == NULL) { - Cudd_RecursiveDeref(dd,key); - Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(var); - /* Update cube. */ - tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,key); + if (ddIsIthAddVar(dd,vector[i],(unsigned int)i)) { + continue; + } + var = Cudd_addIthVar(dd,i); + if (var == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(var); + /* Update cube. */ + tmp = Cudd_addApply(dd,Cudd_addTimes,var,cube); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,cube); + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(tmp); Cudd_RecursiveDeref(dd,cube); + cube = tmp; + /* Update replacement relation. */ + piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]); + if (piece == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(piece); Cudd_RecursiveDeref(dd,var); - return(NULL); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,cube); - cube = tmp; - /* Update replacement relation. */ - piece = Cudd_addApply(dd,Cudd_addXnor,var,vector[i]); - if (piece == NULL) { - Cudd_RecursiveDeref(dd,key); - Cudd_RecursiveDeref(dd,var); - return(NULL); - } - cuddRef(piece); - Cudd_RecursiveDeref(dd,var); - tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece); - if (tmp == NULL) { + tmp = Cudd_addApply(dd,Cudd_addTimes,key,piece); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,key); + Cudd_RecursiveDeref(dd,piece); + return(NULL); + } + cuddRef(tmp); Cudd_RecursiveDeref(dd,key); Cudd_RecursiveDeref(dd,piece); - return(NULL); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,key); - Cudd_RecursiveDeref(dd,piece); - key = tmp; + key = tmp; } /* Now try composition, until no reordering occurs. */ do { - /* Find real substitution with largest index. */ - for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) { - if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) { - break; + /* Find real substitution with largest index. */ + for (lastsub = dd->size - 1; lastsub >= 0; lastsub--) { + if (!ddIsIthAddVar(dd,vector[lastsub],(unsigned int)lastsub)) { + break; + } } - } - /* Recursively solve the problem. */ - dd->reordered = 0; - res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1); - if (res != NULL) cuddRef(res); + /* Recursively solve the problem. */ + dd->reordered = 0; + res = cuddAddNonSimComposeRecur(dd,f,vector,key,cube,lastsub+1); + if (res != NULL) cuddRef(res); } while (dd->reordered == 1); @@ -765,31 +793,31 @@ Cudd_bddVectorCompose( DdNode * f, DdNode ** vector) { - DdHashTable *table; - DdNode *res; - int deepest; + DdHashTable *table; + DdNode *res; + int deepest; int i; do { - dd->reordered = 0; - /* Initialize local cache. */ - table = cuddHashTableInit(dd,1,2); - if (table == NULL) return(NULL); - - /* Find deepest real substitution. */ - for (deepest = dd->size - 1; deepest >= 0; deepest--) { - i = dd->invperm[deepest]; - if (vector[i] != dd->vars[i]) { - break; + dd->reordered = 0; + /* Initialize local cache. */ + table = cuddHashTableInit(dd,1,2); + if (table == NULL) return(NULL); + + /* Find deepest real substitution. */ + for (deepest = dd->size - 1; deepest >= 0; deepest--) { + i = dd->invperm[deepest]; + if (vector[i] != dd->vars[i]) { + break; + } } - } - /* Recursively solve the problem. */ - res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest); - if (res != NULL) cuddRef(res); + /* Recursively solve the problem. */ + res = cuddBddVectorComposeRecur(dd,table,f,vector, deepest); + if (res != NULL) cuddRef(res); - /* Dispose of local cache. */ - cuddHashTableQuit(table); + /* Dispose of local cache. */ + cuddHashTableQuit(table); } while (dd->reordered == 1); if (res != NULL) cuddDeref(res); @@ -825,9 +853,9 @@ cuddBddComposeRecur( DdNode * g, DdNode * proj) { - DdNode *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e; + DdNode *F, *G, *f1, *f0, *g1, *g0, *r, *t, *e; unsigned int v, topf, topg, topindex; - int comple; + int comple; statLine(dd); v = dd->perm[proj->index]; @@ -845,60 +873,60 @@ cuddBddComposeRecur( /* Check cache. */ r = cuddCacheLookup(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj); if (r != NULL) { - return(Cudd_NotCond(r,comple)); + return(Cudd_NotCond(r,comple)); } if (topf == v) { - /* Compose. */ - f1 = cuddT(F); - f0 = cuddE(F); - r = cuddBddIteRecur(dd, g, f1, f0); - if (r == NULL) return(NULL); - } else { - /* Compute cofactors of f and g. Remember the index of the top - ** variable. - */ - G = Cudd_Regular(g); - topg = cuddI(dd,G->index); - if (topf > topg) { - topindex = G->index; - f1 = f0 = F; - } else { - topindex = F->index; + /* Compose. */ f1 = cuddT(F); f0 = cuddE(F); - } - if (topg > topf) { - g1 = g0 = g; + r = cuddBddIteRecur(dd, g, f1, f0); + if (r == NULL) return(NULL); } else { - g1 = cuddT(G); - g0 = cuddE(G); - if (g != G) { - g1 = Cudd_Not(g1); - g0 = Cudd_Not(g0); + /* Compute cofactors of f and g. Remember the index of the top + ** variable. + */ + G = Cudd_Regular(g); + topg = cuddI(dd,G->index); + if (topf > topg) { + topindex = G->index; + f1 = f0 = F; + } else { + topindex = F->index; + f1 = cuddT(F); + f0 = cuddE(F); } - } - /* Recursive step. */ - t = cuddBddComposeRecur(dd, f1, g1, proj); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddBddComposeRecur(dd, f0, g0, proj); - if (e == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - cuddRef(e); + if (topg > topf) { + g1 = g0 = g; + } else { + g1 = cuddT(G); + g0 = cuddE(G); + if (g != G) { + g1 = Cudd_Not(g1); + g0 = Cudd_Not(g0); + } + } + /* Recursive step. */ + t = cuddBddComposeRecur(dd, f1, g1, proj); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddBddComposeRecur(dd, f0, g0, proj); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + cuddRef(e); - r = cuddBddIteRecur(dd, dd->vars[topindex], t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, t); + r = cuddBddIteRecur(dd, dd->vars[topindex], t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */ Cudd_IterDerefBdd(dd, e); - return(NULL); - } - cuddRef(r); - Cudd_IterDerefBdd(dd, t); /* t & e not necessarily part of r */ - Cudd_IterDerefBdd(dd, e); - cuddDeref(r); + cuddDeref(r); } cuddCacheInsert(dd,DD_BDD_COMPOSE_RECUR_TAG,F,g,proj,r); @@ -940,57 +968,57 @@ cuddAddComposeRecur( /* Check cache. */ r = cuddCacheLookup(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj); if (r != NULL) { - return(r); + return(r); } if (topf == v) { - /* Compose. */ - f1 = cuddT(f); - f0 = cuddE(f); - r = cuddAddIteRecur(dd, g, f1, f0); - if (r == NULL) return(NULL); - } else { - /* Compute cofactors of f and g. Remember the index of the top - ** variable. - */ - topg = cuddI(dd,g->index); - if (topf > topg) { - topindex = g->index; - f1 = f0 = f; - } else { - topindex = f->index; + /* Compose. */ f1 = cuddT(f); f0 = cuddE(f); - } - if (topg > topf) { - g1 = g0 = g; - } else { - g1 = cuddT(g); - g0 = cuddE(g); - } - /* Recursive step. */ - t = cuddAddComposeRecur(dd, f1, g1, proj); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddAddComposeRecur(dd, f0, g0, proj); - if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } - cuddRef(e); - - if (t == e) { - r = t; + r = cuddAddIteRecur(dd, g, f1, f0); + if (r == NULL) return(NULL); } else { - r = cuddUniqueInter(dd, (int) topindex, t, e); - if (r == NULL) { - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - return(NULL); + /* Compute cofactors of f and g. Remember the index of the top + ** variable. + */ + topg = cuddI(dd,g->index); + if (topf > topg) { + topindex = g->index; + f1 = f0 = f; + } else { + topindex = f->index; + f1 = cuddT(f); + f0 = cuddE(f); } - } - cuddDeref(t); - cuddDeref(e); + if (topg > topf) { + g1 = g0 = g; + } else { + g1 = cuddT(g); + g0 = cuddE(g); + } + /* Recursive step. */ + t = cuddAddComposeRecur(dd, f1, g1, proj); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddAddComposeRecur(dd, f0, g0, proj); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + r = cuddUniqueInter(dd, (int) topindex, t, e); + if (r == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert(dd,DD_ADD_COMPOSE_RECUR_TAG,f,g,proj,r); @@ -1032,22 +1060,22 @@ cuddAddPermuteRecur( DdNode * node /* ADD to be reordered */, int * permut /* permutation array */) { - DdNode *T,*E; - DdNode *res,*var; - int index; + DdNode *T,*E; + DdNode *res,*var; + int index; statLine(manager); /* Check for terminal case of constant node. */ if (cuddIsConstant(node)) { - return(node); + return(node); } /* If problem already solved, look up answer and return. */ if (node->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { #ifdef DD_DEBUG - addPermuteRecurHits++; + addPermuteRecurHits++; #endif - return(res); + return(res); } /* Split and recur on children of this node. */ @@ -1056,8 +1084,8 @@ cuddAddPermuteRecur( cuddRef(T); E = cuddAddPermuteRecur(manager,table,cuddE(node),permut); if (E == NULL) { - Cudd_RecursiveDeref(manager, T); - return(NULL); + Cudd_RecursiveDeref(manager, T); + return(NULL); } cuddRef(E); @@ -1071,10 +1099,10 @@ cuddAddPermuteRecur( cuddRef(var); res = cuddAddIteRecur(manager,var,T,E); if (res == NULL) { - Cudd_RecursiveDeref(manager,var); - Cudd_RecursiveDeref(manager, T); - Cudd_RecursiveDeref(manager, E); - return(NULL); + Cudd_RecursiveDeref(manager,var); + Cudd_RecursiveDeref(manager, T); + Cudd_RecursiveDeref(manager, E); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(manager,var); @@ -1085,12 +1113,12 @@ cuddAddPermuteRecur( ** it will not be visited again. */ if (node->ref != 1) { - ptrint fanout = (ptrint) node->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,node,res,fanout)) { - Cudd_RecursiveDeref(manager, res); - return(NULL); - } + ptrint fanout = (ptrint) node->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,node,res,fanout)) { + Cudd_RecursiveDeref(manager, res); + return(NULL); + } } cuddDeref(res); return(res); @@ -1125,24 +1153,24 @@ cuddBddPermuteRecur( DdNode * node /* BDD to be reordered */, int * permut /* permutation array */) { - DdNode *N,*T,*E; - DdNode *res; - int index; + DdNode *N,*T,*E; + DdNode *res; + int index; statLine(manager); N = Cudd_Regular(node); /* Check for terminal case of constant node. */ if (cuddIsConstant(N)) { - return(node); + return(node); } /* If problem already solved, look up answer and return. */ if (N->ref != 1 && (res = cuddHashTableLookup1(table,N)) != NULL) { #ifdef DD_DEBUG - bddPermuteRecurHits++; + bddPermuteRecurHits++; #endif - return(Cudd_NotCond(res,N != node)); + return(Cudd_NotCond(res,N != node)); } /* Split and recur on children of this node. */ @@ -1151,8 +1179,8 @@ cuddBddPermuteRecur( cuddRef(T); E = cuddBddPermuteRecur(manager,table,cuddE(N),permut); if (E == NULL) { - Cudd_IterDerefBdd(manager, T); - return(NULL); + Cudd_IterDerefBdd(manager, T); + return(NULL); } cuddRef(E); @@ -1163,9 +1191,9 @@ cuddBddPermuteRecur( index = permut[N->index]; res = cuddBddIteRecur(manager,manager->vars[index],T,E); if (res == NULL) { - Cudd_IterDerefBdd(manager, T); - Cudd_IterDerefBdd(manager, E); - return(NULL); + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + return(NULL); } cuddRef(res); Cudd_IterDerefBdd(manager, T); @@ -1175,12 +1203,12 @@ cuddBddPermuteRecur( ** it will not be visited again. */ if (N->ref != 1) { - ptrint fanout = (ptrint) N->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,N,res,fanout)) { - Cudd_IterDerefBdd(manager, res); - return(NULL); - } + ptrint fanout = (ptrint) N->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,N,res,fanout)) { + Cudd_IterDerefBdd(manager, res); + return(NULL); + } } cuddDeref(res); return(Cudd_NotCond(res,N != node)); @@ -1205,22 +1233,22 @@ cuddBddVarMapRecur( DdManager *manager /* DD manager */, DdNode *f /* BDD to be remapped */) { - DdNode *F, *T, *E; - DdNode *res; - int index; + DdNode *F, *T, *E; + DdNode *res; + int index; statLine(manager); F = Cudd_Regular(f); /* Check for terminal case of constant node. */ if (cuddIsConstant(F)) { - return(f); + return(f); } /* If problem already solved, look up answer and return. */ if (F->ref != 1 && - (res = cuddCacheLookup1(manager,Cudd_bddVarMap,F)) != NULL) { - return(Cudd_NotCond(res,F != f)); + (res = cuddCacheLookup1(manager,Cudd_bddVarMap,F)) != NULL) { + return(Cudd_NotCond(res,F != f)); } /* Split and recur on children of this node. */ @@ -1229,8 +1257,8 @@ cuddBddVarMapRecur( cuddRef(T); E = cuddBddVarMapRecur(manager,cuddE(F)); if (E == NULL) { - Cudd_IterDerefBdd(manager, T); - return(NULL); + Cudd_IterDerefBdd(manager, T); + return(NULL); } cuddRef(E); @@ -1241,9 +1269,9 @@ cuddBddVarMapRecur( index = manager->map[F->index]; res = cuddBddIteRecur(manager,manager->vars[index],T,E); if (res == NULL) { - Cudd_IterDerefBdd(manager, T); - Cudd_IterDerefBdd(manager, E); - return(NULL); + Cudd_IterDerefBdd(manager, T); + Cudd_IterDerefBdd(manager, E); + return(NULL); } cuddRef(res); Cudd_IterDerefBdd(manager, T); @@ -1253,7 +1281,7 @@ cuddBddVarMapRecur( ** it will not be visited again. */ if (F->ref != 1) { - cuddCacheInsert1(manager,Cudd_bddVarMap,F,res); + cuddCacheInsert1(manager,Cudd_bddVarMap,F,res); } cuddDeref(res); return(Cudd_NotCond(res,F != f)); @@ -1280,20 +1308,20 @@ cuddAddVectorComposeRecur( DdNode ** vector /* functions to substitute */, int deepest /* depth of deepest substitution */) { - DdNode *T,*E; - DdNode *res; + DdNode *T,*E; + DdNode *res; statLine(dd); /* If we are past the deepest substitution, return f. */ if (cuddI(dd,f->index) > deepest) { - return(f); + return(f); } if ((res = cuddHashTableLookup1(table,f)) != NULL) { #ifdef DD_DEBUG - addVectorComposeHits++; + addVectorComposeHits++; #endif - return(res); + return(res); } /* Split and recur on children of this node. */ @@ -1302,8 +1330,8 @@ cuddAddVectorComposeRecur( cuddRef(T); E = cuddAddVectorComposeRecur(dd,table,cuddE(f),vector,deepest); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); + Cudd_RecursiveDeref(dd, T); + return(NULL); } cuddRef(E); @@ -1312,9 +1340,9 @@ cuddAddVectorComposeRecur( */ res = cuddAddIteRecur(dd,vector[f->index],T,E); if (res == NULL) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, T); @@ -1324,12 +1352,12 @@ cuddAddVectorComposeRecur( ** it will not be visited again */ if (f->ref != 1) { - ptrint fanout = (ptrint) f->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,f,res,fanout)) { - Cudd_RecursiveDeref(dd, res); - return(NULL); - } + ptrint fanout = (ptrint) f->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } } cuddDeref(res); return(res); @@ -1357,31 +1385,31 @@ cuddAddGeneralVectorComposeRecur( DdNode ** vectorOff /* functions to substitute for x_i' */, int deepest /* depth of deepest substitution */) { - DdNode *T,*E,*t,*e; - DdNode *res; + DdNode *T,*E,*t,*e; + DdNode *res; /* If we are past the deepest substitution, return f. */ if (cuddI(dd,f->index) > deepest) { - return(f); + return(f); } if ((res = cuddHashTableLookup1(table,f)) != NULL) { #ifdef DD_DEBUG - addGeneralVectorComposeHits++; + addGeneralVectorComposeHits++; #endif - return(res); + return(res); } /* Split and recur on children of this node. */ T = cuddAddGeneralVectorComposeRecur(dd,table,cuddT(f), - vectorOn,vectorOff,deepest); + vectorOn,vectorOff,deepest); if (T == NULL) return(NULL); cuddRef(T); E = cuddAddGeneralVectorComposeRecur(dd,table,cuddE(f), - vectorOn,vectorOff,deepest); + vectorOn,vectorOff,deepest); if (E == NULL) { - Cudd_RecursiveDeref(dd, T); - return(NULL); + Cudd_RecursiveDeref(dd, T); + return(NULL); } cuddRef(E); @@ -1421,12 +1449,12 @@ cuddAddGeneralVectorComposeRecur( ** it will not be visited again */ if (f->ref != 1) { - ptrint fanout = (ptrint) f->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,f,res,fanout)) { - Cudd_RecursiveDeref(dd, res); - return(NULL); - } + ptrint fanout = (ptrint) f->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } } cuddDeref(res); return(res); @@ -1466,13 +1494,13 @@ cuddAddNonSimComposeRecur( statLine(dd); /* If we are past the deepest substitution, return f. */ if (cube == DD_ONE(dd) || cuddIsConstant(f)) { - return(f); + return(f); } /* If problem already solved, look up answer and return. */ r = cuddCacheLookup(dd,DD_ADD_NON_SIM_COMPOSE_TAG,f,key,cube); if (r != NULL) { - return(r); + return(r); } /* Find top variable. we just need to look at f, key, and cube, @@ -1487,69 +1515,69 @@ cuddAddNonSimComposeRecur( /* Compute the cofactors. */ if (topf == top) { - f1 = cuddT(f); - f0 = cuddE(f); + f1 = cuddT(f); + f0 = cuddE(f); } else { - f1 = f0 = f; + f1 = f0 = f; } if (topc == top) { - cube1 = cuddT(cube); - /* We want to eliminate vector[index] from key. Otherwise - ** cache performance is severely affected. Hence we - ** existentially quantify the variable with index "index" from key. - */ - var = Cudd_addIthVar(dd, (int) index); - if (var == NULL) { - return(NULL); - } - cuddRef(var); - key1 = cuddAddExistAbstractRecur(dd, key, var); - if (key1 == NULL) { + cube1 = cuddT(cube); + /* We want to eliminate vector[index] from key. Otherwise + ** cache performance is severely affected. Hence we + ** existentially quantify the variable with index "index" from key. + */ + var = Cudd_addIthVar(dd, (int) index); + if (var == NULL) { + return(NULL); + } + cuddRef(var); + key1 = cuddAddExistAbstractRecur(dd, key, var); + if (key1 == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(key1); Cudd_RecursiveDeref(dd,var); - return(NULL); - } - cuddRef(key1); - Cudd_RecursiveDeref(dd,var); - key0 = key1; + key0 = key1; } else { - cube1 = cube; - if (topk == top) { - key1 = cuddT(key); - key0 = cuddE(key); - } else { - key1 = key0 = key; - } - cuddRef(key1); + cube1 = cube; + if (topk == top) { + key1 = cuddT(key); + key0 = cuddE(key); + } else { + key1 = key0 = key; + } + cuddRef(key1); } /* Allocate two new vectors for the cofactors of vector. */ vect1 = ABC_ALLOC(DdNode *,lastsub); if (vect1 == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd,key1); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd,key1); + return(NULL); } vect0 = ABC_ALLOC(DdNode *,lastsub); if (vect0 == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd,key1); - ABC_FREE(vect1); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd,key1); + ABC_FREE(vect1); + return(NULL); } /* Cofactor the gi. Eliminate vect1[index] and vect0[index], because ** we do not need them. */ for (i = 0; i < lastsub; i++) { - DdNode *gi = vector[i]; - if (gi == NULL) { - vect1[i] = vect0[i] = NULL; - } else if (gi->index == index) { - vect1[i] = cuddT(gi); - vect0[i] = cuddE(gi); - } else { - vect1[i] = vect0[i] = gi; - } + DdNode *gi = vector[i]; + if (gi == NULL) { + vect1[i] = vect0[i] = NULL; + } else if (gi->index == index) { + vect1[i] = cuddT(gi); + vect0[i] = cuddE(gi); + } else { + vect1[i] = vect0[i] = gi; + } } vect1[index] = vect0[index] = NULL; @@ -1557,17 +1585,17 @@ cuddAddNonSimComposeRecur( T = cuddAddNonSimComposeRecur(dd,f1,vect1,key1,cube1,lastsub); ABC_FREE(vect1); if (T == NULL) { - Cudd_RecursiveDeref(dd,key1); - ABC_FREE(vect0); - return(NULL); + Cudd_RecursiveDeref(dd,key1); + ABC_FREE(vect0); + return(NULL); } cuddRef(T); E = cuddAddNonSimComposeRecur(dd,f0,vect0,key0,cube1,lastsub); ABC_FREE(vect0); if (E == NULL) { - Cudd_RecursiveDeref(dd,key1); - Cudd_RecursiveDeref(dd,T); - return(NULL); + Cudd_RecursiveDeref(dd,key1); + Cudd_RecursiveDeref(dd,T); + return(NULL); } cuddRef(E); Cudd_RecursiveDeref(dd,key1); @@ -1577,9 +1605,9 @@ cuddAddNonSimComposeRecur( */ r = cuddAddIteRecur(dd,vector[index],T,E); if (r == NULL) { - Cudd_RecursiveDeref(dd,T); - Cudd_RecursiveDeref(dd,E); - return(NULL); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); } cuddRef(r); Cudd_RecursiveDeref(dd,T); @@ -1613,23 +1641,23 @@ cuddBddVectorComposeRecur( DdNode ** vector /* functions to be composed */, int deepest /* depth of the deepest substitution */) { - DdNode *F,*T,*E; - DdNode *res; + DdNode *F,*T,*E; + DdNode *res; statLine(dd); F = Cudd_Regular(f); /* If we are past the deepest substitution, return f. */ if (cuddI(dd,F->index) > deepest) { - return(f); + return(f); } /* If problem already solved, look up answer and return. */ if ((res = cuddHashTableLookup1(table,F)) != NULL) { #ifdef DD_DEBUG - bddVectorComposeHits++; + bddVectorComposeHits++; #endif - return(Cudd_NotCond(res,F != f)); + return(Cudd_NotCond(res,F != f)); } /* Split and recur on children of this node. */ @@ -1638,8 +1666,8 @@ cuddBddVectorComposeRecur( cuddRef(T); E = cuddBddVectorComposeRecur(dd,table,cuddE(F),vector, deepest); if (E == NULL) { - Cudd_IterDerefBdd(dd, T); - return(NULL); + Cudd_IterDerefBdd(dd, T); + return(NULL); } cuddRef(E); @@ -1648,24 +1676,24 @@ cuddBddVectorComposeRecur( */ res = cuddBddIteRecur(dd,vector[F->index],T,E); if (res == NULL) { - Cudd_IterDerefBdd(dd, T); - Cudd_IterDerefBdd(dd, E); - return(NULL); + Cudd_IterDerefBdd(dd, T); + Cudd_IterDerefBdd(dd, E); + return(NULL); } cuddRef(res); Cudd_IterDerefBdd(dd, T); - Cudd_IterDerefBdd(dd, E); + Cudd_IterDerefBdd(dd, E); /* Do not keep the result if the reference count is only 1, since ** it will not be visited again. */ if (F->ref != 1) { - ptrint fanout = (ptrint) F->ref; - cuddSatDec(fanout); - if (!cuddHashTableInsert1(table,F,res,fanout)) { - Cudd_IterDerefBdd(dd, res); - return(NULL); - } + ptrint fanout = (ptrint) F->ref; + cuddSatDec(fanout); + if (!cuddHashTableInsert1(table,F,res,fanout)) { + Cudd_IterDerefBdd(dd, res); + return(NULL); + } } cuddDeref(res); return(Cudd_NotCond(res,F != f)); @@ -1719,9 +1747,11 @@ ddIsIthAddVarPair( unsigned int i) { return(f->index == i && g->index == i && - cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd) && - cuddT(g) == DD_ZERO(dd) && cuddE(g) == DD_ONE(dd)); + cuddT(f) == DD_ONE(dd) && cuddE(f) == DD_ZERO(dd) && + cuddT(g) == DD_ZERO(dd) && cuddE(g) == DD_ONE(dd)); } /* end of ddIsIthAddVarPair */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddDecomp.c b/src/bdd/cudd/cuddDecomp.c index 95a00536..34eaef0c 100644 --- a/src/bdd/cudd/cuddDecomp.c +++ b/src/bdd/cudd/cuddDecomp.c @@ -7,30 +7,57 @@ Synopsis [Functions for BDD decomposition.] Description [External procedures included in this file: - <ul> - <li> Cudd_bddApproxConjDecomp() - <li> Cudd_bddApproxDisjDecomp() - <li> Cudd_bddIterConjDecomp() - <li> Cudd_bddIterDisjDecomp() - <li> Cudd_bddGenConjDecomp() - <li> Cudd_bddGenDisjDecomp() - <li> Cudd_bddVarConjDecomp() - <li> Cudd_bddVarDisjDecomp() - </ul> - Static procedures included in this module: - <ul> - <li> cuddConjunctsAux() - <li> CreateBotDist() - <li> BuildConjuncts() - <li> ConjunctsFree() - </ul>] + <ul> + <li> Cudd_bddApproxConjDecomp() + <li> Cudd_bddApproxDisjDecomp() + <li> Cudd_bddIterConjDecomp() + <li> Cudd_bddIterDisjDecomp() + <li> Cudd_bddGenConjDecomp() + <li> Cudd_bddGenDisjDecomp() + <li> Cudd_bddVarConjDecomp() + <li> Cudd_bddVarDisjDecomp() + </ul> + Static procedures included in this module: + <ul> + <li> cuddConjunctsAux() + <li> CreateBotDist() + <li> BuildConjuncts() + <li> ConjunctsFree() + </ul>] Author [Kavita Ravi, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -40,6 +67,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -78,10 +106,10 @@ typedef struct NodeStat { /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddDecomp.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddDecomp.c,v 1.44 2004/08/13 18:04:47 fabio Exp $"; #endif -static DdNode *one, *zero; +static DdNode *one, *zero; long lastTimeG; /*---------------------------------------------------------------------------*/ @@ -101,16 +129,16 @@ long lastTimeG; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static NodeStat * CreateBotDist ARGS((DdNode * node, st_table * distanceTable)); -static double CountMinterms ARGS((DdNode * node, double max, st_table * mintermTable, FILE *fp)); -static void ConjunctsFree ARGS((DdManager * dd, Conjuncts * factors)); -static int PairInTables ARGS((DdNode * g, DdNode * h, st_table * ghTable)); -static Conjuncts * CheckTablesCacheAndReturn ARGS((DdNode * node, DdNode * g, DdNode * h, st_table * ghTable, st_table * cacheTable)); -static Conjuncts * PickOnePair ARGS((DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable)); -static Conjuncts * CheckInTables ARGS((DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable, int * outOfMem)); -static Conjuncts * ZeroCase ARGS((DdManager * dd, DdNode * node, Conjuncts * factorsNv, st_table * ghTable, st_table * cacheTable, int switched)); -static Conjuncts * BuildConjuncts ARGS((DdManager * dd, DdNode * node, st_table * distanceTable, st_table * cacheTable, int approxDistance, int maxLocalRef, st_table * ghTable, st_table * mintermTable)); -static int cuddConjunctsAux ARGS((DdManager * dd, DdNode * f, DdNode ** c1, DdNode ** c2)); +static NodeStat * CreateBotDist (DdNode * node, st_table * distanceTable); +static double CountMinterms (DdNode * node, double max, st_table * mintermTable, FILE *fp); +static void ConjunctsFree (DdManager * dd, Conjuncts * factors); +static int PairInTables (DdNode * g, DdNode * h, st_table * ghTable); +static Conjuncts * CheckTablesCacheAndReturn (DdNode * node, DdNode * g, DdNode * h, st_table * ghTable, st_table * cacheTable); +static Conjuncts * PickOnePair (DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable); +static Conjuncts * CheckInTables (DdNode * node, DdNode * g1, DdNode * h1, DdNode * g2, DdNode * h2, st_table * ghTable, st_table * cacheTable, int * outOfMem); +static Conjuncts * ZeroCase (DdManager * dd, DdNode * node, Conjuncts * factorsNv, st_table * ghTable, st_table * cacheTable, int switched); +static Conjuncts * BuildConjuncts (DdManager * dd, DdNode * node, st_table * distanceTable, st_table * cacheTable, int approxDistance, int maxLocalRef, st_table * ghTable, st_table * mintermTable); +static int cuddConjunctsAux (DdManager * dd, DdNode * f, DdNode ** c1, DdNode ** c2); /**AutomaticEnd***************************************************************/ @@ -158,8 +186,8 @@ Cudd_bddApproxConjDecomp( cuddRef(superset1); superset2 = Cudd_bddSqueeze(dd,f,superset1); if (superset2 == NULL) { - Cudd_RecursiveDeref(dd,superset1); - return(0); + Cudd_RecursiveDeref(dd,superset1); + return(0); } cuddRef(superset2); Cudd_RecursiveDeref(dd,superset1); @@ -167,8 +195,8 @@ Cudd_bddApproxConjDecomp( /* Compute the second factor by minimization. */ hlocal = Cudd_bddLICompaction(dd,f,superset2); if (hlocal == NULL) { - Cudd_RecursiveDeref(dd,superset2); - return(0); + Cudd_RecursiveDeref(dd,superset2); + return(0); } cuddRef(hlocal); @@ -176,47 +204,47 @@ Cudd_bddApproxConjDecomp( ** step guarantees that g will be 1. */ glocal = Cudd_bddLICompaction(dd,superset2,hlocal); if (glocal == NULL) { - Cudd_RecursiveDeref(dd,superset2); - Cudd_RecursiveDeref(dd,hlocal); - return(0); + Cudd_RecursiveDeref(dd,superset2); + Cudd_RecursiveDeref(dd,hlocal); + return(0); } cuddRef(glocal); Cudd_RecursiveDeref(dd,superset2); if (glocal != DD_ONE(dd)) { - if (hlocal != DD_ONE(dd)) { - *conjuncts = ABC_ALLOC(DdNode *,2); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,glocal); - Cudd_RecursiveDeref(dd,hlocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + if (hlocal != DD_ONE(dd)) { + *conjuncts = ABC_ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ABC_ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); } - (*conjuncts)[0] = glocal; - (*conjuncts)[1] = hlocal; - return(2); } else { - Cudd_RecursiveDeref(dd,hlocal); + Cudd_RecursiveDeref(dd,glocal); *conjuncts = ABC_ALLOC(DdNode *,1); if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,glocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - (*conjuncts)[0] = glocal; + (*conjuncts)[0] = hlocal; return(1); } - } else { - Cudd_RecursiveDeref(dd,glocal); - *conjuncts = ABC_ALLOC(DdNode *,1); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,hlocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - (*conjuncts)[0] = hlocal; - return(1); - } } /* end of Cudd_bddApproxConjDecomp */ @@ -251,7 +279,7 @@ Cudd_bddApproxDisjDecomp( result = Cudd_bddApproxConjDecomp(dd,Cudd_Not(f),disjuncts); for (i = 0; i < result; i++) { - (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); } return(result); @@ -298,59 +326,59 @@ Cudd_bddIterConjDecomp( sizeOld = Cudd_SharingSize(old,2); do { - /* Find a tentative first factor by overapproximation and - ** minimization. */ - superset1 = Cudd_RemapOverApprox(dd,old[1],nvars,0,1.0); - if (superset1 == NULL) { - Cudd_RecursiveDeref(dd,old[0]); - Cudd_RecursiveDeref(dd,old[1]); - return(0); - } - cuddRef(superset1); - superset2 = Cudd_bddSqueeze(dd,old[1],superset1); - if (superset2 == NULL) { - Cudd_RecursiveDeref(dd,old[0]); - Cudd_RecursiveDeref(dd,old[1]); + /* Find a tentative first factor by overapproximation and + ** minimization. */ + superset1 = Cudd_RemapOverApprox(dd,old[1],nvars,0,1.0); + if (superset1 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(superset1); + superset2 = Cudd_bddSqueeze(dd,old[1],superset1); + if (superset2 == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + Cudd_RecursiveDeref(dd,superset1); + return(0); + } + cuddRef(superset2); Cudd_RecursiveDeref(dd,superset1); - return(0); - } - cuddRef(superset2); - Cudd_RecursiveDeref(dd,superset1); - res[0] = Cudd_bddAnd(dd,old[0],superset2); - if (res[0] == NULL) { + res[0] = Cudd_bddAnd(dd,old[0],superset2); + if (res[0] == NULL) { + Cudd_RecursiveDeref(dd,superset2); + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(res[0]); Cudd_RecursiveDeref(dd,superset2); - Cudd_RecursiveDeref(dd,old[0]); - Cudd_RecursiveDeref(dd,old[1]); - return(0); - } - cuddRef(res[0]); - Cudd_RecursiveDeref(dd,superset2); - if (res[0] == old[0]) { - Cudd_RecursiveDeref(dd,res[0]); - break; /* avoid infinite loop */ - } - - /* Compute the second factor by minimization. */ - res[1] = Cudd_bddLICompaction(dd,old[1],res[0]); - if (res[1] == NULL) { - Cudd_RecursiveDeref(dd,old[0]); - Cudd_RecursiveDeref(dd,old[1]); - return(0); - } - cuddRef(res[1]); + if (res[0] == old[0]) { + Cudd_RecursiveDeref(dd,res[0]); + break; /* avoid infinite loop */ + } - sizeNew = Cudd_SharingSize(res,2); - if (sizeNew <= sizeOld) { - Cudd_RecursiveDeref(dd,old[0]); - old[0] = res[0]; - Cudd_RecursiveDeref(dd,old[1]); - old[1] = res[1]; - sizeOld = sizeNew; - } else { - Cudd_RecursiveDeref(dd,res[0]); - Cudd_RecursiveDeref(dd,res[1]); - break; - } + /* Compute the second factor by minimization. */ + res[1] = Cudd_bddLICompaction(dd,old[1],res[0]); + if (res[1] == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); + } + cuddRef(res[1]); + + sizeNew = Cudd_SharingSize(res,2); + if (sizeNew <= sizeOld) { + Cudd_RecursiveDeref(dd,old[0]); + old[0] = res[0]; + Cudd_RecursiveDeref(dd,old[1]); + old[1] = res[1]; + sizeOld = sizeNew; + } else { + Cudd_RecursiveDeref(dd,res[0]); + Cudd_RecursiveDeref(dd,res[1]); + break; + } } while (1); @@ -358,48 +386,48 @@ Cudd_bddIterConjDecomp( ** be f, this step guarantees that g will be 1. */ superset1 = Cudd_bddLICompaction(dd,old[0],old[1]); if (superset1 == NULL) { - Cudd_RecursiveDeref(dd,old[0]); - Cudd_RecursiveDeref(dd,old[1]); - return(0); + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + return(0); } cuddRef(superset1); Cudd_RecursiveDeref(dd,old[0]); old[0] = superset1; if (old[0] != DD_ONE(dd)) { - if (old[1] != DD_ONE(dd)) { - *conjuncts = ABC_ALLOC(DdNode *,2); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,old[0]); - Cudd_RecursiveDeref(dd,old[1]); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + if (old[1] != DD_ONE(dd)) { + *conjuncts = ABC_ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + Cudd_RecursiveDeref(dd,old[1]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[0]; + (*conjuncts)[1] = old[1]; + return(2); + } else { + Cudd_RecursiveDeref(dd,old[1]); + *conjuncts = ABC_ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,old[0]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = old[0]; + return(1); } - (*conjuncts)[0] = old[0]; - (*conjuncts)[1] = old[1]; - return(2); } else { - Cudd_RecursiveDeref(dd,old[1]); + Cudd_RecursiveDeref(dd,old[0]); *conjuncts = ABC_ALLOC(DdNode *,1); if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,old[0]); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + Cudd_RecursiveDeref(dd,old[1]); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - (*conjuncts)[0] = old[0]; + (*conjuncts)[0] = old[1]; return(1); } - } else { - Cudd_RecursiveDeref(dd,old[0]); - *conjuncts = ABC_ALLOC(DdNode *,1); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,old[1]); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - (*conjuncts)[0] = old[1]; - return(1); - } } /* end of Cudd_bddIterConjDecomp */ @@ -434,7 +462,7 @@ Cudd_bddIterDisjDecomp( result = Cudd_bddIterConjDecomp(dd,Cudd_Not(f),disjuncts); for (i = 0; i < result; i++) { - (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); } return(result); @@ -477,48 +505,48 @@ Cudd_bddGenConjDecomp( zero = Cudd_Not(one); do { - dd->reordered = 0; - result = cuddConjunctsAux(dd, f, &glocal, &hlocal); + dd->reordered = 0; + result = cuddConjunctsAux(dd, f, &glocal, &hlocal); } while (dd->reordered == 1); if (result == 0) { - return(0); + return(0); } if (glocal != one) { - if (hlocal != one) { - *conjuncts = ABC_ALLOC(DdNode *,2); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,glocal); - Cudd_RecursiveDeref(dd,hlocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + if (hlocal != one) { + *conjuncts = ABC_ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ABC_ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); } - (*conjuncts)[0] = glocal; - (*conjuncts)[1] = hlocal; - return(2); } else { - Cudd_RecursiveDeref(dd,hlocal); + Cudd_RecursiveDeref(dd,glocal); *conjuncts = ABC_ALLOC(DdNode *,1); if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,glocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - (*conjuncts)[0] = glocal; + (*conjuncts)[0] = hlocal; return(1); } - } else { - Cudd_RecursiveDeref(dd,glocal); - *conjuncts = ABC_ALLOC(DdNode *,1); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,hlocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - (*conjuncts)[0] = hlocal; - return(1); - } } /* end of Cudd_bddGenConjDecomp */ @@ -553,7 +581,7 @@ Cudd_bddGenDisjDecomp( result = Cudd_bddGenConjDecomp(dd,Cudd_Not(f),disjuncts); for (i = 0; i < result; i++) { - (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); } return(result); @@ -597,30 +625,30 @@ Cudd_bddVarConjDecomp( support = Cudd_Support(dd,f); if (support == NULL) return(0); if (Cudd_IsConstant(support)) { - *conjuncts = ABC_ALLOC(DdNode *,1); - if (*conjuncts == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - (*conjuncts)[0] = f; - cuddRef((*conjuncts)[0]); - return(1); + *conjuncts = ABC_ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = f; + cuddRef((*conjuncts)[0]); + return(1); } cuddRef(support); min = 1000000000; best = -1; scan = support; while (!Cudd_IsConstant(scan)) { - int i = scan->index; - int est1 = Cudd_EstimateCofactor(dd,f,i,1); - int est0 = Cudd_EstimateCofactor(dd,f,i,0); - /* Minimize the size of the larger of the two cofactors. */ - int est = (est1 > est0) ? est1 : est0; - if (est < min) { - min = est; - best = i; - } - scan = cuddT(scan); + int i = scan->index; + int est1 = Cudd_EstimateCofactor(dd,f,i,1); + int est0 = Cudd_EstimateCofactor(dd,f,i,0); + /* Minimize the size of the larger of the two cofactors. */ + int est = (est1 > est0) ? est1 : est0; + if (est < min) { + min = est; + best = i; + } + scan = cuddT(scan); } #ifdef DD_DEBUG assert(best >= 0 && best < dd->size); @@ -630,50 +658,50 @@ Cudd_bddVarConjDecomp( var = Cudd_bddIthVar(dd,best); glocal = Cudd_bddOr(dd,f,var); if (glocal == NULL) { - return(0); + return(0); } cuddRef(glocal); hlocal = Cudd_bddOr(dd,f,Cudd_Not(var)); if (hlocal == NULL) { - Cudd_RecursiveDeref(dd,glocal); - return(0); + Cudd_RecursiveDeref(dd,glocal); + return(0); } cuddRef(hlocal); if (glocal != DD_ONE(dd)) { - if (hlocal != DD_ONE(dd)) { - *conjuncts = ABC_ALLOC(DdNode *,2); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,glocal); - Cudd_RecursiveDeref(dd,hlocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + if (hlocal != DD_ONE(dd)) { + *conjuncts = ABC_ALLOC(DdNode *,2); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + (*conjuncts)[1] = hlocal; + return(2); + } else { + Cudd_RecursiveDeref(dd,hlocal); + *conjuncts = ABC_ALLOC(DdNode *,1); + if (*conjuncts == NULL) { + Cudd_RecursiveDeref(dd,glocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + (*conjuncts)[0] = glocal; + return(1); } - (*conjuncts)[0] = glocal; - (*conjuncts)[1] = hlocal; - return(2); } else { - Cudd_RecursiveDeref(dd,hlocal); + Cudd_RecursiveDeref(dd,glocal); *conjuncts = ABC_ALLOC(DdNode *,1); if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,glocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + Cudd_RecursiveDeref(dd,hlocal); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - (*conjuncts)[0] = glocal; + (*conjuncts)[0] = hlocal; return(1); } - } else { - Cudd_RecursiveDeref(dd,glocal); - *conjuncts = ABC_ALLOC(DdNode *,1); - if (*conjuncts == NULL) { - Cudd_RecursiveDeref(dd,hlocal); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - (*conjuncts)[0] = hlocal; - return(1); - } } /* end of Cudd_bddVarConjDecomp */ @@ -711,7 +739,7 @@ Cudd_bddVarDisjDecomp( result = Cudd_bddVarConjDecomp(dd,Cudd_Not(f),disjuncts); for (i = 0; i < result; i++) { - (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); + (*disjuncts)[i] = Cudd_Not((*disjuncts)[i]); } return(result); @@ -751,15 +779,15 @@ CreateBotDist( #if 0 if (Cudd_IsConstant(node)) { - return(0); + return(0); } #endif /* Return the entry in the table if found. */ N = Cudd_Regular(node); - if (st_lookup(distanceTable, (char *)N, (char **)&nodeStat)) { - nodeStat->localRef++; - return(nodeStat); + if (st_lookup(distanceTable, (const char *)N, (char **)&nodeStat)) { + nodeStat->localRef++; + return(nodeStat); } Nv = cuddT(N); @@ -782,14 +810,14 @@ CreateBotDist( nodeStat = ABC_ALLOC(NodeStat, 1); if (nodeStat == NULL) { - return(0); + return(0); } nodeStat->distance = distance; nodeStat->localRef = 1; if (st_insert(distanceTable, (char *)N, (char *)nodeStat) == - ST_OUT_OF_MEM) { - return(0); + ST_OUT_OF_MEM) { + return(0); } return(nodeStat); @@ -823,17 +851,17 @@ CountMinterms( N = Cudd_Regular(node); if (cuddIsConstant(N)) { - if (node == zero) { - return(0); - } else { - return(max); - } + if (node == zero) { + return(0); + } else { + return(max); + } } /* Return the entry in the table if found. */ - if (st_lookup(mintermTable, (char *)node, (char **)&dummy)) { - min = *dummy; - return(min); + if (st_lookup(mintermTable, (const char *)node, (char **)&dummy)) { + min = *dummy; + return(min); } Nv = cuddT(N); @@ -854,7 +882,7 @@ CountMinterms( if (dummy == NULL) return(-1.0); *dummy = min; if (st_insert(mintermTable, (char *)node, (char *)dummy) == ST_OUT_OF_MEM) { - (void) fprintf(fp, "st table insert failed\n"); + (void) fprintf(fp, "st table insert failed\n"); } return(min); @@ -928,21 +956,21 @@ PairInTables( if (!gPresent && !hPresent) return(NONE); if (!hPresent) { - if (valueG & 1) return(G_ST); - if (valueG & 2) return(G_CR); + if (valueG & 1) return(G_ST); + if (valueG & 2) return(G_CR); } if (!gPresent) { - if (valueH & 1) return(H_CR); - if (valueH & 2) return(H_ST); + if (valueH & 1) return(H_CR); + if (valueH & 2) return(H_ST); } /* both in tables */ if ((valueG & 1) && (valueH & 2)) return(PAIR_ST); if ((valueG & 2) && (valueH & 1)) return(PAIR_CR); if (valueG & 1) { - return(BOTH_G); + return(BOTH_G); } else { - return(BOTH_H); + return(BOTH_H); } } /* end of PairInTables */ @@ -984,74 +1012,74 @@ CheckTablesCacheAndReturn( factors = ABC_ALLOC(Conjuncts, 1); if (factors == NULL) return(NULL); if ((pairValue == BOTH_H) || (pairValue == H_ST)) { - if (g != one) { - value = 0; - if (st_lookup_int(ghTable, (char *)Cudd_Regular(g), &value)) { - value |= 1; - } else { - value = 1; - } - if (st_insert(ghTable, (char *)Cudd_Regular(g), - (char *)(long)value) == ST_OUT_OF_MEM) { - return(NULL); + if (g != one) { + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(g), &value)) { + value |= 1; + } else { + value = 1; + } + if (st_insert(ghTable, (char *)Cudd_Regular(g), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } } - } - factors->g = g; - factors->h = h; + factors->g = g; + factors->h = h; } else if ((pairValue == BOTH_G) || (pairValue == G_ST)) { - if (h != one) { - value = 0; - if (st_lookup_int(ghTable, (char *)Cudd_Regular(h), &value)) { - value |= 2; - } else { - value = 2; - } - if (st_insert(ghTable, (char *)Cudd_Regular(h), - (char *)(long)value) == ST_OUT_OF_MEM) { - return(NULL); + if (h != one) { + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(h), &value)) { + value |= 2; + } else { + value = 2; + } + if (st_insert(ghTable, (char *)Cudd_Regular(h), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } } - } - factors->g = g; - factors->h = h; + factors->g = g; + factors->h = h; } else if (pairValue == H_CR) { - if (g != one) { - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(g), - (char *)(long)value) == ST_OUT_OF_MEM) { - return(NULL); + if (g != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } } - } - factors->g = h; - factors->h = g; + factors->g = h; + factors->h = g; } else if (pairValue == G_CR) { - if (h != one) { - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(h), - (char *)(long)value) == ST_OUT_OF_MEM) { - return(NULL); + if (h != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h), + (char *)(long)value) == ST_OUT_OF_MEM) { + return(NULL); + } } - } - factors->g = h; - factors->h = g; + factors->g = h; + factors->h = g; } else if (pairValue == PAIR_CR) { /* pair exists in table */ - factors->g = h; - factors->h = g; + factors->g = h; + factors->h = g; } else if (pairValue == PAIR_ST) { - factors->g = g; - factors->h = h; + factors->g = g; + factors->h = h; } - + /* cache the result for this node */ if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { - ABC_FREE(factors); - return(NULL); + ABC_FREE(factors); + return(NULL); } return(factors); } /* end of CheckTablesCacheAndReturn */ - + /**Function******************************************************************** Synopsis [Check the tables for the existence of pair and return one @@ -1086,29 +1114,29 @@ PickOnePair( /* count the number of pointers to pair 2 */ if (h2 == one) { - twoRef = (Cudd_Regular(g2))->ref; + twoRef = (Cudd_Regular(g2))->ref; } else if (g2 == one) { - twoRef = (Cudd_Regular(h2))->ref; + twoRef = (Cudd_Regular(h2))->ref; } else { - twoRef = ((Cudd_Regular(g2))->ref + (Cudd_Regular(h2))->ref)/2; + twoRef = ((Cudd_Regular(g2))->ref + (Cudd_Regular(h2))->ref)/2; } /* count the number of pointers to pair 1 */ if (h1 == one) { - oneRef = (Cudd_Regular(g1))->ref; + oneRef = (Cudd_Regular(g1))->ref; } else if (g1 == one) { - oneRef = (Cudd_Regular(h1))->ref; + oneRef = (Cudd_Regular(h1))->ref; } else { - oneRef = ((Cudd_Regular(g1))->ref + (Cudd_Regular(h1))->ref)/2; + oneRef = ((Cudd_Regular(g1))->ref + (Cudd_Regular(h1))->ref)/2; } /* pick the pair with higher reference count */ if (oneRef >= twoRef) { - factors->g = g1; - factors->h = h1; + factors->g = g1; + factors->h = h1; } else { - factors->g = g2; - factors->h = h2; + factors->g = g2; + factors->h = h2; } /* @@ -1116,54 +1144,54 @@ PickOnePair( * recombination. */ if (factors->g != one) { - /* insert g in htable */ - value = 0; - if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->g), &value)) { - if (value == 2) { - value |= 1; - if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), - (char *)(long)value) == ST_OUT_OF_MEM) { - ABC_FREE(factors); - return(NULL); - } - } - } else { - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), - (char *)(long)value) == ST_OUT_OF_MEM) { - ABC_FREE(factors); - return(NULL); + /* insert g in htable */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->g), &value)) { + if (value == 2) { + value |= 1; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), + (char *)(long)value) == ST_OUT_OF_MEM) { + ABC_FREE(factors); + return(NULL); + } + } + } else { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->g), + (char *)(long)value) == ST_OUT_OF_MEM) { + ABC_FREE(factors); + return(NULL); + } } } - } if (factors->h != one) { - /* insert h in htable */ - value = 0; - if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->h), &value)) { - if (value == 1) { - value |= 2; - if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), - (char *)(long)value) == ST_OUT_OF_MEM) { - ABC_FREE(factors); - return(NULL); - } - } - } else { - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), - (char *)(long)value) == ST_OUT_OF_MEM) { - ABC_FREE(factors); - return(NULL); + /* insert h in htable */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(factors->h), &value)) { + if (value == 1) { + value |= 2; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), + (char *)(long)value) == ST_OUT_OF_MEM) { + ABC_FREE(factors); + return(NULL); + } + } + } else { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(factors->h), + (char *)(long)value) == ST_OUT_OF_MEM) { + ABC_FREE(factors); + return(NULL); + } } } - } /* Store factors in cache table for later use. */ if (st_insert(cacheTable, (char *)node, (char *)factors) == - ST_OUT_OF_MEM) { - ABC_FREE(factors); - return(NULL); + ST_OUT_OF_MEM) { + ABC_FREE(factors); + return(NULL); } return(factors); @@ -1208,192 +1236,192 @@ CheckInTables( /* if none of the 4 exist in the gh tables, return NULL */ if ((pairValue1 == NONE) && (pairValue2 == NONE)) { - return NULL; + return NULL; } factors = ABC_ALLOC(Conjuncts, 1); if (factors == NULL) { - *outOfMem = 1; - return NULL; + *outOfMem = 1; + return NULL; } /* pairs that already exist in the table get preference. */ if (pairValue1 == PAIR_ST) { - factors->g = g1; - factors->h = h1; + factors->g = g1; + factors->h = h1; } else if (pairValue2 == PAIR_ST) { - factors->g = g2; - factors->h = h2; + factors->g = g2; + factors->h = h2; } else if (pairValue1 == PAIR_CR) { - factors->g = h1; - factors->h = g1; + factors->g = h1; + factors->h = g1; } else if (pairValue2 == PAIR_CR) { - factors->g = h2; - factors->h = g2; + factors->g = h2; + factors->h = g2; } else if (pairValue1 == G_ST) { - /* g exists in the table, h is not found in either table */ - factors->g = g1; - factors->h = h1; - if (h1 != one) { - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(h1), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g exists in the table, h is not found in either table */ + factors->g = g1; + factors->h = h1; + if (h1 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue1 == BOTH_G) { - /* g and h are found in the g table */ - factors->g = g1; - factors->h = h1; - if (h1 != one) { - value = 3; - if (st_insert(ghTable, (char *)Cudd_Regular(h1), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g and h are found in the g table */ + factors->g = g1; + factors->h = h1; + if (h1 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue1 == H_ST) { - /* h exists in the table, g is not found in either table */ - factors->g = g1; - factors->h = h1; - if (g1 != one) { - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(g1), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* h exists in the table, g is not found in either table */ + factors->g = g1; + factors->h = h1; + if (g1 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue1 == BOTH_H) { - /* g and h are found in the h table */ - factors->g = g1; - factors->h = h1; - if (g1 != one) { - value = 3; - if (st_insert(ghTable, (char *)Cudd_Regular(g1), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g and h are found in the h table */ + factors->g = g1; + factors->h = h1; + if (g1 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue2 == G_ST) { - /* g exists in the table, h is not found in either table */ - factors->g = g2; - factors->h = h2; - if (h2 != one) { - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(h2), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g exists in the table, h is not found in either table */ + factors->g = g2; + factors->h = h2; + if (h2 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue2 == BOTH_G) { - /* g and h are found in the g table */ - factors->g = g2; - factors->h = h2; - if (h2 != one) { - value = 3; - if (st_insert(ghTable, (char *)Cudd_Regular(h2), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g and h are found in the g table */ + factors->g = g2; + factors->h = h2; + if (h2 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue2 == H_ST) { - /* h exists in the table, g is not found in either table */ - factors->g = g2; - factors->h = h2; - if (g2 != one) { - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(g2), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* h exists in the table, g is not found in either table */ + factors->g = g2; + factors->h = h2; + if (g2 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue2 == BOTH_H) { - /* g and h are found in the h table */ - factors->g = g2; - factors->h = h2; - if (g2 != one) { - value = 3; - if (st_insert(ghTable, (char *)Cudd_Regular(g2), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g and h are found in the h table */ + factors->g = g2; + factors->h = h2; + if (g2 != one) { + value = 3; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue1 == G_CR) { - /* g found in h table and h in none */ - factors->g = h1; - factors->h = g1; - if (h1 != one) { - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(h1), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g found in h table and h in none */ + factors->g = h1; + factors->h = g1; + if (h1 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue1 == H_CR) { - /* h found in g table and g in none */ - factors->g = h1; - factors->h = g1; - if (g1 != one) { - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(g1), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* h found in g table and g in none */ + factors->g = h1; + factors->h = g1; + if (g1 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g1), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue2 == G_CR) { - /* g found in h table and h in none */ - factors->g = h2; - factors->h = g2; - if (h2 != one) { - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(h2), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* g found in h table and h in none */ + factors->g = h2; + factors->h = g2; + if (h2 != one) { + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(h2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } - } } else if (pairValue2 == H_CR) { - /* h found in g table and g in none */ - factors->g = h2; - factors->h = g2; - if (g2 != one) { - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(g2), - (char *)(long)value) == ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + /* h found in g table and g in none */ + factors->g = h2; + factors->h = g2; + if (g2 != one) { + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(g2), + (char *)(long)value) == ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); + } } } - } /* Store factors in cache table for later use. */ if (st_insert(cacheTable, (char *)node, (char *)factors) == - ST_OUT_OF_MEM) { - *outOfMem = 1; - ABC_FREE(factors); - return(NULL); + ST_OUT_OF_MEM) { + *outOfMem = 1; + ABC_FREE(factors); + return(NULL); } return factors; } /* end of CheckInTables */ @@ -1440,69 +1468,69 @@ ZeroCase( /* Seprate variable and child */ if (factorsNv->g == one) { - Cudd_RecursiveDeref(dd, factorsNv->g); - factors = ABC_ALLOC(Conjuncts, 1); - if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, x); - return(NULL); - } - factors->g = x; - factors->h = factorsNv->h; - /* cache the result*/ - if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, x); - ABC_FREE(factors); - return NULL; - } - - /* store x in g table, the other node is already in the table */ - if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { - value |= 1; - } else { - value = 1; - } - if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { - dd->errorCode = CUDD_MEMORY_OUT; - return NULL; - } - return(factors); + Cudd_RecursiveDeref(dd, factorsNv->g); + factors = ABC_ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + factors->g = x; + factors->h = factorsNv->h; + /* cache the result*/ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + ABC_FREE(factors); + return NULL; + } + + /* store x in g table, the other node is already in the table */ + if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { + value |= 1; + } else { + value = 1; + } + if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + return(factors); } /* Seprate variable and child */ if (factorsNv->h == one) { - Cudd_RecursiveDeref(dd, factorsNv->h); - factors = ABC_ALLOC(Conjuncts, 1); - if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, x); - return(NULL); - } - factors->g = factorsNv->g; - factors->h = x; - /* cache the result. */ - if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, x); - ABC_FREE(factors); - return(NULL); - } - /* store x in h table, the other node is already in the table */ - if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { - value |= 2; - } else { - value = 2; - } - if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { - dd->errorCode = CUDD_MEMORY_OUT; - return NULL; - } - return(factors); + Cudd_RecursiveDeref(dd, factorsNv->h); + factors = ABC_ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + return(NULL); + } + factors->g = factorsNv->g; + factors->h = x; + /* cache the result. */ + if (st_insert(cacheTable, (char *)node, (char *)factors) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + ABC_FREE(factors); + return(NULL); + } + /* store x in h table, the other node is already in the table */ + if (st_lookup_int(ghTable, (char *)Cudd_Regular(x), &value)) { + value |= 2; + } else { + value = 2; + } + if (st_insert(ghTable, (char *)Cudd_Regular(x), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + return NULL; + } + return(factors); } G = Cudd_Regular(factorsNv->g); @@ -1512,29 +1540,29 @@ ZeroCase( Gnv = Cudd_NotCond(Gnv, Cudd_IsComplement(node)); /* if the child below is a variable */ if ((Gv == zero) || (Gnv == zero)) { - h = factorsNv->h; - g = cuddBddAndRecur(dd, x, factorsNv->g); - if (g != NULL) cuddRef(g); - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, x); - if (g == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->h); - return NULL; - } - /* CheckTablesCacheAndReturn responsible for allocating - * factors structure., g,h referenced for cache store the - */ - factors = CheckTablesCacheAndReturn(node, - g, - h, - ghTable, - cacheTable); - if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, g); - Cudd_RecursiveDeref(dd, h); - } - return(factors); + h = factorsNv->h; + g = cuddBddAndRecur(dd, x, factorsNv->g); + if (g != NULL) cuddRef(g); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, x); + if (g == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->h); + return NULL; + } + /* CheckTablesCacheAndReturn responsible for allocating + * factors structure., g,h referenced for cache store the + */ + factors = CheckTablesCacheAndReturn(node, + g, + h, + ghTable, + cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g); + Cudd_RecursiveDeref(dd, h); + } + return(factors); } H = Cudd_Regular(factorsNv->h); @@ -1544,29 +1572,29 @@ ZeroCase( Hnv = Cudd_NotCond(Hnv, Cudd_IsComplement(node)); /* if the child below is a variable */ if ((Hv == zero) || (Hnv == zero)) { - g = factorsNv->g; - h = cuddBddAndRecur(dd, x, factorsNv->h); - if (h!= NULL) cuddRef(h); - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, x); - if (h == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->g); - return NULL; - } - /* CheckTablesCacheAndReturn responsible for allocating - * factors structure.g,h referenced for table store - */ - factors = CheckTablesCacheAndReturn(node, - g, - h, - ghTable, - cacheTable); - if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, g); - Cudd_RecursiveDeref(dd, h); - } - return(factors); + g = factorsNv->g; + h = cuddBddAndRecur(dd, x, factorsNv->h); + if (h!= NULL) cuddRef(h); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, x); + if (h == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + return NULL; + } + /* CheckTablesCacheAndReturn responsible for allocating + * factors structure.g,h referenced for table store + */ + factors = CheckTablesCacheAndReturn(node, + g, + h, + ghTable, + cacheTable); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g); + Cudd_RecursiveDeref(dd, h); + } + return(factors); } /* build g1 = x*g; h1 = h */ @@ -1576,60 +1604,60 @@ ZeroCase( g1 = cuddBddAndRecur(dd, x, factorsNv->g); if (g1 != NULL) cuddRef(g1); if (g1 == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, factorsNv->h); - return NULL; + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + return NULL; } g2 = factorsNv->g; h2 = cuddBddAndRecur(dd, x, factorsNv->h); if (h2 != NULL) cuddRef(h2); if (h2 == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, factorsNv->g); - return NULL; + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNv->g); + return NULL; } /* check whether any pair is in tables */ factors = CheckInTables(node, g1, h1, g2, h2, ghTable, cacheTable, &outOfMem); if (outOfMem) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - Cudd_RecursiveDeref(dd, g2); - Cudd_RecursiveDeref(dd, h2); - return NULL; - } - if (factors != NULL) { - if ((factors->g == g1) || (factors->g == h1)) { - Cudd_RecursiveDeref(dd, g2); - Cudd_RecursiveDeref(dd, h2); - } else { + dd->errorCode = CUDD_MEMORY_OUT; Cudd_RecursiveDeref(dd, g1); Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + return NULL; } - return factors; + if (factors != NULL) { + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + return factors; } /* check for each pair in tables and choose one */ factors = PickOnePair(node,g1, h1, g2, h2, ghTable, cacheTable); if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - Cudd_RecursiveDeref(dd, g2); - Cudd_RecursiveDeref(dd, h2); - } else { - /* now free what was created and not used */ - if ((factors->g == g1) || (factors->g == h1)) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); Cudd_RecursiveDeref(dd, g2); Cudd_RecursiveDeref(dd, h2); } else { - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - } + /* now free what was created and not used */ + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } } - + return(factors); } /* end of ZeroCase */ @@ -1665,8 +1693,7 @@ BuildConjuncts( st_table * mintermTable) { int topid, distance; - Conjuncts *factorsNv = NULL, *factorsNnv = NULL; // Suppress "might be used uninitialized" - Conjuncts *factors; + Conjuncts *factorsNv, *factorsNnv, *factors; Conjuncts *dummy; DdNode *N, *Nv, *Nnv, *temp, *g1, *g2, *h1, *h2, *topv; double minNv = 0.0, minNnv = 0.0; @@ -1679,82 +1706,82 @@ BuildConjuncts( /* if f is constant, return (f,f) */ if (Cudd_IsConstant(node)) { - factors = ABC_ALLOC(Conjuncts, 1); - if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - factors->g = node; - factors->h = node; - return(FactorsComplement(factors)); + factors = ABC_ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + factors->g = node; + factors->h = node; + return(FactorsComplement(factors)); } /* If result (a pair of conjuncts) in cache, return the factors. */ - if (st_lookup(cacheTable, (char *)node, (char **)&dummy)) { - factors = dummy; - return(factors); + if (st_lookup(cacheTable, (const char *)node, (char **)&dummy)) { + factors = dummy; + return(factors); } /* check distance and local reference count of this node */ N = Cudd_Regular(node); - if (!st_lookup(distanceTable, (char *)N, (char **)&nodeStat)) { - (void) fprintf(dd->err, "Not in table, Something wrong\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + if (!st_lookup(distanceTable, (const char *)N, (char **)&nodeStat)) { + (void) fprintf(dd->err, "Not in table, Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } distance = nodeStat->distance; /* at or below decomposition point, return (f, 1) */ if (((nodeStat->localRef > maxLocalRef*2/3) && - (distance < approxDistance*2/3)) || - (distance <= approxDistance/4)) { - factors = ABC_ALLOC(Conjuncts, 1); - if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - /* alternate assigning (f,1) */ - value = 0; - if (st_lookup_int(ghTable, (char *)Cudd_Regular(node), &value)) { - if (value == 3) { - if (!lastTimeG) { + (distance < approxDistance*2/3)) || + (distance <= approxDistance/4)) { + factors = ABC_ALLOC(Conjuncts, 1); + if (factors == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + /* alternate assigning (f,1) */ + value = 0; + if (st_lookup_int(ghTable, (char *)Cudd_Regular(node), &value)) { + if (value == 3) { + if (!lastTimeG) { + factors->g = node; + factors->h = one; + lastTimeG = 1; + } else { + factors->g = one; + factors->h = node; + lastTimeG = 0; + } + } else if (value == 1) { + factors->g = node; + factors->h = one; + } else { + factors->g = one; + factors->h = node; + } + } else if (!lastTimeG) { factors->g = node; factors->h = one; lastTimeG = 1; + value = 1; + if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(factors); + return NULL; + } } else { factors->g = one; factors->h = node; - lastTimeG = 0; - } - } else if (value == 1) { - factors->g = node; - factors->h = one; - } else { - factors->g = one; - factors->h = node; - } - } else if (!lastTimeG) { - factors->g = node; - factors->h = one; - lastTimeG = 1; - value = 1; - if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(factors); - return NULL; - } - } else { - factors->g = one; - factors->h = node; - lastTimeG = 0; - value = 2; - if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(factors); - return NULL; + lastTimeG = 0; + value = 2; + if (st_insert(ghTable, (char *)Cudd_Regular(node), (char *)(long)value) == ST_OUT_OF_MEM) { + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(factors); + return NULL; + } } - } - return(FactorsComplement(factors)); + return(FactorsComplement(factors)); } /* get the children and recur */ @@ -1767,87 +1794,87 @@ BuildConjuncts( * minterms. We go first where there are more minterms. */ if (!Cudd_IsConstant(Nv)) { - if (!st_lookup(mintermTable, (char *)Nv, (char **)&doubleDummy)) { - (void) fprintf(dd->err, "Not in table: Something wrong\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } - minNv = *doubleDummy; + if (!st_lookup(mintermTable, (const char *)Nv, (char **)&doubleDummy)) { + (void) fprintf(dd->err, "Not in table: Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + minNv = *doubleDummy; } if (!Cudd_IsConstant(Nnv)) { - if (!st_lookup(mintermTable, (char *)Nnv, (char **)&doubleDummy)) { - (void) fprintf(dd->err, "Not in table: Something wrong\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } - minNnv = *doubleDummy; + if (!st_lookup(mintermTable, (const char *)Nnv, (char **)&doubleDummy)) { + (void) fprintf(dd->err, "Not in table: Something wrong\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + minNnv = *doubleDummy; } if (minNv < minNnv) { - temp = Nv; - Nv = Nnv; - Nnv = temp; - switched = 1; + temp = Nv; + Nv = Nnv; + Nnv = temp; + switched = 1; } /* build gt, ht recursively */ if (Nv != zero) { - factorsNv = BuildConjuncts(dd, Nv, distanceTable, - cacheTable, approxDistance, maxLocalRef, - ghTable, mintermTable); - if (factorsNv == NULL) return(NULL); - freeNv = FactorsNotStored(factorsNv); - factorsNv = (freeNv) ? FactorsUncomplement(factorsNv) : factorsNv; - cuddRef(factorsNv->g); - cuddRef(factorsNv->h); - - /* Deal with the zero case */ - if (Nnv == zero) { - /* is responsible for freeing factorsNv */ - factors = ZeroCase(dd, node, factorsNv, ghTable, - cacheTable, switched); - if (freeNv) ABC_FREE(factorsNv); - return(factors); - } + factorsNv = BuildConjuncts(dd, Nv, distanceTable, + cacheTable, approxDistance, maxLocalRef, + ghTable, mintermTable); + if (factorsNv == NULL) return(NULL); + freeNv = FactorsNotStored(factorsNv); + factorsNv = (freeNv) ? FactorsUncomplement(factorsNv) : factorsNv; + cuddRef(factorsNv->g); + cuddRef(factorsNv->h); + + /* Deal with the zero case */ + if (Nnv == zero) { + /* is responsible for freeing factorsNv */ + factors = ZeroCase(dd, node, factorsNv, ghTable, + cacheTable, switched); + if (freeNv) ABC_FREE(factorsNv); + return(factors); + } } /* build ge, he recursively */ if (Nnv != zero) { - factorsNnv = BuildConjuncts(dd, Nnv, distanceTable, - cacheTable, approxDistance, maxLocalRef, - ghTable, mintermTable); - if (factorsNnv == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, factorsNv->h); - if (freeNv) ABC_FREE(factorsNv); - return(NULL); - } - freeNnv = FactorsNotStored(factorsNnv); - factorsNnv = (freeNnv) ? FactorsUncomplement(factorsNnv) : factorsNnv; - cuddRef(factorsNnv->g); - cuddRef(factorsNnv->h); - - /* Deal with the zero case */ - if (Nv == zero) { - /* is responsible for freeing factorsNv */ - factors = ZeroCase(dd, node, factorsNnv, ghTable, - cacheTable, switched); - if (freeNnv) ABC_FREE(factorsNnv); - return(factors); - } + factorsNnv = BuildConjuncts(dd, Nnv, distanceTable, + cacheTable, approxDistance, maxLocalRef, + ghTable, mintermTable); + if (factorsNnv == NULL) { + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + if (freeNv) ABC_FREE(factorsNv); + return(NULL); + } + freeNnv = FactorsNotStored(factorsNnv); + factorsNnv = (freeNnv) ? FactorsUncomplement(factorsNnv) : factorsNnv; + cuddRef(factorsNnv->g); + cuddRef(factorsNnv->h); + + /* Deal with the zero case */ + if (Nv == zero) { + /* is responsible for freeing factorsNv */ + factors = ZeroCase(dd, node, factorsNnv, ghTable, + cacheTable, switched); + if (freeNnv) ABC_FREE(factorsNnv); + return(factors); + } } /* construct the 2 pairs */ /* g1 = x*gt + x'*ge; h1 = x*ht + x'*he; */ /* g2 = x*gt + x'*he; h2 = x*ht + x'*ge */ if (switched) { - factors = factorsNnv; - factorsNnv = factorsNv; - factorsNv = factors; - freeTemp = freeNv; - freeNv = freeNnv; - freeNnv = freeTemp; + factors = factorsNnv; + factorsNnv = factorsNv; + factorsNv = factors; + freeTemp = freeNv; + freeNv = freeNnv; + freeNnv = freeTemp; } /* Build the factors for this node. */ @@ -1856,42 +1883,42 @@ BuildConjuncts( g1 = cuddBddIteRecur(dd, topv, factorsNv->g, factorsNnv->g); if (g1 == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, factorsNnv->g); - Cudd_RecursiveDeref(dd, factorsNnv->h); - if (freeNv) ABC_FREE(factorsNv); - if (freeNnv) ABC_FREE(factorsNnv); - return(NULL); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + if (freeNv) ABC_FREE(factorsNv); + if (freeNnv) ABC_FREE(factorsNnv); + return(NULL); } cuddRef(g1); h1 = cuddBddIteRecur(dd, topv, factorsNv->h, factorsNnv->h); if (h1 == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, factorsNnv->g); - Cudd_RecursiveDeref(dd, factorsNnv->h); - Cudd_RecursiveDeref(dd, g1); - if (freeNv) ABC_FREE(factorsNv); - if (freeNnv) ABC_FREE(factorsNnv); - return(NULL); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + if (freeNv) ABC_FREE(factorsNv); + if (freeNnv) ABC_FREE(factorsNnv); + return(NULL); } cuddRef(h1); g2 = cuddBddIteRecur(dd, topv, factorsNv->g, factorsNnv->h); if (g2 == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, factorsNnv->g); - Cudd_RecursiveDeref(dd, factorsNnv->h); - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - if (freeNv) ABC_FREE(factorsNv); - if (freeNnv) ABC_FREE(factorsNnv); - return(NULL); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + if (freeNv) ABC_FREE(factorsNv); + if (freeNnv) ABC_FREE(factorsNnv); + return(NULL); } cuddRef(g2); Cudd_RecursiveDeref(dd, factorsNv->g); @@ -1899,16 +1926,16 @@ BuildConjuncts( h2 = cuddBddIteRecur(dd, topv, factorsNv->h, factorsNnv->g); if (h2 == NULL) { - Cudd_RecursiveDeref(dd, factorsNv->g); - Cudd_RecursiveDeref(dd, factorsNv->h); - Cudd_RecursiveDeref(dd, factorsNnv->g); - Cudd_RecursiveDeref(dd, factorsNnv->h); - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - Cudd_RecursiveDeref(dd, g2); - if (freeNv) ABC_FREE(factorsNv); - if (freeNnv) ABC_FREE(factorsNnv); - return(NULL); + Cudd_RecursiveDeref(dd, factorsNv->g); + Cudd_RecursiveDeref(dd, factorsNv->h); + Cudd_RecursiveDeref(dd, factorsNnv->g); + Cudd_RecursiveDeref(dd, factorsNnv->h); + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + if (freeNv) ABC_FREE(factorsNv); + if (freeNnv) ABC_FREE(factorsNnv); + return(NULL); } cuddRef(h2); Cudd_RecursiveDeref(dd, factorsNv->h); @@ -1919,43 +1946,43 @@ BuildConjuncts( /* check for each pair in tables and choose one */ factors = CheckInTables(node, g1, h1, g2, h2, ghTable, cacheTable, &outOfMem); if (outOfMem) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - Cudd_RecursiveDeref(dd, g2); - Cudd_RecursiveDeref(dd, h2); - return(NULL); - } - if (factors != NULL) { - if ((factors->g == g1) || (factors->g == h1)) { - Cudd_RecursiveDeref(dd, g2); - Cudd_RecursiveDeref(dd, h2); - } else { + dd->errorCode = CUDD_MEMORY_OUT; Cudd_RecursiveDeref(dd, g1); Cudd_RecursiveDeref(dd, h1); + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + return(NULL); } - return(factors); + if (factors != NULL) { + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } + return(factors); } /* if not in tables, pick one pair */ factors = PickOnePair(node,g1, h1, g2, h2, ghTable, cacheTable); if (factors == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - Cudd_RecursiveDeref(dd, g2); - Cudd_RecursiveDeref(dd, h2); - } else { - /* now free what was created and not used */ - if ((factors->g == g1) || (factors->g == h1)) { + dd->errorCode = CUDD_MEMORY_OUT; + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); Cudd_RecursiveDeref(dd, g2); Cudd_RecursiveDeref(dd, h2); } else { - Cudd_RecursiveDeref(dd, g1); - Cudd_RecursiveDeref(dd, h1); - } + /* now free what was created and not used */ + if ((factors->g == g1) || (factors->g == h1)) { + Cudd_RecursiveDeref(dd, g2); + Cudd_RecursiveDeref(dd, h2); + } else { + Cudd_RecursiveDeref(dd, g1); + Cudd_RecursiveDeref(dd, h1); + } } - + return(factors); } /* end of BuildConjuncts */ @@ -1999,7 +2026,7 @@ cuddConjunctsAux( *c2 = NULL; /* initialize distances table */ - distanceTable = st_init_table(st_ptrcmp, st_ptrhash);; + distanceTable = st_init_table(st_ptrcmp,st_ptrhash); if (distanceTable == NULL) goto outOfMem; /* make the entry for the constant */ @@ -2008,7 +2035,7 @@ cuddConjunctsAux( nodeStat->distance = 0; nodeStat->localRef = 1; if (st_insert(distanceTable, (char *)one, (char *)nodeStat) == ST_OUT_OF_MEM) { - goto outOfMem; + goto outOfMem; } /* Count node distances from constant. */ @@ -2020,18 +2047,18 @@ cuddConjunctsAux( distance = nodeStat->distance; if (distance < approxDistance) { - /* Too small to bother. */ - *c1 = f; - *c2 = DD_ONE(dd); - cuddRef(*c1); cuddRef(*c2); - stGen = st_init_gen(distanceTable); - if (stGen == NULL) goto outOfMem; - while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ABC_FREE(value); - } - st_free_gen(stGen); stGen = NULL; - st_free_table(distanceTable); - return(1); + /* Too small to bother. */ + *c1 = f; + *c2 = DD_ONE(dd); + cuddRef(*c1); cuddRef(*c2); + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (const char **)&key, (char **)&value)) { + ABC_FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); + return(1); } /* record the maximum local reference count */ @@ -2039,16 +2066,16 @@ cuddConjunctsAux( stGen = st_init_gen(distanceTable); if (stGen == NULL) goto outOfMem; while(st_gen(stGen, (const char **)&key, (char **)&value)) { - nodeStat = (NodeStat *)value; - maxLocalRef = (nodeStat->localRef > maxLocalRef) ? - nodeStat->localRef : maxLocalRef; + nodeStat = (NodeStat *)value; + maxLocalRef = (nodeStat->localRef > maxLocalRef) ? + nodeStat->localRef : maxLocalRef; } st_free_gen(stGen); stGen = NULL; - + /* Count minterms for each node. */ max = pow(2.0, (double)Cudd_SupportSize(dd,f)); /* potential overflow */ - mintermTable = st_init_table(st_ptrcmp, st_ptrhash);; + mintermTable = st_init_table(st_ptrcmp,st_ptrhash); if (mintermTable == NULL) goto outOfMem; minterms = CountMinterms(f, max, mintermTable, dd->err); if (minterms == -1.0) goto outOfMem; @@ -2061,14 +2088,14 @@ cuddConjunctsAux( /* Build conjuncts. */ factors = BuildConjuncts(dd, f, distanceTable, cacheTable, - approxDistance, maxLocalRef, ghTable, mintermTable); + approxDistance, maxLocalRef, ghTable, mintermTable); if (factors == NULL) goto outOfMem; - /* Free up tables */ + /* free up tables */ stGen = st_init_gen(distanceTable); if (stGen == NULL) goto outOfMem; while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ABC_FREE(value); + ABC_FREE(value); } st_free_gen(stGen); stGen = NULL; st_free_table(distanceTable); distanceTable = NULL; @@ -2077,7 +2104,7 @@ cuddConjunctsAux( stGen = st_init_gen(mintermTable); if (stGen == NULL) goto outOfMem; while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ABC_FREE(value); + ABC_FREE(value); } st_free_gen(stGen); stGen = NULL; st_free_table(mintermTable); mintermTable = NULL; @@ -2085,33 +2112,33 @@ cuddConjunctsAux( freeFactors = FactorsNotStored(factors); factors = (freeFactors) ? FactorsUncomplement(factors) : factors; if (factors != NULL) { - *c1 = factors->g; - *c2 = factors->h; - cuddRef(*c1); - cuddRef(*c2); - if (freeFactors) ABC_FREE(factors); - + *c1 = factors->g; + *c2 = factors->h; + cuddRef(*c1); + cuddRef(*c2); + if (freeFactors) ABC_FREE(factors); + #if 0 - if ((*c1 == f) && (!Cudd_IsConstant(f))) { - assert(*c2 == one); - } - if ((*c2 == f) && (!Cudd_IsConstant(f))) { - assert(*c1 == one); - } - - if ((*c1 != one) && (!Cudd_IsConstant(f))) { - assert(!Cudd_bddLeq(dd, *c2, *c1)); - } - if ((*c2 != one) && (!Cudd_IsConstant(f))) { - assert(!Cudd_bddLeq(dd, *c1, *c2)); - } + if ((*c1 == f) && (!Cudd_IsConstant(f))) { + assert(*c2 == one); + } + if ((*c2 == f) && (!Cudd_IsConstant(f))) { + assert(*c1 == one); + } + + if ((*c1 != one) && (!Cudd_IsConstant(f))) { + assert(!Cudd_bddLeq(dd, *c2, *c1)); + } + if ((*c2 != one) && (!Cudd_IsConstant(f))) { + assert(!Cudd_bddLeq(dd, *c1, *c2)); + } #endif } stGen = st_init_gen(cacheTable); if (stGen == NULL) goto outOfMem; while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ConjunctsFree(dd, (Conjuncts *)value); + ConjunctsFree(dd, (Conjuncts *)value); } st_free_gen(stGen); stGen = NULL; @@ -2121,36 +2148,38 @@ cuddConjunctsAux( outOfMem: if (distanceTable != NULL) { - stGen = st_init_gen(distanceTable); - if (stGen == NULL) goto outOfMem; - while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ABC_FREE(value); - } - st_free_gen(stGen); stGen = NULL; - st_free_table(distanceTable); distanceTable = NULL; + stGen = st_init_gen(distanceTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (const char **)&key, (char **)&value)) { + ABC_FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(distanceTable); distanceTable = NULL; } if (mintermTable != NULL) { - stGen = st_init_gen(mintermTable); - if (stGen == NULL) goto outOfMem; - while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ABC_FREE(value); - } - st_free_gen(stGen); stGen = NULL; - st_free_table(mintermTable); mintermTable = NULL; + stGen = st_init_gen(mintermTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (const char **)&key, (char **)&value)) { + ABC_FREE(value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(mintermTable); mintermTable = NULL; } if (ghTable != NULL) st_free_table(ghTable); if (cacheTable != NULL) { - stGen = st_init_gen(cacheTable); - if (stGen == NULL) goto outOfMem; - while(st_gen(stGen, (const char **)&key, (char **)&value)) { - ConjunctsFree(dd, (Conjuncts *)value); - } - st_free_gen(stGen); stGen = NULL; - st_free_table(cacheTable); cacheTable = NULL; + stGen = st_init_gen(cacheTable); + if (stGen == NULL) goto outOfMem; + while(st_gen(stGen, (const char **)&key, (char **)&value)) { + ConjunctsFree(dd, (Conjuncts *)value); + } + st_free_gen(stGen); stGen = NULL; + st_free_table(cacheTable); cacheTable = NULL; } dd->errorCode = CUDD_MEMORY_OUT; return(0); } /* end of cuddConjunctsAux */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddEssent.c b/src/bdd/cudd/cuddEssent.c index 2d82019c..b3264715 100644 --- a/src/bdd/cudd/cuddEssent.c +++ b/src/bdd/cudd/cuddEssent.c @@ -7,21 +7,67 @@ Synopsis [Functions for the detection of essential variables.] Description [External procedures included in this file: - <ul> - <li> Cudd_FindEssential() - <li> Cudd_bddIsVarEssential() - </ul> - Static procedures included in this module: - <ul> - <li> ddFindEssentialRecur() - </ul>] + <ul> + <li> Cudd_FindEssential() + <li> Cudd_bddIsVarEssential() + <li> Cudd_FindTwoLiteralClauses() + <li> Cudd_ReadIthClause() + <li> Cudd_PrintTwoLiteralClauses() + <li> Cudd_tlcInfoFree() + </ul> + Static procedures included in this module: + <ul> + <li> ddFindEssentialRecur() + <li> ddFindTwoLiteralClausesRecur() + <li> computeClauses() + <li> computeClausesWithUniverse() + <li> emptyClauseSet() + <li> sentinelp() + <li> equalp() + <li> beforep() + <li> oneliteralp() + <li> impliedp() + <li> bitVectorAlloc() + <li> bitVectorClear() + <li> bitVectorFree() + <li> bitVectorRead() + <li> bitVectorSet() + <li> tlcInfoAlloc() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -31,26 +77,84 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ +/* These definitions are for the bit vectors. */ +#if SIZEOF_LONG == 8 +#define BPL 64 +#define LOGBPL 6 +#else +#define BPL 32 +#define LOGBPL 5 +#endif + /*---------------------------------------------------------------------------*/ /* Stucture declarations */ /*---------------------------------------------------------------------------*/ +/* This structure holds the set of clauses for a node. Each clause consists +** of two literals. For one-literal clauses, the second lietral is FALSE. +** Each literal is composed of a variable and a phase. A variable is a node +** index, and requires sizeof(DdHalfWord) bytes. The constant literals use +** CUDD_MAXINDEX as variable indicator. Each phase is a bit: 0 for positive +** phase, and 1 for negative phase. +** Variables and phases are stored separately for the sake of compactness. +** The variables are stored in an array of DdHalfWord's terminated by a +** sentinel (a pair of zeroes). The phases are stored in a bit vector. +** The cnt field holds, at the end, the number of clauses. +** The clauses of the set are kept sorted. For each clause, the first literal +** is the one of least index. So, the clause with literals +2 and -4 is stored +** as (+2,-4). A one-literal clause with literal +3 is stored as +** (+3,-CUDD_MAXINDEX). Clauses are sorted in decreasing order as follows: +** (+5,-7) +** (+5,+6) +** (-5,+7) +** (-4,FALSE) +** (-4,+8) +** ... +** That is, one first looks at the variable of the first literal, then at the +** phase of the first litral, then at the variable of the second literal, +** and finally at the phase of the second literal. +*/ +struct DdTlcInfo { + DdHalfWord *vars; + long *phases; + DdHalfWord cnt; +}; + +/* This structure is for temporary representation of sets of clauses. It is +** meant to be used in link lists, when the number of clauses is not yet +** known. The encoding of a clause is the same as in DdTlcInfo, though +** the phase information is not stored in a bit array. */ +struct TlClause { + DdHalfWord v1, v2; + short p1, p2; + struct TlClause *next; +}; + /*---------------------------------------------------------------------------*/ /* Type declarations */ /*---------------------------------------------------------------------------*/ +typedef long BitVector; +typedef struct TlClause TlClause; + /*---------------------------------------------------------------------------*/ /* Variable declarations */ /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddEssent.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddEssent.c,v 1.24 2009/02/21 18:24:10 fabio Exp $"; #endif +static BitVector *Tolv; +static BitVector *Tolp; +static BitVector *Eolv; +static BitVector *Eolp; + /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ @@ -61,7 +165,22 @@ static char rcsid[] DD_UNUSED = "$Id: cuddEssent.c,v 1.1.1.1 2003/02/24 22:23:51 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * ddFindEssentialRecur ARGS((DdManager *dd, DdNode *f)); +static DdNode * ddFindEssentialRecur (DdManager *dd, DdNode *f); +static DdTlcInfo * ddFindTwoLiteralClausesRecur (DdManager * dd, DdNode * f, st_table *table); +static DdTlcInfo * computeClauses (DdTlcInfo *Tres, DdTlcInfo *Eres, DdHalfWord label, int size); +static DdTlcInfo * computeClausesWithUniverse (DdTlcInfo *Cres, DdHalfWord label, short phase); +static DdTlcInfo * emptyClauseSet (void); +static int sentinelp (DdHalfWord var1, DdHalfWord var2); +static int equalp (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b); +static int beforep (DdHalfWord var1a, short phase1a, DdHalfWord var1b, short phase1b, DdHalfWord var2a, short phase2a, DdHalfWord var2b, short phase2b); +static int oneliteralp (DdHalfWord var); +static int impliedp (DdHalfWord var1, short phase1, DdHalfWord var2, short phase2, BitVector *olv, BitVector *olp); +static BitVector * bitVectorAlloc (int size); +DD_INLINE static void bitVectorClear (BitVector *vector, int size); +static void bitVectorFree (BitVector *vector); +DD_INLINE static short bitVectorRead (BitVector *vector, int i); +DD_INLINE static void bitVectorSet (BitVector * vector, int i, short val); +static DdTlcInfo * tlcInfoAlloc (void); /**AutomaticEnd***************************************************************/ @@ -94,8 +213,8 @@ Cudd_FindEssential( DdNode *res; do { - dd->reordered = 0; - res = ddFindEssentialRecur(dd,f); + dd->reordered = 0; + res = ddFindEssentialRecur(dd,f); } while (dd->reordered == 1); return(res); @@ -123,24 +242,226 @@ Cudd_bddIsVarEssential( int id, int phase) { - DdNode *var; - int res; - DdNode *one, *zero; - - one = DD_ONE(manager); - zero = Cudd_Not(one); + DdNode *var; + int res; - var = cuddUniqueInter(manager, id, one, zero); + var = Cudd_bddIthVar(manager, id); var = Cudd_NotCond(var,phase == 0); - res = Cudd_bddIteConstant(manager, Cudd_Not(f), one, var) == one; + res = Cudd_bddLeq(manager, f, var); return(res); } /* end of Cudd_bddIsVarEssential */ +/**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] + +******************************************************************************/ +DdTlcInfo * +Cudd_FindTwoLiteralClauses( + DdManager * dd, + DdNode * f) +{ + DdTlcInfo *res; + st_table *table; + st_generator *gen; + DdTlcInfo *tlc; + DdNode *node; + int size = dd->size; + + if (Cudd_IsConstant(f)) { + res = emptyClauseSet(); + return(res); + } + table = st_init_table(st_ptrcmp,st_ptrhash); + if (table == NULL) return(NULL); + Tolv = bitVectorAlloc(size); + if (Tolv == NULL) { + st_free_table(table); + return(NULL); + } + Tolp = bitVectorAlloc(size); + if (Tolp == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + return(NULL); + } + Eolv = bitVectorAlloc(size); + if (Eolv == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + return(NULL); + } + Eolp = bitVectorAlloc(size); + if (Eolp == NULL) { + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + bitVectorFree(Eolv); + return(NULL); + } + + res = ddFindTwoLiteralClausesRecur(dd,f,table); + /* Dispose of table contents and free table. */ + st_foreach_item(table, gen, (const char **)&node, (char **)&tlc) { + if (node != f) { + Cudd_tlcInfoFree(tlc); + } + } + st_free_table(table); + bitVectorFree(Tolv); + bitVectorFree(Tolp); + bitVectorFree(Eolv); + bitVectorFree(Eolp); + + if (res != NULL) { + int i; + for (i = 0; !sentinelp(res->vars[i], res->vars[i+1]); i += 2); + res->cnt = i >> 1; + } + + return(res); + +} /* end of Cudd_FindTwoLiteralClauses */ + + +/**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] + +******************************************************************************/ +int +Cudd_ReadIthClause( + DdTlcInfo * tlc, + int i, + DdHalfWord *var1, + DdHalfWord *var2, + int *phase1, + int *phase2) +{ + if (tlc == NULL) return(0); + if (tlc->vars == NULL || tlc->phases == NULL) return(0); + if (i < 0 || (unsigned) i >= tlc->cnt) return(0); + *var1 = tlc->vars[2*i]; + *var2 = tlc->vars[2*i+1]; + *phase1 = (int) bitVectorRead(tlc->phases, 2*i); + *phase2 = (int) bitVectorRead(tlc->phases, 2*i+1); + return(1); + +} /* end of Cudd_ReadIthClause */ + + +/**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] + +******************************************************************************/ +int +Cudd_PrintTwoLiteralClauses( + DdManager * dd, + DdNode * f, + char **names, + FILE *fp) +{ + DdHalfWord *vars; + BitVector *phases; + int i; + DdTlcInfo *res = Cudd_FindTwoLiteralClauses(dd, f); + FILE *ifp = fp == NULL ? dd->out : fp; + + if (res == NULL) return(0); + vars = res->vars; + phases = res->phases; + for (i = 0; !sentinelp(vars[i], vars[i+1]); i += 2) { + if (names != NULL) { + if (vars[i+1] == CUDD_MAXINDEX) { + (void) fprintf(ifp, "%s%s\n", + bitVectorRead(phases, i) ? "~" : " ", + names[vars[i]]); + } else { + (void) fprintf(ifp, "%s%s | %s%s\n", + bitVectorRead(phases, i) ? "~" : " ", + names[vars[i]], + bitVectorRead(phases, i+1) ? "~" : " ", + names[vars[i+1]]); + } + } else { + if (vars[i+1] == CUDD_MAXINDEX) { + (void) fprintf(ifp, "%s%d\n", + bitVectorRead(phases, i) ? "~" : " ", + (int) vars[i]); + } else { + (void) fprintf(ifp, "%s%d | %s%d\n", + bitVectorRead(phases, i) ? "~" : " ", + (int) vars[i], + bitVectorRead(phases, i+1) ? "~" : " ", + (int) vars[i+1]); + } + } + } + Cudd_tlcInfoFree(res); + + return(1); + +} /* end of Cudd_PrintTwoLiteralClauses */ + + +/**Function******************************************************************** + + Synopsis [Frees a DdTlcInfo Structure.] + + Description [Frees a DdTlcInfo Structure as well as the memory pointed + by it.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +void +Cudd_tlcInfoFree( + DdTlcInfo * t) +{ + if (t->vars != NULL) ABC_FREE(t->vars); + if (t->phases != NULL) ABC_FREE(t->phases); + ABC_FREE(t); + +} /* end of Cudd_tlcInfoFree */ + + /*---------------------------------------------------------------------------*/ /* Definition of internal functions */ /*---------------------------------------------------------------------------*/ @@ -166,10 +487,10 @@ ddFindEssentialRecur( DdManager * dd, DdNode * f) { - DdNode *T, *E, *F; - DdNode *essT, *essE, *res; - int index; - DdNode *one, *lzero, *azero; + DdNode *T, *E, *F; + DdNode *essT, *essE, *res; + int index; + DdNode *one, *lzero, *azero; one = DD_ONE(dd); F = Cudd_Regular(f); @@ -178,7 +499,7 @@ ddFindEssentialRecur( res = cuddCacheLookup1(dd,Cudd_FindEssential,f); if (res != NULL) { - return(res); + return(res); } lzero = Cudd_Not(one); @@ -187,98 +508,968 @@ ddFindEssentialRecur( T = cuddT(F); E = cuddE(F); if (Cudd_IsComplement(f)) { - T = Cudd_Not(T); E = Cudd_Not(E); + T = Cudd_Not(T); E = Cudd_Not(E); } index = F->index; if (Cudd_IsConstant(T) && T != lzero && T != azero) { - /* if E is zero, index is essential, otherwise there are no - ** essentials, because index is not essential and no other variable - ** can be, since setting index = 1 makes the function constant and - ** different from 0. - */ - if (E == lzero || E == azero) { - res = dd->vars[index]; - } else { - res = one; - } + /* if E is zero, index is essential, otherwise there are no + ** essentials, because index is not essential and no other variable + ** can be, since setting index = 1 makes the function constant and + ** different from 0. + */ + if (E == lzero || E == azero) { + res = dd->vars[index]; + } else { + res = one; + } } else if (T == lzero || T == azero) { - if (Cudd_IsConstant(E)) { /* E cannot be zero here */ - res = Cudd_Not(dd->vars[index]); - } else { /* E == non-constant */ - /* find essentials in the else branch */ - essE = ddFindEssentialRecur(dd,E); - if (essE == NULL) { - return(NULL); + if (Cudd_IsConstant(E)) { /* E cannot be zero here */ + res = Cudd_Not(dd->vars[index]); + } else { /* E == non-constant */ + /* find essentials in the else branch */ + essE = ddFindEssentialRecur(dd,E); + if (essE == NULL) { + return(NULL); + } + cuddRef(essE); + + /* add index to the set with negative phase */ + res = cuddUniqueInter(dd,index,one,Cudd_Not(essE)); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essE); + return(NULL); + } + res = Cudd_Not(res); + cuddDeref(essE); } - cuddRef(essE); - - /* add index to the set with negative phase */ - res = cuddUniqueInter(dd,index,one,Cudd_Not(essE)); - if (res == NULL) { - Cudd_RecursiveDeref(dd,essE); - return(NULL); + } else { /* T == non-const */ + if (E == lzero || E == azero) { + /* find essentials in the then branch */ + essT = ddFindEssentialRecur(dd,T); + if (essT == NULL) { + return(NULL); + } + cuddRef(essT); + + /* add index to the set with positive phase */ + /* use And because essT may be complemented */ + res = cuddBddAndRecur(dd,dd->vars[index],essT); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essT); + return(NULL); + } + cuddDeref(essT); + } else if (!Cudd_IsConstant(E)) { + /* if E is a non-zero constant there are no essentials + ** because T is non-constant. + */ + essT = ddFindEssentialRecur(dd,T); + if (essT == NULL) { + return(NULL); + } + if (essT == one) { + res = one; + } else { + cuddRef(essT); + essE = ddFindEssentialRecur(dd,E); + if (essE == NULL) { + Cudd_RecursiveDeref(dd,essT); + return(NULL); + } + cuddRef(essE); + + /* res = intersection(essT, essE) */ + res = cuddBddLiteralSetIntersectionRecur(dd,essT,essE); + if (res == NULL) { + Cudd_RecursiveDeref(dd,essT); + Cudd_RecursiveDeref(dd,essE); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDeref(dd,essT); + Cudd_RecursiveDeref(dd,essE); + cuddDeref(res); + } + } else { /* E is a non-zero constant */ + res = one; } - res = Cudd_Not(res); - cuddDeref(essE); } + + cuddCacheInsert1(dd,Cudd_FindEssential, f, res); + return(res); + +} /* end of ddFindEssentialRecur */ + + +/**Function******************************************************************** + + Synopsis [Implements the recursive step of Cudd_FindTwoLiteralClauses.] + + Description [Implements the recursive step of + Cudd_FindTwoLiteralClauses. The DD node is assumed to be not + constant. Returns a pointer to a set of clauses if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_FindTwoLiteralClauses] + +******************************************************************************/ +static DdTlcInfo * +ddFindTwoLiteralClausesRecur( + DdManager * dd, + DdNode * f, + st_table *table) +{ + DdNode *T, *E, *F; + DdNode *one, *lzero, *azero; + DdTlcInfo *res, *Tres, *Eres; + DdHalfWord index; + + F = Cudd_Regular(f); + + assert(!cuddIsConstant(F)); + + /* Check computed table. Separate entries are necessary for + ** a node and its complement. We should update the counter here. */ + if (st_lookup(table, (const char *)f, (char **)&res)) { + return(res); + } + + /* Easy access to the constants for BDDs and ADDs. */ + one = DD_ONE(dd); + lzero = Cudd_Not(one); + azero = DD_ZERO(dd); + + /* Find cofactors and variable labeling the top node. */ + T = cuddT(F); E = cuddE(F); + if (Cudd_IsComplement(f)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + index = F->index; + + if (Cudd_IsConstant(T) && T != lzero && T != azero) { + /* T is a non-zero constant. If E is zero, then this node's index + ** is a one-literal clause. Otherwise, if E is a non-zero + ** constant, there are no clauses for this node. Finally, + ** if E is not constant, we recursively compute its clauses, and then + ** merge using the empty set for T. */ + if (E == lzero || E == azero) { + /* Create the clause (index + 0). */ + res = tlcInfoAlloc(); + if (res == NULL) return(NULL); + res->vars = ABC_ALLOC(DdHalfWord,4); + if (res->vars == NULL) { + ABC_FREE(res); + return(NULL); + } + res->phases = bitVectorAlloc(2); + if (res->phases == NULL) { + ABC_FREE(res->vars); + ABC_FREE(res); + return(NULL); + } + res->vars[0] = index; + res->vars[1] = CUDD_MAXINDEX; + res->vars[2] = 0; + res->vars[3] = 0; + bitVectorSet(res->phases, 0, 0); /* positive phase */ + bitVectorSet(res->phases, 1, 1); /* negative phase */ + } else if (Cudd_IsConstant(E)) { + /* If E is a non-zero constant, no clauses. */ + res = emptyClauseSet(); + } else { + /* E is non-constant */ + Tres = emptyClauseSet(); + if (Tres == NULL) return(NULL); + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) { + Cudd_tlcInfoFree(Tres); + return(NULL); + } + res = computeClauses(Tres, Eres, index, dd->size); + Cudd_tlcInfoFree(Tres); + } + } else if (T == lzero || T == azero) { + /* T is zero. If E is a non-zero constant, then the + ** complement of this node's index is a one-literal clause. + ** Otherwise, if E is not constant, we recursively compute its + ** clauses, and then merge using the universal set for T. */ + if (Cudd_IsConstant(E)) { /* E cannot be zero here */ + /* Create the clause (!index + 0). */ + res = tlcInfoAlloc(); + if (res == NULL) return(NULL); + res->vars = ABC_ALLOC(DdHalfWord,4); + if (res->vars == NULL) { + ABC_FREE(res); + return(NULL); + } + res->phases = bitVectorAlloc(2); + if (res->phases == NULL) { + ABC_FREE(res->vars); + ABC_FREE(res); + return(NULL); + } + res->vars[0] = index; + res->vars[1] = CUDD_MAXINDEX; + res->vars[2] = 0; + res->vars[3] = 0; + bitVectorSet(res->phases, 0, 1); /* negative phase */ + bitVectorSet(res->phases, 1, 1); /* negative phase */ + } else { /* E == non-constant */ + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) return(NULL); + res = computeClausesWithUniverse(Eres, index, 1); + } } else { /* T == non-const */ - if (E == lzero || E == azero) { - /* find essentials in the then branch */ - essT = ddFindEssentialRecur(dd,T); - if (essT == NULL) { - return(NULL); + Tres = ddFindTwoLiteralClausesRecur(dd, T, table); + if (Tres == NULL) return(NULL); + if (Cudd_IsConstant(E)) { + if (E == lzero || E == azero) { + res = computeClausesWithUniverse(Tres, index, 0); + } else { + Eres = emptyClauseSet(); + if (Eres == NULL) return(NULL); + res = computeClauses(Tres, Eres, index, dd->size); + Cudd_tlcInfoFree(Eres); + } + } else { + Eres = ddFindTwoLiteralClausesRecur(dd, E, table); + if (Eres == NULL) return(NULL); + res = computeClauses(Tres, Eres, index, dd->size); } - cuddRef(essT); + } - /* add index to the set with positive phase */ - /* use And because essT may be complemented */ - res = cuddBddAndRecur(dd,dd->vars[index],essT); - if (res == NULL) { - Cudd_RecursiveDeref(dd,essT); - return(NULL); - } - cuddDeref(essT); - } else if (!Cudd_IsConstant(E)) { - /* if E is a non-zero constant there are no essentials - ** because T is non-constant. - */ - essT = ddFindEssentialRecur(dd,T); - if (essT == NULL) { + /* Cache results. */ + if (st_add_direct(table, (char *)f, (char *)res) == ST_OUT_OF_MEM) { + ABC_FREE(res); return(NULL); + } + return(res); + +} /* end of ddFindTwoLiteralClausesRecur */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-literal clauses for a node.] + + Description [Computes the two-literal clauses for a node given the + clauses for its children and the label of the node. Returns a + pointer to a TclInfo structure if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [computeClausesWithUniverse] + +******************************************************************************/ +static DdTlcInfo * +computeClauses( + DdTlcInfo *Tres /* list of clauses for T child */, + DdTlcInfo *Eres /* list of clauses for E child */, + DdHalfWord label /* variable labeling the current node */, + int size /* number of variables in the manager */) +{ + DdHalfWord *Tcv = Tres->vars; /* variables of clauses for the T child */ + BitVector *Tcp = Tres->phases; /* phases of clauses for the T child */ + DdHalfWord *Ecv = Eres->vars; /* variables of clauses for the E child */ + BitVector *Ecp = Eres->phases; /* phases of clauses for the E child */ + DdHalfWord *Vcv = NULL; /* pointer to variables of the clauses for v */ + BitVector *Vcp = NULL; /* pointer to phases of the clauses for v */ + DdTlcInfo *res = NULL; /* the set of clauses to be returned */ + int pt = 0; /* index in the list of clauses of T */ + int pe = 0; /* index in the list of clauses of E */ + int cv = 0; /* counter of the clauses for this node */ + TlClause *iclauses = NULL; /* list of inherited clauses */ + TlClause *tclauses = NULL; /* list of 1-literal clauses of T */ + TlClause *eclauses = NULL; /* list of 1-literal clauses of E */ + TlClause *nclauses = NULL; /* list of new (non-inherited) clauses */ + TlClause *lnclause = NULL; /* pointer to last new clause */ + TlClause *newclause; /* temporary pointer to new clauses */ + + /* Initialize sets of one-literal clauses. The one-literal clauses + ** are stored redundantly. These sets allow constant-time lookup, which + ** we need when we check for implication of a two-literal clause by a + ** one-literal clause. The linked lists allow fast sequential + ** processing. */ + bitVectorClear(Tolv, size); + bitVectorClear(Tolp, size); + bitVectorClear(Eolv, size); + bitVectorClear(Eolp, size); + + /* Initialize result structure. */ + res = tlcInfoAlloc(); + if (res == NULL) goto cleanup; + + /* Scan the two input list. Extract inherited two-literal clauses + ** and set aside one-literal clauses from each list. The incoming lists + ** are sorted in the order defined by beforep. The three linked list + ** produced by this loop are sorted in the reverse order because we + ** always append to the front of the lists. + ** The inherited clauses are those clauses (both one- and two-literal) + ** that are common to both children; and the two-literal clauses of + ** one child that are implied by a one-literal clause of the other + ** child. */ + while (!sentinelp(Tcv[pt], Tcv[pt+1]) || !sentinelp(Ecv[pe], Ecv[pe+1])) { + if (equalp(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1))) { + /* Add clause to inherited list. */ + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = Tcv[pt+1]; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = bitVectorRead(Tcp, pt+1); + newclause->next = iclauses; + iclauses = newclause; + pt += 2; pe += 2; cv++; + } else if (beforep(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1))) { + if (oneliteralp(Tcv[pt+1])) { + /* Add this one-literal clause to the T set. */ + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = 1; + newclause->next = tclauses; + tclauses = newclause; + bitVectorSet(Tolv, Tcv[pt], 1); + bitVectorSet(Tolp, Tcv[pt], bitVectorRead(Tcp, pt)); + } else { + if (impliedp(Tcv[pt], bitVectorRead(Tcp, pt), + Tcv[pt+1], bitVectorRead(Tcp, pt+1), + Eolv, Eolp)) { + /* Add clause to inherited list. */ + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Tcv[pt]; + newclause->v2 = Tcv[pt+1]; + newclause->p1 = bitVectorRead(Tcp, pt); + newclause->p2 = bitVectorRead(Tcp, pt+1); + newclause->next = iclauses; + iclauses = newclause; + cv++; + } + } + pt += 2; + } else { /* !beforep() */ + if (oneliteralp(Ecv[pe+1])) { + /* Add this one-literal clause to the E set. */ + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Ecv[pe]; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = bitVectorRead(Ecp, pe); + newclause->p2 = 1; + newclause->next = eclauses; + eclauses = newclause; + bitVectorSet(Eolv, Ecv[pe], 1); + bitVectorSet(Eolp, Ecv[pe], bitVectorRead(Ecp, pe)); + } else { + if (impliedp(Ecv[pe], bitVectorRead(Ecp, pe), + Ecv[pe+1], bitVectorRead(Ecp, pe+1), + Tolv, Tolp)) { + /* Add clause to inherited list. */ + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = Ecv[pe]; + newclause->v2 = Ecv[pe+1]; + newclause->p1 = bitVectorRead(Ecp, pe); + newclause->p2 = bitVectorRead(Ecp, pe+1); + newclause->next = iclauses; + iclauses = newclause; + cv++; + } + } + pe += 2; } - if (essT == one) { - res = one; + } + + /* Add one-literal clauses for the label variable to the front of + ** the two lists. */ + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = label; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = 0; + newclause->p2 = 1; + newclause->next = tclauses; + tclauses = newclause; + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = label; + newclause->v2 = CUDD_MAXINDEX; + newclause->p1 = 1; + newclause->p2 = 1; + newclause->next = eclauses; + eclauses = newclause; + + /* Produce the non-inherited clauses. We preserve the "reverse" + ** order of the two input lists by appending to the end of the + ** list. In this way, iclauses and nclauses are consistent. */ + while (tclauses != NULL && eclauses != NULL) { + if (beforep(eclauses->v1, eclauses->p1, eclauses->v2, eclauses->p2, + tclauses->v1, tclauses->p1, tclauses->v2, tclauses->p2)) { + TlClause *nextclause = tclauses->next; + TlClause *otherclauses = eclauses; + while (otherclauses != NULL) { + if (tclauses->v1 != otherclauses->v1) { + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = tclauses->v1; + newclause->v2 = otherclauses->v1; + newclause->p1 = tclauses->p1; + newclause->p2 = otherclauses->p1; + newclause->next = NULL; + if (nclauses == NULL) { + nclauses = newclause; + lnclause = newclause; + } else { + lnclause->next = newclause; + lnclause = newclause; + } + cv++; + } + otherclauses = otherclauses->next; + } + ABC_FREE(tclauses); + tclauses = nextclause; } else { - cuddRef(essT); - essE = ddFindEssentialRecur(dd,E); - if (essE == NULL) { - Cudd_RecursiveDeref(dd,essT); - return(NULL); + TlClause *nextclause = eclauses->next; + TlClause *otherclauses = tclauses; + while (otherclauses != NULL) { + if (eclauses->v1 != otherclauses->v1) { + newclause = ABC_ALLOC(TlClause,1); + if (newclause == NULL) goto cleanup; + newclause->v1 = eclauses->v1; + newclause->v2 = otherclauses->v1; + newclause->p1 = eclauses->p1; + newclause->p2 = otherclauses->p1; + newclause->next = NULL; + if (nclauses == NULL) { + nclauses = newclause; + lnclause = newclause; + } else { + lnclause->next = newclause; + lnclause = newclause; + } + cv++; + } + otherclauses = otherclauses->next; + } + ABC_FREE(eclauses); + eclauses = nextclause; } - cuddRef(essE); - - /* res = intersection(essT, essE) */ - res = cuddBddLiteralSetIntersectionRecur(dd,essT,essE); - if (res == NULL) { - Cudd_RecursiveDeref(dd,essT); - Cudd_RecursiveDeref(dd,essE); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(dd,essT); - Cudd_RecursiveDeref(dd,essE); - cuddDeref(res); + } + while (tclauses != NULL) { + TlClause *nextclause = tclauses->next; + ABC_FREE(tclauses); + tclauses = nextclause; + } + while (eclauses != NULL) { + TlClause *nextclause = eclauses->next; + ABC_FREE(eclauses); + eclauses = nextclause; + } + + /* Merge inherited and non-inherited clauses. Now that we know the + ** total number, we allocate the arrays, and we fill them bottom-up + ** to restore the proper ordering. */ + Vcv = ABC_ALLOC(DdHalfWord, 2*(cv+1)); + if (Vcv == NULL) goto cleanup; + if (cv > 0) { + Vcp = bitVectorAlloc(2*cv); + if (Vcp == NULL) goto cleanup; + } else { + Vcp = NULL; + } + res->vars = Vcv; + res->phases = Vcp; + /* Add sentinel. */ + Vcv[2*cv] = 0; + Vcv[2*cv+1] = 0; + while (iclauses != NULL || nclauses != NULL) { + TlClause *nextclause; + cv--; + if (nclauses == NULL || (iclauses != NULL && + beforep(nclauses->v1, nclauses->p1, nclauses->v2, nclauses->p2, + iclauses->v1, iclauses->p1, iclauses->v2, iclauses->p2))) { + Vcv[2*cv] = iclauses->v1; + Vcv[2*cv+1] = iclauses->v2; + bitVectorSet(Vcp, 2*cv, iclauses->p1); + bitVectorSet(Vcp, 2*cv+1, iclauses->p2); + nextclause = iclauses->next; + ABC_FREE(iclauses); + iclauses = nextclause; + } else { + Vcv[2*cv] = nclauses->v1; + Vcv[2*cv+1] = nclauses->v2; + bitVectorSet(Vcp, 2*cv, nclauses->p1); + bitVectorSet(Vcp, 2*cv+1, nclauses->p2); + nextclause = nclauses->next; + ABC_FREE(nclauses); + nclauses = nextclause; } - } else { /* E is a non-zero constant */ - res = one; } + assert(cv == 0); + + return(res); + + cleanup: + if (res != NULL) Cudd_tlcInfoFree(res); + while (iclauses != NULL) { + TlClause *nextclause = iclauses->next; + ABC_FREE(iclauses); + iclauses = nextclause; + } + while (nclauses != NULL) { + TlClause *nextclause = nclauses->next; + ABC_FREE(nclauses); + nclauses = nextclause; + } + while (tclauses != NULL) { + TlClause *nextclause = tclauses->next; + ABC_FREE(tclauses); + tclauses = nextclause; + } + while (eclauses != NULL) { + TlClause *nextclause = eclauses->next; + ABC_FREE(eclauses); + eclauses = nextclause; } - cuddCacheInsert1(dd,Cudd_FindEssential, f, res); + return(NULL); + +} /* end of computeClauses */ + + +/**Function******************************************************************** + + Synopsis [Computes the two-literal clauses for a node.] + + Description [Computes the two-literal clauses for a node with a zero + child, given the clauses for its other child and the label of the + node. Returns a pointer to a TclInfo structure if successful; NULL + otherwise.] + + SideEffects [None] + + SeeAlso [computeClauses] + +******************************************************************************/ +static DdTlcInfo * +computeClausesWithUniverse( + DdTlcInfo *Cres /* list of clauses for child */, + DdHalfWord label /* variable labeling the current node */, + short phase /* 0 if E child is zero; 1 if T child is zero */) +{ + DdHalfWord *Ccv = Cres->vars; /* variables of clauses for child */ + BitVector *Ccp = Cres->phases; /* phases of clauses for child */ + DdHalfWord *Vcv = NULL; /* pointer to the variables of the clauses for v */ + BitVector *Vcp = NULL; /* pointer to the phases of the clauses for v */ + DdTlcInfo *res = NULL; /* the set of clauses to be returned */ + int i; + + /* Initialize result. */ + res = tlcInfoAlloc(); + if (res == NULL) goto cleanup; + /* Count entries for new list and allocate accordingly. */ + for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2); + /* At this point, i is twice the number of clauses in the child's + ** list. We need four more entries for this node: 2 for the one-literal + ** clause for the label, and 2 for the sentinel. */ + Vcv = ABC_ALLOC(DdHalfWord,i+4); + if (Vcv == NULL) goto cleanup; + Vcp = bitVectorAlloc(i+4); + if (Vcp == NULL) goto cleanup; + res->vars = Vcv; + res->phases = Vcp; + /* Copy old list into new. */ + for (i = 0; !sentinelp(Ccv[i], Ccv[i+1]); i += 2) { + Vcv[i] = Ccv[i]; + Vcv[i+1] = Ccv[i+1]; + bitVectorSet(Vcp, i, bitVectorRead(Ccp, i)); + bitVectorSet(Vcp, i+1, bitVectorRead(Ccp, i+1)); + } + /* Add clause corresponding to label. */ + Vcv[i] = label; + bitVectorSet(Vcp, i, phase); + i++; + Vcv[i] = CUDD_MAXINDEX; + bitVectorSet(Vcp, i, 1); + i++; + /* Add sentinel. */ + Vcv[i] = 0; + Vcv[i+1] = 0; + bitVectorSet(Vcp, i, 0); + bitVectorSet(Vcp, i+1, 0); + return(res); -} /* end of ddFindEssentialRecur */ + cleanup: + /* Vcp is guaranteed to be NULL here. Hence, we do not try to free it. */ + if (Vcv != NULL) ABC_FREE(Vcv); + if (res != NULL) Cudd_tlcInfoFree(res); + + return(NULL); + +} /* end of computeClausesWithUniverse */ + + +/**Function******************************************************************** + + Synopsis [Returns an enpty set of clauses.] + + Description [Returns a pointer to an empty set of clauses if + successful; NULL otherwise. No bit vector for the phases is + allocated.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static DdTlcInfo * +emptyClauseSet(void) +{ + DdTlcInfo *eset; + + eset = ABC_ALLOC(DdTlcInfo,1); + if (eset == NULL) return(NULL); + eset->vars = ABC_ALLOC(DdHalfWord,2); + if (eset->vars == NULL) { + ABC_FREE(eset); + return(NULL); + } + /* Sentinel */ + eset->vars[0] = 0; + eset->vars[1] = 0; + eset->phases = NULL; /* does not matter */ + eset->cnt = 0; + return(eset); + +} /* end of emptyClauseSet */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the argument is the sentinel clause.] + + Description [Returns true iff the argument is the sentinel clause. + A sentinel clause has both variables equal to 0.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +sentinelp( + DdHalfWord var1, + DdHalfWord var2) +{ + return(var1 == 0 && var2 == 0); + +} /* end of sentinelp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the two arguments are identical clauses.] + + Description [Returns true iff the two arguments are identical + clauses. Since literals are sorted, we only need to compare + literals in the same position.] + + SideEffects [None] + + SeeAlso [beforep] + +******************************************************************************/ +static int +equalp( + DdHalfWord var1a, + short phase1a, + DdHalfWord var1b, + short phase1b, + DdHalfWord var2a, + short phase2a, + DdHalfWord var2b, + short phase2b) +{ + return(var1a == var2a && phase1a == phase2a && + var1b == var2b && phase1b == phase2b); + +} /* end of equalp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the first argument precedes the second in + the clause order.] + + Description [Returns true iff the first argument precedes the second + in the clause order. A clause precedes another if its first lieral + precedes the first literal of the other, or if the first literals + are the same, and its second literal precedes the second literal of + the other clause. A literal precedes another if it has a higher + index, of if it has the same index, but it has lower phase. Phase 0 + is the positive phase, and it is lower than Phase 1 (negative + phase).] + + SideEffects [None] + + SeeAlso [equalp] + +******************************************************************************/ +static int +beforep( + DdHalfWord var1a, + short phase1a, + DdHalfWord var1b, + short phase1b, + DdHalfWord var2a, + short phase2a, + DdHalfWord var2b, + short phase2b) +{ + return(var1a > var2a || (var1a == var2a && + (phase1a < phase2a || (phase1a == phase2a && + (var1b > var2b || (var1b == var2b && phase1b < phase2b)))))); + +} /* end of beforep */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff the argument is a one-literal clause.] + + Description [Returns true iff the argument is a one-literal clause. + A one-litaral clause has the constant FALSE as second literal. + Since the constant TRUE is never used, it is sufficient to test for + a constant.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +oneliteralp( + DdHalfWord var) +{ + return(var == CUDD_MAXINDEX); + +} /* end of oneliteralp */ + + +/**Function******************************************************************** + + Synopsis [Returns true iff either literal of a clause is in a set of + literals.] + + Description [Returns true iff either literal of a clause is in a set + of literals. The first four arguments specify the clause. The + remaining two arguments specify the literal set.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +impliedp( + DdHalfWord var1, + short phase1, + DdHalfWord var2, + short phase2, + BitVector *olv, + BitVector *olp) +{ + return((bitVectorRead(olv, var1) && + bitVectorRead(olp, var1) == phase1) || + (bitVectorRead(olv, var2) && + bitVectorRead(olp, var2) == phase2)); + +} /* end of impliedp */ + + +/**Function******************************************************************** + + Synopsis [Allocates a bit vector.] + + Description [Allocates a bit vector. The parameter size gives the + number of bits. This procedure allocates enough long's to hold the + specified number of bits. Returns a pointer to the allocated vector + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [bitVectorClear bitVectorFree] + +******************************************************************************/ +static BitVector * +bitVectorAlloc( + int size) +{ + int allocSize; + BitVector *vector; + + /* Find out how many long's we need. + ** There are sizeof(long) * 8 bits in a long. + ** The ceiling of the ratio of two integers m and n is given + ** by ((n-1)/m)+1. Putting all this together, we get... */ + allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1; + vector = ABC_ALLOC(BitVector, allocSize); + if (vector == NULL) return(NULL); + /* Clear the whole array. */ + (void) memset(vector, 0, allocSize * sizeof(BitVector)); + return(vector); + +} /* end of bitVectorAlloc */ + + +/**Function******************************************************************** + + Synopsis [Clears a bit vector.] + + Description [Clears a bit vector. The parameter size gives the + number of bits.] + + SideEffects [None] + + SeeAlso [bitVectorAlloc] + +******************************************************************************/ +DD_INLINE +static void +bitVectorClear( + BitVector *vector, + int size) +{ + int allocSize; + + /* Find out how many long's we need. + ** There are sizeof(long) * 8 bits in a long. + ** The ceiling of the ratio of two integers m and n is given + ** by ((n-1)/m)+1. Putting all this together, we get... */ + allocSize = ((size - 1) / (sizeof(BitVector) * 8)) + 1; + /* Clear the whole array. */ + (void) memset(vector, 0, allocSize * sizeof(BitVector)); + return; + +} /* end of bitVectorClear */ + + +/**Function******************************************************************** + + Synopsis [Frees a bit vector.] + + Description [Frees a bit vector.] + + SideEffects [None] + + SeeAlso [bitVectorAlloc] + +******************************************************************************/ +static void +bitVectorFree( + BitVector *vector) +{ + ABC_FREE(vector); + +} /* end of bitVectorFree */ + + +/**Function******************************************************************** + + Synopsis [Returns the i-th entry of a bit vector.] + + Description [Returns the i-th entry of a bit vector.] + + SideEffects [None] + + SeeAlso [bitVectorSet] + +******************************************************************************/ +DD_INLINE +static short +bitVectorRead( + BitVector *vector, + int i) +{ + int word, bit; + short result; + + if (vector == NULL) return((short) 0); + + word = i >> LOGBPL; + bit = i & (BPL - 1); + result = (short) ((vector[word] >> bit) & 1L); + return(result); + +} /* end of bitVectorRead */ + + +/**Function******************************************************************** + + Synopsis [Sets the i-th entry of a bit vector to a value.] + + Description [Sets the i-th entry of a bit vector to a value.] + + SideEffects [None] + + SeeAlso [bitVectorRead] + +******************************************************************************/ +DD_INLINE +static void +bitVectorSet( + BitVector * vector, + int i, + short val) +{ + int word, bit; + + word = i >> LOGBPL; + bit = i & (BPL - 1); + vector[word] &= ~(1L << bit); + vector[word] |= (((long) val) << bit); + +} /* end of bitVectorSet */ + + +/**Function******************************************************************** + + Synopsis [Allocates a DdTlcInfo Structure.] + + Description [Returns a pointer to a DdTlcInfo Structure if successful; + NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_tlcInfoFree] + +******************************************************************************/ +static DdTlcInfo * +tlcInfoAlloc(void) +{ + DdTlcInfo *res = ABC_ALLOC(DdTlcInfo,1); + if (res == NULL) return(NULL); + res->vars = NULL; + res->phases = NULL; + res->cnt = 0; + return(res); + +} /* end of tlcInfoAlloc */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddExact.c b/src/bdd/cudd/cuddExact.c index b9ed4676..19fcbcd4 100644 --- a/src/bdd/cudd/cuddExact.c +++ b/src/bdd/cudd/cuddExact.c @@ -7,36 +7,63 @@ Synopsis [Functions for exact variable reordering.] Description [External procedures included in this file: - <ul> - </ul> - Internal procedures included in this module: - <ul> - <li> cuddExact() - </ul> - Static procedures included in this module: - <ul> + <ul> + </ul> + Internal procedures included in this module: + <ul> + <li> cuddExact() + </ul> + Static procedures included in this module: + <ul> <li> getMaxBinomial() - <li> gcd() + <li> gcd() <li> getMatrix() - <li> freeMatrix() + <li> freeMatrix() <li> getLevelKeys() <li> ddShuffle() <li> ddSiftUp() - <li> updateUB() - <li> ddCountRoots() - <li> ddClearGlobal() - <li> computeLB() - <li> updateEntry() - <li> pushDown() - <li> initSymmInfo() + <li> updateUB() + <li> ddCountRoots() + <li> ddClearGlobal() + <li> computeLB() + <li> updateEntry() + <li> pushDown() + <li> initSymmInfo() </ul>] Author [Cheng Hua, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -46,6 +73,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -64,7 +92,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddExact.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddExact.c,v 1.28 2009/02/19 16:19:19 fabio Exp $"; #endif #ifdef DD_STATS @@ -81,21 +109,20 @@ static int ddTotalShuffles; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int getMaxBinomial ARGS((int n)); -static int gcd ARGS((int x, int y)); -static DdHalfWord ** getMatrix ARGS((int rows, int cols)); -static void freeMatrix ARGS((DdHalfWord **matrix)); -static int getLevelKeys ARGS((DdManager *table, int l)); -static int ddShuffle ARGS((DdManager *table, DdHalfWord *permutation, int lower, int upper)); -static int ddSiftUp ARGS((DdManager *table, int x, int xLow)); -static int updateUB ARGS((DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper)); -static int ddCountRoots ARGS((DdManager *table, int lower, int upper)); -static void ddClearGlobal ARGS((DdManager *table, int lower, int maxlevel)); -static int computeLB ARGS((DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level)); -static int updateEntry ARGS((DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper)); -static void pushDown ARGS((DdHalfWord *order, int j, int level)); -static DdHalfWord * initSymmInfo ARGS((DdManager *table, int lower, int upper)); -static int checkSymmInfo ARGS((DdManager *table, DdHalfWord *symmInfo, int index, int level)); +static int getMaxBinomial (int n); +static DdHalfWord ** getMatrix (int rows, int cols); +static void freeMatrix (DdHalfWord **matrix); +static int getLevelKeys (DdManager *table, int l); +static int ddShuffle (DdManager *table, DdHalfWord *permutation, int lower, int upper); +static int ddSiftUp (DdManager *table, int x, int xLow); +static int updateUB (DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper); +static int ddCountRoots (DdManager *table, int lower, int upper); +static void ddClearGlobal (DdManager *table, int lower, int maxlevel); +static int computeLB (DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level); +static int updateEntry (DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper); +static void pushDown (DdHalfWord *order, int j, int level); +static DdHalfWord * initSymmInfo (DdManager *table, int lower, int upper); +static int checkSymmInfo (DdManager *table, DdHalfWord *symmInfo, int index, int level); /**AutomaticEnd***************************************************************/ @@ -131,7 +158,7 @@ cuddExact( int k, i, j; int maxBinomial, oldSubsets, newSubsets; int subsetCost; - int size; /* number of variables to be reordered */ + int size; /* number of variables to be reordered */ int unused, nvars, level, result; int upperBound, lowerBound, cost; int roots; @@ -152,13 +179,13 @@ cuddExact( /* Restrict the range to be reordered by excluding unused variables ** at the two ends. */ while (table->subtables[lower].keys == 1 && - table->vars[table->invperm[lower]]->ref == 1 && - lower < upper) - lower++; + table->vars[table->invperm[lower]]->ref == 1 && + lower < upper) + lower++; while (table->subtables[upper].keys == 1 && - table->vars[table->invperm[upper]]->ref == 1 && - lower < upper) - upper--; + table->vars[table->invperm[upper]]->ref == 1 && + lower < upper) + upper--; if (lower == upper) return(1); /* trivial problem */ /* Apply symmetric sifting to get a good upper bound and to extract @@ -179,9 +206,9 @@ cuddExact( ** used to compute maxBinomial. */ unused = 0; for (i = lower + 1; i < upper; i++) { - if (table->subtables[i].keys == 1 && - table->vars[table->invperm[i]]->ref == 1) - unused++; + if (table->subtables[i].keys == 1 && + table->vars[table->invperm[i]]->ref == 1) + unused++; } /* Find the maximum number of subsets we may have to store. */ @@ -218,65 +245,65 @@ cuddExact( */ oldSubsets = 1; for (i = 0; i < size; i++) { - oldOrder[0][i] = bestOrder[i] = (DdHalfWord) table->invperm[i+lower]; + oldOrder[0][i] = bestOrder[i] = (DdHalfWord) table->invperm[i+lower]; } subsetCost = table->constants.keys; for (i = upper + 1; i < nvars; i++) - subsetCost += getLevelKeys(table,i); + subsetCost += getLevelKeys(table,i); oldCost[0] = subsetCost; /* The upper bound is initialized to the current size of the BDDs. */ upperBound = table->keys - table->isolated; /* Now consider subsets of increasing size. */ for (k = 1; k <= size; k++) { -#if DD_STATS - (void) fprintf(table->out,"Processing subsets of size %d\n", k); - fflush(table->out); +#ifdef DD_STATS + (void) fprintf(table->out,"Processing subsets of size %d\n", k); + fflush(table->out); #endif - newSubsets = 0; - level = size - k; /* offset of first bottom variable */ - - for (i = 0; i < oldSubsets; i++) { /* for each subset of size k-1 */ - order = oldOrder[i]; - cost = oldCost[i]; - lowerBound = computeLB(table, order, roots, cost, lower, upper, - level); - if (lowerBound >= upperBound) - continue; - /* Impose new order. */ - result = ddShuffle(table, order, lower, upper); - if (result == 0) goto cuddExactOutOfMem; - upperBound = updateUB(table,upperBound,bestOrder,lower,upper); - /* For each top bottom variable. */ - for (j = level; j >= 0; j--) { - /* Skip unused variables. */ - if (table->subtables[j+lower-1].keys == 1 && - table->vars[table->invperm[j+lower-1]]->ref == 1) continue; - /* Find cost under this order. */ - subsetCost = cost + getLevelKeys(table, lower + level); - newSubsets = updateEntry(table, order, level, subsetCost, - newOrder, newCost, newSubsets, mask, - lower, upper); - if (j == 0) - break; - if (checkSymmInfo(table, symmInfo, order[j-1], level) == 0) - continue; - pushDown(order,j-1,level); - /* Impose new order. */ - result = ddShuffle(table, order, lower, upper); - if (result == 0) goto cuddExactOutOfMem; - upperBound = updateUB(table,upperBound,bestOrder,lower,upper); - } /* for each bottom variable */ - } /* for each subset of size k */ - - /* New orders become old orders in preparation for next iteration. */ - tmpOrder = oldOrder; tmpCost = oldCost; - oldOrder = newOrder; oldCost = newCost; - newOrder = tmpOrder; newCost = tmpCost; + newSubsets = 0; + level = size - k; /* offset of first bottom variable */ + + for (i = 0; i < oldSubsets; i++) { /* for each subset of size k-1 */ + order = oldOrder[i]; + cost = oldCost[i]; + lowerBound = computeLB(table, order, roots, cost, lower, upper, + level); + if (lowerBound >= upperBound) + continue; + /* Impose new order. */ + result = ddShuffle(table, order, lower, upper); + if (result == 0) goto cuddExactOutOfMem; + upperBound = updateUB(table,upperBound,bestOrder,lower,upper); + /* For each top bottom variable. */ + for (j = level; j >= 0; j--) { + /* Skip unused variables. */ + if (table->subtables[j+lower-1].keys == 1 && + table->vars[table->invperm[j+lower-1]]->ref == 1) continue; + /* Find cost under this order. */ + subsetCost = cost + getLevelKeys(table, lower + level); + newSubsets = updateEntry(table, order, level, subsetCost, + newOrder, newCost, newSubsets, mask, + lower, upper); + if (j == 0) + break; + if (checkSymmInfo(table, symmInfo, order[j-1], level) == 0) + continue; + pushDown(order,j-1,level); + /* Impose new order. */ + result = ddShuffle(table, order, lower, upper); + if (result == 0) goto cuddExactOutOfMem; + upperBound = updateUB(table,upperBound,bestOrder,lower,upper); + } /* for each bottom variable */ + } /* for each subset of size k */ + + /* New orders become old orders in preparation for next iteration. */ + tmpOrder = oldOrder; tmpCost = oldCost; + oldOrder = newOrder; oldCost = newCost; + newOrder = tmpOrder; newCost = tmpCost; #ifdef DD_STATS - ddTotalSubsets += newSubsets; + ddTotalSubsets += newSubsets; #endif - oldSubsets = newSubsets; + oldSubsets = newSubsets; } result = ddShuffle(table, bestOrder, lower, upper); if (result == 0) goto cuddExactOutOfMem; @@ -285,9 +312,9 @@ cuddExact( (void) fprintf(table->out,"\n"); #endif (void) fprintf(table->out,"#:S_EXACT %8d: total subsets\n", - ddTotalSubsets); + ddTotalSubsets); (void) fprintf(table->out,"#:H_EXACT %8d: total shuffles", - ddTotalShuffles); + ddTotalShuffles); #endif freeMatrix(newOrder); @@ -320,9 +347,12 @@ cuddExactOutOfMem: Description [Computes the maximum value of (n choose k) for a given n. The maximum value occurs for k = n/2 when n is even, or k = - (n-1)/2 when n is odd. The algorithm used in this procedure is - quite inefficient, but it avoids intermediate overflow problems. - Returns the computed value if successful; -1 otherwise.] + (n-1)/2 when n is odd. The algorithm used in this procedure avoids + intermediate overflow problems. It is based on the identity + <pre> + binomial(n,k) = n/k * binomial(n-1,k-1). + </pre> + Returns the computed value if successful; -1 if out of range.] SideEffects [None] @@ -331,42 +361,24 @@ cuddExactOutOfMem: ******************************************************************************/ static int getMaxBinomial( - int n) + int n) { - int *numerator; - int i, j, k, y, g, result; - - k = (n & ~1) >> 1; - - numerator = ABC_ALLOC(int,k); - if (numerator == NULL) return(-1); - - for (i = 0; i < k; i++) - numerator[i] = n - i; - - for (i = k; i > 1; i--) { - y = i; - for (j = 0; j < k; j++) { - if (numerator[j] == 1) continue; - g = gcd(numerator[j], y); - if (g != 1) { - numerator[j] /= g; - if (y == g) break; - y /= g; - } - } - } + double i, j, result; + + if (n < 0 || n > 33) return(-1); /* error */ + if (n < 2) return(1); - result = 1; - for (i = 0; i < k; i++) - result *= numerator[i]; + for (result = (double)((n+3)/2), i = result+1, j=2; i <= n; i++, j++) { + result *= i; + result /= j; + } - ABC_FREE(numerator); - return(result); + return((int)result); -} /* end of getMaxBinomial */ +} /* end of getMaxBinomial */ +#if 0 /**Function******************************************************************** Synopsis [Returns the gcd of two integers.] @@ -393,33 +405,34 @@ gcd( if (y == 0) return(x); a = x; b = y; lsbMask = 1; - + /* Here both a and b are != 0. The iteration maintains this invariant. ** Hence, we only need to check for when they become equal. */ while (a != b) { - if (a & lsbMask) { - if (b & lsbMask) { /* both odd */ - if (a < b) { - b = (b - a) >> 1; + if (a & lsbMask) { + if (b & lsbMask) { /* both odd */ + if (a < b) { + b = (b - a) >> 1; + } else { + a = (a - b) >> 1; + } + } else { /* a odd, b even */ + b >>= 1; + } } else { - a = (a - b) >> 1; - } - } else { /* a odd, b even */ - b >>= 1; - } - } else { - if (b & lsbMask) { /* a even, b odd */ - a >>= 1; - } else { /* both even */ - lsbMask <<= 1; + if (b & lsbMask) { /* a even, b odd */ + a >>= 1; + } else { /* both even */ + lsbMask <<= 1; + } } } - } return(a); } /* end of gcd */ +#endif /**Function******************************************************************** @@ -446,9 +459,12 @@ getMatrix( matrix = ABC_ALLOC(DdHalfWord *, rows); if (matrix == NULL) return(NULL); matrix[0] = ABC_ALLOC(DdHalfWord, cols*rows); - if (matrix[0] == NULL) return(NULL); + if (matrix[0] == NULL) { + ABC_FREE(matrix); + return(NULL); + } for (i = 1; i < rows; i++) { - matrix[i] = matrix[i-1] + cols; + matrix[i] = matrix[i-1] + cols; } return(matrix); @@ -528,18 +544,20 @@ ddShuffle( int lower, int upper) { - DdHalfWord index; - int level; - int position; - int numvars; - int result; + DdHalfWord index; + int level; + int position; +#if 0 + int numvars; +#endif + int result; #ifdef DD_STATS - long localTime; - int initialSize; + long localTime; + int initialSize; #ifdef DD_VERBOSE - int finalSize; + int finalSize; #endif - int previousSize; + int previousSize; #endif #ifdef DD_STATS @@ -547,24 +565,24 @@ ddShuffle( initialSize = table->keys - table->isolated; #endif +#if 0 numvars = table->size; -#if 0 (void) fprintf(table->out,"%d:", ddTotalShuffles); for (level = 0; level < numvars; level++) { - (void) fprintf(table->out," %d", table->invperm[level]); + (void) fprintf(table->out," %d", table->invperm[level]); } (void) fprintf(table->out,"\n"); #endif for (level = 0; level <= upper - lower; level++) { - index = permutation[level]; - position = table->perm[index]; + index = permutation[level]; + position = table->perm[index]; #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - result = ddSiftUp(table,position,level+lower); - if (!result) return(0); + result = ddSiftUp(table,position,level+lower); + if (!result) return(0); } #ifdef DD_STATS @@ -572,11 +590,11 @@ ddShuffle( #ifdef DD_VERBOSE finalSize = table->keys - table->isolated; if (finalSize < initialSize) { - (void) fprintf(table->out,"-"); + (void) fprintf(table->out,"-"); } else if (finalSize > initialSize) { - (void) fprintf(table->out,"+"); + (void) fprintf(table->out,"+"); } else { - (void) fprintf(table->out,"="); + (void) fprintf(table->out,"="); } if ((ddTotalShuffles & 63) == 0) (void) fprintf(table->out,"\n"); fflush(table->out); @@ -612,12 +630,12 @@ ddSiftUp( y = cuddNextLow(table,x); while (y >= xLow) { - size = cuddSwapInPlace(table,y,x); - if (size == 0) { - return(0); - } - x = y; - y = cuddNextLow(table,x); + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); } return(1); @@ -649,14 +667,14 @@ updateUB( if (newBound < oldBound) { #ifdef DD_STATS - (void) fprintf(table->out,"New upper bound = %d\n", newBound); - fflush(table->out); + (void) fprintf(table->out,"New upper bound = %d\n", newBound); + fflush(table->out); #endif - for (i = lower; i <= upper; i++) - bestOrder[i-lower] = (DdHalfWord) table->invperm[i]; - return(newBound); + for (i = lower; i <= upper; i++) + bestOrder[i-lower] = (DdHalfWord) table->invperm[i]; + return(newBound); } else { - return(oldBound); + return(oldBound); } } /* end of updateUB */ @@ -693,36 +711,36 @@ ddCountRoots( int maxlevel = lower; for (i = lower; i <= upper; i++) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; - for (j = 0; j < slots; j++) { - f = nodelist[j]; - while (f != sentinel) { - /* A node is a root of the DAG if it cannot be - ** reached by nodes above it. If a node was never - ** reached during the previous depth-first searches, - ** then it is a root, and we start a new depth-first - ** search from it. - */ - if (!Cudd_IsComplement(f->next)) { - if (f != table->vars[f->index]) { - roots++; + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + /* A node is a root of the DAG if it cannot be + ** reached by nodes above it. If a node was never + ** reached during the previous depth-first searches, + ** then it is a root, and we start a new depth-first + ** search from it. + */ + if (!Cudd_IsComplement(f->next)) { + if (f != table->vars[f->index]) { + roots++; + } + } + if (!Cudd_IsConstant(cuddT(f))) { + cuddT(f)->next = Cudd_Complement(cuddT(f)->next); + if (table->perm[cuddT(f)->index] > maxlevel) + maxlevel = table->perm[cuddT(f)->index]; + } + if (!Cudd_IsConstant(cuddE(f))) { + Cudd_Regular(cuddE(f))->next = + Cudd_Complement(Cudd_Regular(cuddE(f))->next); + if (table->perm[Cudd_Regular(cuddE(f))->index] > maxlevel) + maxlevel = table->perm[Cudd_Regular(cuddE(f))->index]; + } + f = Cudd_Regular(f->next); } } - if (!Cudd_IsConstant(cuddT(f))) { - cuddT(f)->next = Cudd_Complement(cuddT(f)->next); - if (table->perm[cuddT(f)->index] > maxlevel) - maxlevel = table->perm[cuddT(f)->index]; - } - if (!Cudd_IsConstant(cuddE(f))) { - Cudd_Regular(cuddE(f))->next = - Cudd_Complement(Cudd_Regular(cuddE(f))->next); - if (table->perm[Cudd_Regular(cuddE(f))->index] > maxlevel) - maxlevel = table->perm[Cudd_Regular(cuddE(f))->index]; - } - f = Cudd_Regular(f->next); - } - } } ddClearGlobal(table, lower, maxlevel); @@ -758,16 +776,16 @@ ddClearGlobal( int slots; for (i = lower; i <= maxlevel; i++) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; - for (j = 0; j < slots; j++) { - f = nodelist[j]; - while (f != sentinel) { - f->next = Cudd_Regular(f->next); - f = f->next; + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + f->next = Cudd_Regular(f->next); + f = f->next; + } } } - } } /* end of ddClearGlobal */ @@ -793,13 +811,13 @@ ddClearGlobal( ******************************************************************************/ static int computeLB( - DdManager * table /* manager */, - DdHalfWord * order /* optimal order for the subset */, - int roots /* roots between lower and upper */, - int cost /* minimum cost for the subset */, - int lower /* lower level to be reordered */, - int upper /* upper level to be reordered */, - int level /* offset for the current top bottom var */ + DdManager * table /* manager */, + DdHalfWord * order /* optimal order for the subset */, + int roots /* roots between lower and upper */, + int cost /* minimum cost for the subset */, + int lower /* lower level to be reordered */, + int upper /* upper level to be reordered */, + int level /* offset for the current top bottom var */ ) { int i; @@ -813,28 +831,28 @@ computeLB( ** Add their sizes to the lower bound. */ for (i = 0; i < lower; i++) { - lb += getLevelKeys(table,i); + lb += getLevelKeys(table,i); } /* If a variable is in the support, then there is going ** to be at least one node labeled by that variable. */ for (i = lower; i <= lower+level; i++) { - support = table->subtables[i].keys > 1 || - table->vars[order[i-lower]]->ref > 1; - lb1 += support; + support = table->subtables[i].keys > 1 || + table->vars[order[i-lower]]->ref > 1; + lb1 += support; } /* Estimate the number of nodes required to connect the roots to ** the nodes in the bottom part. */ if (lower+level+1 < table->size) { - if (lower+level < upper) - ref = table->vars[order[level+1]]->ref; - else - ref = table->vars[table->invperm[upper+1]]->ref; - lb2 = table->subtables[lower+level+1].keys - - (ref > (DdHalfWord) 1) - roots; + if (lower+level < upper) + ref = table->vars[order[level+1]]->ref; + else + ref = table->vars[table->invperm[upper+1]]->ref; + lb2 = table->subtables[lower+level+1].keys - + (ref > (DdHalfWord) 1) - roots; } else { - lb2 = 0; + lb2 = 0; } lb += lb1 > lb2 ? lb1 : lb2; @@ -876,25 +894,25 @@ updateEntry( /* Build a mask that says what variables are in this subset. */ for (i = lower; i <= upper; i++) - mask[table->invperm[i]] = 0; + mask[table->invperm[i]] = 0; for (i = level; i < size; i++) - mask[order[i]] = 1; + mask[order[i]] = 1; /* Check each subset until a match is found or all subsets are examined. */ for (i = 0; i < subsets; i++) { - DdHalfWord *subset = orders[i]; - for (j = level; j < size; j++) { - if (mask[subset[j]] == 0) - break; - } - if (j == size) /* no mismatches: success */ - break; + DdHalfWord *subset = orders[i]; + for (j = level; j < size; j++) { + if (mask[subset[j]] == 0) + break; + } + if (j == size) /* no mismatches: success */ + break; } - if (i == subsets || cost < costs[i]) { /* add or replace */ - for (j = 0; j < size; j++) - orders[i][j] = order[j]; - costs[i] = cost; - subsets += (i == subsets); + if (i == subsets || cost < costs[i]) { /* add or replace */ + for (j = 0; j < size; j++) + orders[i][j] = order[j]; + costs[i] = cost; + subsets += (i == subsets); } return(subsets); @@ -923,7 +941,7 @@ pushDown( tmp = order[j]; for (i = j; i < level; i++) { - order[i] = order[i+1]; + order[i] = order[i+1]; } order[level] = tmp; return; @@ -963,10 +981,10 @@ initSymmInfo( if (symmInfo == NULL) return(NULL); for (level = lower; level <= upper; level++) { - index = table->invperm[level]; - next = table->subtables[level].next; - nextindex = table->invperm[next]; - symmInfo[index] = nextindex; + index = table->invperm[level]; + next = table->subtables[level].next; + nextindex = table->invperm[next]; + symmInfo[index] = nextindex; } return(symmInfo); @@ -997,13 +1015,14 @@ checkSymmInfo( i = symmInfo[index]; while (i != index) { - if (index < i && table->perm[i] <= level) - return(0); - i = symmInfo[i]; + if (index < i && table->perm[i] <= level) + return(0); + i = symmInfo[i]; } return(1); } /* end of checkSymmInfo */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddExport.c b/src/bdd/cudd/cuddExport.c index cccf2465..255baabf 100644 --- a/src/bdd/cudd/cuddExport.c +++ b/src/bdd/cudd/cuddExport.c @@ -7,31 +7,58 @@ Synopsis [Export functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_DumpBlif() - <li> Cudd_DumpBlifBody() - <li> Cudd_DumpDot() - <li> Cudd_DumpDaVinci() - <li> Cudd_DumpDDcal() - <li> Cudd_DumpFactoredForm() - </ul> - Internal procedures included in this module: - <ul> - </ul> - Static procedures included in this module: - <ul> - <li> ddDoDumpBlif() - <li> ddDoDumpDaVinci() - <li> ddDoDumpDDcal() - <li> ddDoDumpFactoredForm() - </ul>] + <ul> + <li> Cudd_DumpBlif() + <li> Cudd_DumpBlifBody() + <li> Cudd_DumpDot() + <li> Cudd_DumpDaVinci() + <li> Cudd_DumpDDcal() + <li> Cudd_DumpFactoredForm() + </ul> + Internal procedures included in this module: + <ul> + </ul> + Static procedures included in this module: + <ul> + <li> ddDoDumpBlif() + <li> ddDoDumpDaVinci() + <li> ddDoDumpDDcal() + <li> ddDoDumpFactoredForm() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -41,6 +68,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -58,7 +86,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddExport.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddExport.c,v 1.22 2009/03/08 02:49:02 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -71,10 +99,10 @@ static char rcsid[] DD_UNUSED = "$Id: cuddExport.c,v 1.1.1.1 2003/02/24 22:23:52 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int ddDoDumpBlif ARGS((DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names)); -static int ddDoDumpDaVinci ARGS((DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, long mask)); -static int ddDoDumpDDcal ARGS((DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, long mask)); -static int ddDoDumpFactoredForm ARGS((DdManager *dd, DdNode *f, FILE *fp, char **names)); +static int ddDoDumpBlif (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, int mv); +static int ddDoDumpDaVinci (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, ptruint mask); +static int ddDoDumpDDcal (DdManager *dd, DdNode *f, FILE *fp, st_table *visited, char **names, ptruint mask); +static int ddDoDumpFactoredForm (DdManager *dd, DdNode *f, FILE *fp, char **names); /**AutomaticEnd***************************************************************/ @@ -112,20 +140,21 @@ Cudd_DumpBlif( char ** inames /* array of input names (or NULL) */, char ** onames /* array of output names (or NULL) */, char * mname /* model name (or NULL) */, - FILE * fp /* pointer to the dump file */) + FILE * fp /* pointer to the dump file */, + int mv /* 0: blif, 1: blif-MV */) { - DdNode *support = NULL; - DdNode *scan; - int *sorted = NULL; - int nvars = dd->size; - int retval; - int i; + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + int retval; + int i; /* Build a bit array with the support of f. */ sorted = ABC_ALLOC(int,nvars); if (sorted == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - goto failure; + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; } for (i = 0; i < nvars; i++) sorted[i] = 0; @@ -135,28 +164,31 @@ Cudd_DumpBlif( cuddRef(support); scan = support; while (!cuddIsConstant(scan)) { - sorted[scan->index] = 1; - scan = cuddT(scan); + sorted[scan->index] = 1; + scan = cuddT(scan); } Cudd_RecursiveDeref(dd,support); support = NULL; /* so that we do not try to free it in case of failure */ /* Write the header (.model .inputs .outputs). */ if (mname == NULL) { - retval = fprintf(fp,".model DD\n.inputs"); + retval = fprintf(fp,".model DD\n.inputs"); } else { - retval = fprintf(fp,".model %s\n.inputs",mname); + retval = fprintf(fp,".model %s\n.inputs",mname); + } + if (retval == EOF) { + ABC_FREE(sorted); + return(0); } - if (retval == EOF) return(0); /* Write the input list by scanning the support array. */ for (i = 0; i < nvars; i++) { if (sorted[i]) { - if (inames == NULL) { - retval = fprintf(fp," %d", i); - } else { - retval = fprintf(fp," %s", inames[i]); - } + if (inames == NULL) { + retval = fprintf(fp," %d", i); + } else { + retval = fprintf(fp," %s", inames[i]); + } if (retval == EOF) goto failure; } } @@ -167,17 +199,17 @@ Cudd_DumpBlif( retval = fprintf(fp,"\n.outputs"); if (retval == EOF) goto failure; for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp," f%d", i); - } else { - retval = fprintf(fp," %s", onames[i]); - } - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp," f%d", i); + } else { + retval = fprintf(fp," %s", onames[i]); + } + if (retval == EOF) goto failure; } retval = fprintf(fp,"\n"); if (retval == EOF) goto failure; - retval = Cudd_DumpBlifBody(dd, n, f, inames, onames, fp); + retval = Cudd_DumpBlifBody(dd, n, f, inames, onames, fp, mv); if (retval == 0) goto failure; /* Write trailer and return. */ @@ -199,11 +231,12 @@ failure: Synopsis [Writes a blif body representing the argument BDDs.] Description [Writes a blif body 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., + 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_DumpBlif does not close the file: This is the - caller responsibility. Cudd_DumpBlif uses a minimal unique subset of + 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 @@ -211,7 +244,7 @@ failure: SideEffects [None] - SeeAlso [Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal + SeeAlso [Cudd_DumpBlif Cudd_DumpDot Cudd_PrintDebug Cudd_DumpDDcal Cudd_DumpDaVinci Cudd_DumpFactoredForm] ******************************************************************************/ @@ -222,11 +255,12 @@ Cudd_DumpBlifBody( DdNode ** f /* array of output nodes to be dumped */, char ** inames /* array of input names (or NULL) */, char ** onames /* array of output names (or NULL) */, - FILE * fp /* pointer to the dump file */) + FILE * fp /* pointer to the dump file */, + int mv /* 0: blif, 1: blif-MV */) { st_table *visited = NULL; - int retval; - int i; + int retval; + int i; /* Initialize symbol table for visited nodes. */ visited = st_init_table(st_ptrcmp, st_ptrhash); @@ -234,8 +268,8 @@ Cudd_DumpBlifBody( /* Call the function that really gets the job done. */ for (i = 0; i < n; i++) { - retval = ddDoDumpBlif(dd,Cudd_Regular(f[i]),fp,visited,inames); - if (retval == 0) goto failure; + retval = ddDoDumpBlif(dd,Cudd_Regular(f[i]),fp,visited,inames,mv); + if (retval == 0) goto failure; } /* To account for the possible complement on the root, @@ -243,28 +277,28 @@ Cudd_DumpBlifBody( ** the multiplexer representing the top node. */ for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp, + if (onames == NULL) { + retval = fprintf(fp, #if SIZEOF_VOID_P == 8 - ".names %lx f%d\n", (unsigned long) f[i] / (unsigned long) sizeof(DdNode), i); + ".names %lx f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); #else - ".names %x f%d\n", (unsigned) f[i] / (unsigned) sizeof(DdNode), i); + ".names %x f%d\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), i); #endif - } else { - retval = fprintf(fp, + } else { + retval = fprintf(fp, #if SIZEOF_VOID_P == 8 - ".names %lx %s\n", (unsigned long) f[i] / (unsigned long) sizeof(DdNode), onames[i]); + ".names %lx %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]); #else - ".names %x %s\n", (unsigned) f[i] / (unsigned) sizeof(DdNode), onames[i]); + ".names %x %s\n", (ptruint) f[i] / (ptruint) sizeof(DdNode), onames[i]); #endif - } - if (retval == EOF) goto failure; - if (Cudd_IsComplement(f[i])) { - retval = fprintf(fp,"0 1\n"); - } else { - retval = fprintf(fp,"1 1\n"); - } - if (retval == EOF) goto failure; + } + if (retval == EOF) goto failure; + if (Cudd_IsComplement(f[i])) { + retval = fprintf(fp,"%s0 1\n", mv ? ".def 0\n" : ""); + } else { + retval = fprintf(fp,"%s1 1\n", mv ? ".def 0\n" : ""); + } + if (retval == EOF) goto failure; } st_free_table(visited); @@ -315,23 +349,23 @@ Cudd_DumpDot( char ** onames /* array of output names (or NULL) */, FILE * fp /* pointer to the dump file */) { - DdNode *support = NULL; - DdNode *scan; - int *sorted = NULL; - int nvars = dd->size; + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; st_table *visited = NULL; st_generator *gen = NULL; - int retval; - int i, j; - int slots; - DdNodePtr *nodelist; - long refAddr, diff, mask; + int retval; + int i, j; + int slots; + DdNodePtr *nodelist; + long refAddr, diff, mask; /* Build a bit array with the support of f. */ sorted = ABC_ALLOC(int,nvars); if (sorted == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - goto failure; + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; } for (i = 0; i < nvars; i++) sorted[i] = 0; @@ -341,8 +375,8 @@ Cudd_DumpDot( cuddRef(support); scan = support; while (!cuddIsConstant(scan)) { - sorted[scan->index] = 1; - scan = cuddT(scan); + sorted[scan->index] = 1; + scan = cuddT(scan); } Cudd_RecursiveDeref(dd,support); support = NULL; /* so that we do not try to free it in case of failure */ @@ -353,8 +387,8 @@ Cudd_DumpDot( /* Collect all the nodes of this DD in the symbol table. */ for (i = 0; i < n; i++) { - retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); - if (retval == 0) goto failure; + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; } /* Find how many most significant hex digits are identical @@ -373,22 +407,22 @@ Cudd_DumpDot( diff = 0; gen = st_init_gen(visited); if (gen == NULL) goto failure; - while (st_gen(gen, (const char **) &scan, NULL)) { - diff |= refAddr ^ (long) scan; + while (st_gen(gen, (const char **)&scan, NULL)) { + diff |= refAddr ^ (long) scan; } st_free_gen(gen); gen = NULL; /* Choose the mask. */ for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { - mask = (1 << i) - 1; - if (diff <= mask) break; + mask = (1 << i) - 1; + if (diff <= mask) break; } /* Write the header and the global attributes. */ retval = fprintf(fp,"digraph \"DD\" {\n"); if (retval == EOF) return(0); retval = fprintf(fp, - "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); + "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); if (retval == EOF) return(0); /* Write the input name subgraph by scanning the support array. */ @@ -403,11 +437,11 @@ Cudd_DumpDot( if (retval == EOF) goto failure; for (i = 0; i < nvars; i++) { if (sorted[dd->invperm[i]]) { - if (inames == NULL || inames[dd->invperm[i]] == NULL) { - retval = fprintf(fp,"\" %d \" -> ", dd->invperm[i]); - } else { - retval = fprintf(fp,"\" %s \" -> ", inames[dd->invperm[i]]); - } + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"\" %d \" -> ", dd->invperm[i]); + } else { + retval = fprintf(fp,"\" %s \" -> ", inames[dd->invperm[i]]); + } if (retval == EOF) goto failure; } } @@ -418,63 +452,66 @@ Cudd_DumpDot( retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); if (retval == EOF) goto failure; for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp,"\"F%d\"", i); - } else { - retval = fprintf(fp,"\" %s \"", onames[i]); - } - if (retval == EOF) goto failure; - if (i == n - 1) { - retval = fprintf(fp,"; }\n"); - } else { - retval = fprintf(fp," -> "); - } - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + if (i == n - 1) { + retval = fprintf(fp,"; }\n"); + } else { + retval = fprintf(fp," -> "); + } + if (retval == EOF) goto failure; } /* Write rank info: All nodes with the same index have the same rank. */ for (i = 0; i < nvars; i++) { if (sorted[dd->invperm[i]]) { - retval = fprintf(fp,"{ rank = same; "); - if (retval == EOF) goto failure; - if (inames == NULL || inames[dd->invperm[i]] == NULL) { - retval = fprintf(fp,"\" %d \";\n", dd->invperm[i]); - } else { - retval = fprintf(fp,"\" %s \";\n", inames[dd->invperm[i]]); - } + retval = fprintf(fp,"{ rank = same; "); if (retval == EOF) goto failure; - nodelist = dd->subtables[i].nodelist; - slots = dd->subtables[i].slots; - for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode)); + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"\" %d \";\n", dd->invperm[i]); + } else { + retval = fprintf(fp,"\" %s \";\n", inames[dd->invperm[i]]); + } if (retval == EOF) goto failure; + nodelist = dd->subtables[i].nodelist; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } } - scan = scan->next; - } + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; } - retval = fprintf(fp,"}\n"); - if (retval == EOF) goto failure; - } } /* All constants have the same rank. */ retval = fprintf(fp, - "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); + "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); if (retval == EOF) goto failure; nodelist = dd->constants.nodelist; slots = dd->constants.slots; for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode)); - if (retval == EOF) goto failure; + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; } - scan = scan->next; - } } retval = fprintf(fp,"}\n}\n"); if (retval == EOF) goto failure; @@ -482,69 +519,76 @@ Cudd_DumpDot( /* Write edge info. */ /* Edges from the output nodes. */ for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp,"\"F%d\"", i); - } else { - retval = fprintf(fp,"\" %s \"", onames[i]); - } - if (retval == EOF) goto failure; - /* Account for the possible complement on the root. */ - if (Cudd_IsComplement(f[i])) { - retval = fprintf(fp," -> \"%lx\" [style = dotted];\n", - (mask & (long) f[i]) / sizeof(DdNode)); - } else { - retval = fprintf(fp," -> \"%lx\" [style = solid];\n", - (mask & (long) f[i]) / sizeof(DdNode)); - } - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + /* Account for the possible complement on the root. */ + if (Cudd_IsComplement(f[i])) { + retval = fprintf(fp," -> \"%p\" [style = dotted];\n", + (void *) ((mask & (ptrint) f[i]) / sizeof(DdNode))); + } else { + retval = fprintf(fp," -> \"%p\" [style = solid];\n", + (void *) ((mask & (ptrint) f[i]) / sizeof(DdNode))); + } + if (retval == EOF) goto failure; } /* Edges from internal nodes. */ for (i = 0; i < nvars; i++) { if (sorted[dd->invperm[i]]) { - nodelist = dd->subtables[i].nodelist; - slots = dd->subtables[i].slots; - for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp, - "\"%lx\" -> \"%lx\";\n", - (mask & (long) scan) / sizeof(DdNode), - (mask & (long) cuddT(scan)) / sizeof(DdNode)); - if (retval == EOF) goto failure; - if (Cudd_IsComplement(cuddE(scan))) { - retval = fprintf(fp, - "\"%lx\" -> \"%lx\" [style = dotted];\n", - (mask & (long) scan) / sizeof(DdNode), - (mask & (long) cuddE(scan)) / sizeof(DdNode)); - } else { - retval = fprintf(fp, - "\"%lx\" -> \"%lx\" [style = dashed];\n", - (mask & (long) scan) / sizeof(DdNode), - (mask & (long) cuddE(scan)) / sizeof(DdNode)); - } - if (retval == EOF) goto failure; + nodelist = dd->subtables[i].nodelist; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp, + "\"%p\" -> \"%p\";\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddT(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + if (Cudd_IsComplement(cuddE(scan))) { + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dotted];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddE(scan)) / + sizeof(DdNode))); + } else { + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dashed];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddE(scan)) / + sizeof(DdNode))); + } + if (retval == EOF) goto failure; + } + scan = scan->next; + } } - scan = scan->next; } - } - } } /* Write constant labels. */ nodelist = dd->constants.nodelist; slots = dd->constants.slots; for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp,"\"%lx\" [label = \"%g\"];\n", - (mask & (long) scan) / sizeof(DdNode), cuddV(scan)); - if (retval == EOF) goto failure; + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode)), + cuddV(scan)); + if (retval == EOF) goto failure; + } + scan = scan->next; } - scan = scan->next; - } } /* Write trailer and return. */ @@ -591,13 +635,13 @@ Cudd_DumpDaVinci( char ** onames /* array of output names (or NULL) */, FILE * fp /* pointer to the dump file */) { - DdNode *support = NULL; - DdNode *scan; - st_table *visited = NULL; - int retval; - int i; - st_generator *gen; - long refAddr, diff, mask; + DdNode *support = NULL; + DdNode *scan; + st_table *visited = NULL; + int retval; + int i; + st_generator *gen; + ptruint refAddr, diff, mask; /* Initialize symbol table for visited nodes. */ visited = st_init_table(st_ptrcmp, st_ptrhash); @@ -605,8 +649,8 @@ Cudd_DumpDaVinci( /* Collect all the nodes of this DD in the symbol table. */ for (i = 0; i < n; i++) { - retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); - if (retval == 0) goto failure; + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; } /* Find how many most significant hex digits are identical @@ -621,18 +665,18 @@ Cudd_DumpDaVinci( */ /* Find the bits that are different. */ - refAddr = (long) Cudd_Regular(f[0]); + refAddr = (ptruint) Cudd_Regular(f[0]); diff = 0; gen = st_init_gen(visited); - while (st_gen(gen, (const char **) &scan, NULL)) { - diff |= refAddr ^ (long) scan; + while (st_gen(gen, (const char **)&scan, NULL)) { + diff |= refAddr ^ (ptruint) scan; } st_free_gen(gen); /* Choose the mask. */ - for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { - mask = (1 << i) - 1; - if (diff <= mask) break; + for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; } st_free_table(visited); @@ -644,23 +688,23 @@ Cudd_DumpDaVinci( if (retval == EOF) goto failure; /* Call the function that really gets the job done. */ for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp, - "l(\"f%d\",n(\"root\",[a(\"OBJECT\",\"f%d\")],", - i,i); - } else { - retval = fprintf(fp, - "l(\"%s\",n(\"root\",[a(\"OBJECT\",\"%s\")],", - onames[i], onames[i]); - } - if (retval == EOF) goto failure; - retval = fprintf(fp, "[e(\"edge\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", - Cudd_IsComplement(f[i]) ? "red" : "blue"); - if (retval == EOF) goto failure; - retval = ddDoDumpDaVinci(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); - if (retval == 0) goto failure; - retval = fprintf(fp, ")]))%s", i == n-1 ? "" : ","); - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp, + "l(\"f%d\",n(\"root\",[a(\"OBJECT\",\"f%d\")],", + i,i); + } else { + retval = fprintf(fp, + "l(\"%s\",n(\"root\",[a(\"OBJECT\",\"%s\")],", + onames[i], onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp, "[e(\"edge\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", + Cudd_IsComplement(f[i]) ? "red" : "blue"); + if (retval == EOF) goto failure; + retval = ddDoDumpDaVinci(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); + if (retval == 0) goto failure; + retval = fprintf(fp, ")]))%s", i == n-1 ? "" : ","); + if (retval == EOF) goto failure; } /* Write trailer and return. */ @@ -705,15 +749,15 @@ Cudd_DumpDDcal( char ** onames /* array of output names (or NULL) */, FILE * fp /* pointer to the dump file */) { - DdNode *support = NULL; - DdNode *scan; - int *sorted = NULL; - int nvars = dd->size; - st_table *visited = NULL; - int retval; - int i; - st_generator *gen; - long refAddr, diff, mask; + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->size; + st_table *visited = NULL; + int retval; + int i; + st_generator *gen; + ptruint refAddr, diff, mask; /* Initialize symbol table for visited nodes. */ visited = st_init_table(st_ptrcmp, st_ptrhash); @@ -721,8 +765,8 @@ Cudd_DumpDDcal( /* Collect all the nodes of this DD in the symbol table. */ for (i = 0; i < n; i++) { - retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); - if (retval == 0) goto failure; + retval = cuddCollectNodes(Cudd_Regular(f[i]),visited); + if (retval == 0) goto failure; } /* Find how many most significant hex digits are identical @@ -737,26 +781,26 @@ Cudd_DumpDDcal( */ /* Find the bits that are different. */ - refAddr = (long) Cudd_Regular(f[0]); + refAddr = (ptruint) Cudd_Regular(f[0]); diff = 0; gen = st_init_gen(visited); - while (st_gen(gen, (const char **) &scan, NULL)) { - diff |= refAddr ^ (long) scan; + while (st_gen(gen, (const char **)&scan, NULL)) { + diff |= refAddr ^ (ptruint) scan; } st_free_gen(gen); /* Choose the mask. */ - for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { - mask = (1 << i) - 1; - if (diff <= mask) break; + for (i = 0; (unsigned) i < 8 * sizeof(ptruint); i += 4) { + mask = (1 << i) - 1; + if (diff <= mask) break; } st_free_table(visited); /* Build a bit array with the support of f. */ sorted = ABC_ALLOC(int,nvars); if (sorted == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - goto failure; + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; } for (i = 0; i < nvars; i++) sorted[i] = 0; @@ -766,22 +810,22 @@ Cudd_DumpDDcal( cuddRef(support); scan = support; while (!cuddIsConstant(scan)) { - sorted[scan->index] = 1; - scan = cuddT(scan); + sorted[scan->index] = 1; + scan = cuddT(scan); } Cudd_RecursiveDeref(dd,support); support = NULL; /* so that we do not try to free it in case of failure */ for (i = 0; i < nvars; i++) { if (sorted[dd->invperm[i]]) { - if (inames == NULL || inames[dd->invperm[i]] == NULL) { - retval = fprintf(fp,"v%d", dd->invperm[i]); - } else { - retval = fprintf(fp,"%s", inames[dd->invperm[i]]); - } + if (inames == NULL || inames[dd->invperm[i]] == NULL) { + retval = fprintf(fp,"v%d", dd->invperm[i]); + } else { + retval = fprintf(fp,"%s", inames[dd->invperm[i]]); + } if (retval == EOF) goto failure; } - retval = fprintf(fp,"%s", i == nvars - 1 ? "\n" : " * "); - if (retval == EOF) goto failure; + retval = fprintf(fp,"%s", i == nvars - 1 ? "\n" : " * "); + if (retval == EOF) goto failure; } ABC_FREE(sorted); sorted = NULL; @@ -792,31 +836,32 @@ Cudd_DumpDDcal( /* Call the function that really gets the job done. */ for (i = 0; i < n; i++) { - retval = ddDoDumpDDcal(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); - if (retval == 0) goto failure; - if (onames == NULL) { - retval = fprintf(fp, "f%d = ", i); - } else { - retval = fprintf(fp, "%s = ", onames[i]); - } - if (retval == EOF) goto failure; - retval = fprintf(fp, "n%lx%s\n", - ((long) f[i] & mask) / sizeof(DdNode), - Cudd_IsComplement(f[i]) ? "'" : ""); - if (retval == EOF) goto failure; + retval = ddDoDumpDDcal(dd,Cudd_Regular(f[i]),fp,visited,inames,mask); + if (retval == 0) goto failure; + if (onames == NULL) { + retval = fprintf(fp, "f%d = ", i); + } else { + retval = fprintf(fp, "%s = ", onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp, "n%p%s\n", + (void *) (((ptruint) f[i] & mask) / + (ptruint) sizeof(DdNode)), + Cudd_IsComplement(f[i]) ? "'" : ""); + if (retval == EOF) goto failure; } /* Write trailer and return. */ retval = fprintf(fp, "["); if (retval == EOF) goto failure; for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp, "f%d", i); - } else { - retval = fprintf(fp, "%s", onames[i]); - } - retval = fprintf(fp, "%s", i == n-1 ? "" : " "); - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp, "f%d", i); + } else { + retval = fprintf(fp, "%s", onames[i]); + } + retval = fprintf(fp, "%s", i == n-1 ? "" : " "); + if (retval == EOF) goto failure; } retval = fprintf(fp, "]\n"); if (retval == EOF) goto failure; @@ -862,34 +907,34 @@ Cudd_DumpFactoredForm( char ** onames /* array of output names (or NULL) */, FILE * fp /* pointer to the dump file */) { - int retval; - int i; + int retval; + int i; /* Call the function that really gets the job done. */ for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp, "f%d = ", i); - } else { - retval = fprintf(fp, "%s = ", onames[i]); - } - if (retval == EOF) return(0); - if (f[i] == DD_ONE(dd)) { - retval = fprintf(fp, "CONST1"); - if (retval == EOF) return(0); - } else if (f[i] == Cudd_Not(DD_ONE(dd)) || f[i] == DD_ZERO(dd)) { - retval = fprintf(fp, "CONST0"); - if (retval == EOF) return(0); - } else { - retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? "!(" : ""); + if (onames == NULL) { + retval = fprintf(fp, "f%d = ", i); + } else { + retval = fprintf(fp, "%s = ", onames[i]); + } if (retval == EOF) return(0); - retval = ddDoDumpFactoredForm(dd,Cudd_Regular(f[i]),fp,inames); - if (retval == 0) return(0); - retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? ")" : ""); + if (f[i] == DD_ONE(dd)) { + retval = fprintf(fp, "CONST1"); + if (retval == EOF) return(0); + } else if (f[i] == Cudd_Not(DD_ONE(dd)) || f[i] == DD_ZERO(dd)) { + retval = fprintf(fp, "CONST0"); + if (retval == EOF) return(0); + } else { + retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? "!(" : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,Cudd_Regular(f[i]),fp,inames); + if (retval == 0) return(0); + retval = fprintf(fp, "%s", Cudd_IsComplement(f[i]) ? ")" : ""); + if (retval == EOF) return(0); + } + retval = fprintf(fp, "%s", i == n-1 ? "" : "\n"); if (retval == EOF) return(0); } - retval = fprintf(fp, "%s", i == n-1 ? "" : "\n"); - if (retval == EOF) return(0); - } return(1); @@ -926,10 +971,11 @@ ddDoDumpBlif( DdNode * f, FILE * fp, st_table * visited, - char ** names) + char ** names, + int mv) { - DdNode *T, *E; - int retval; + DdNode *T, *E; + int retval; #ifdef DD_DEBUG assert(!Cudd_IsComplement(f)); @@ -950,9 +996,9 @@ ddDoDumpBlif( /* Check for special case: If constant node, generate constant 1. */ if (f == DD_ONE(dd)) { #if SIZEOF_VOID_P == 8 - retval = fprintf(fp, ".names %lx\n1\n",(unsigned long) f / (unsigned long) sizeof(DdNode)); + retval = fprintf(fp, ".names %lx\n1\n",(ptruint) f / (ptruint) sizeof(DdNode)); #else - retval = fprintf(fp, ".names %x\n1\n",(unsigned) f / (unsigned) sizeof(DdNode)); + retval = fprintf(fp, ".names %x\n1\n",(ptruint) f / (ptruint) sizeof(DdNode)); #endif if (retval == EOF) { return(0); @@ -966,9 +1012,13 @@ ddDoDumpBlif( */ if (f == DD_ZERO(dd)) { #if SIZEOF_VOID_P == 8 - retval = fprintf(fp, ".names %lx\n",(unsigned long) f / (unsigned long) sizeof(DdNode)); + retval = fprintf(fp, ".names %lx\n%s", + (ptruint) f / (ptruint) sizeof(DdNode), + mv ? "0\n" : ""); #else - retval = fprintf(fp, ".names %x\n",(unsigned) f / (unsigned) sizeof(DdNode)); + retval = fprintf(fp, ".names %x\n%s", + (ptruint) f / (ptruint) sizeof(DdNode), + mv ? "0\n" : ""); #endif if (retval == EOF) { return(0); @@ -977,48 +1027,80 @@ ddDoDumpBlif( } } if (cuddIsConstant(f)) - return(0); + return(0); /* Recursive calls. */ T = cuddT(f); - retval = ddDoDumpBlif(dd,T,fp,visited,names); + retval = ddDoDumpBlif(dd,T,fp,visited,names,mv); if (retval != 1) return(retval); E = Cudd_Regular(cuddE(f)); - retval = ddDoDumpBlif(dd,E,fp,visited,names); + retval = ddDoDumpBlif(dd,E,fp,visited,names,mv); if (retval != 1) return(retval); /* Write multiplexer taking complement arc into account. */ if (names != NULL) { - retval = fprintf(fp,".names %s", names[f->index]); + retval = fprintf(fp,".names %s", names[f->index]); } else { - retval = fprintf(fp,".names %d", f->index); +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp,".names %u", f->index); +#else + retval = fprintf(fp,".names %hu", f->index); +#endif } if (retval == EOF) - return(0); + return(0); #if SIZEOF_VOID_P == 8 - if (Cudd_IsComplement(cuddE(f))) { - retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-0 1\n", - (unsigned long) T / (unsigned long) sizeof(DdNode), - (unsigned long) E / (unsigned long) sizeof(DdNode), - (unsigned long) f / (unsigned long) sizeof(DdNode)); + if (mv) { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %lx %lx %lx\n.def 0\n1 1 - 1\n0 - 0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %lx %lx %lx\n.def 0\n1 1 - 1\n0 - 1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } } else { - retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-1 1\n", - (unsigned long) T / (unsigned long) sizeof(DdNode), - (unsigned long) E / (unsigned long) sizeof(DdNode), - (unsigned long) f / (unsigned long) sizeof(DdNode)); + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %lx %lx %lx\n11- 1\n0-1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } } #else - if (Cudd_IsComplement(cuddE(f))) { - retval = fprintf(fp," %x %x %x\n11- 1\n0-0 1\n", - (unsigned) T / (unsigned) sizeof(DdNode), - (unsigned) E / (unsigned) sizeof(DdNode), - (unsigned) f / (unsigned) sizeof(DdNode)); + if (mv) { + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %x %x %x\n.def 0\n1 1 - 1\n0 - 0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %x %x %x\n.def 0\n1 1 - 1\n0 - 1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } } else { - retval = fprintf(fp," %x %x %x\n11- 1\n0-1 1\n", - (unsigned) T / (unsigned) sizeof(DdNode), - (unsigned) E / (unsigned) sizeof(DdNode), - (unsigned) f / (unsigned) sizeof(DdNode)); + if (Cudd_IsComplement(cuddE(f))) { + retval = fprintf(fp," %x %x %x\n11- 1\n0-0 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } else { + retval = fprintf(fp," %x %x %x\n11- 1\n0-1 1\n", + (ptruint) T / (ptruint) sizeof(DdNode), + (ptruint) E / (ptruint) sizeof(DdNode), + (ptruint) f / (ptruint) sizeof(DdNode)); + } } #endif if (retval == EOF) { @@ -1051,21 +1133,21 @@ ddDoDumpDaVinci( FILE * fp, st_table * visited, char ** names, - long mask) + ptruint mask) { - DdNode *T, *E; - int retval; - long id; + DdNode *T, *E; + int retval; + ptruint id; #ifdef DD_DEBUG assert(!Cudd_IsComplement(f)); #endif - id = ((long) f & mask) / sizeof(DdNode); + id = ((ptruint) f & mask) / sizeof(DdNode); /* If already visited, insert a reference. */ if (st_is_member(visited, (char *) f) == 1) { - retval = fprintf(fp,"r(\"%lx\")", id); + retval = fprintf(fp,"r(\"%p\")", (void *) id); if (retval == EOF) { return(0); } else { @@ -1083,7 +1165,9 @@ ddDoDumpDaVinci( /* Check for special case: If constant node, generate constant 1. */ if (Cudd_IsConstant(f)) { - retval = fprintf(fp, "l(\"%lx\",n(\"constant\",[a(\"OBJECT\",\"%g\")],[]))", id, cuddV(f)); + retval = fprintf(fp, + "l(\"%p\",n(\"constant\",[a(\"OBJECT\",\"%g\")],[]))", + (void *) id, cuddV(f)); if (retval == EOF) { return(0); } else { @@ -1093,13 +1177,17 @@ ddDoDumpDaVinci( /* Recursive calls. */ if (names != NULL) { - retval = fprintf(fp, - "l(\"%lx\",n(\"internal\",[a(\"OBJECT\",\"%s\"),", - id, names[f->index]); + retval = fprintf(fp, + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%s\"),", + (void *) id, names[f->index]); } else { - retval = fprintf(fp, - "l(\"%lx\",n(\"internal\",[a(\"OBJECT\",\"%d\"),", - id, f->index); + retval = fprintf(fp, +#if SIZEOF_VOID_P == 8 + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%u\"),", +#else + "l(\"%p\",n(\"internal\",[a(\"OBJECT\",\"%hu\"),", +#endif + (void *) id, f->index); } retval = fprintf(fp, "a(\"_GO\",\"ellipse\")],[e(\"then\",[a(\"EDGECOLOR\",\"blue\"),a(\"_DIR\",\"none\")],"); if (retval == EOF) return(0); @@ -1107,7 +1195,7 @@ ddDoDumpDaVinci( retval = ddDoDumpDaVinci(dd,T,fp,visited,names,mask); if (retval != 1) return(retval); retval = fprintf(fp, "),e(\"else\",[a(\"EDGECOLOR\",\"%s\"),a(\"_DIR\",\"none\")],", - Cudd_IsComplement(cuddE(f)) ? "red" : "green"); + Cudd_IsComplement(cuddE(f)) ? "red" : "green"); if (retval == EOF) return(0); E = Cudd_Regular(cuddE(f)); retval = ddDoDumpDaVinci(dd,E,fp,visited,names,mask); @@ -1144,21 +1232,21 @@ ddDoDumpDDcal( FILE * fp, st_table * visited, char ** names, - long mask) + ptruint mask) { - DdNode *T, *E; - int retval; - long id, idT, idE; + DdNode *T, *E; + int retval; + ptruint id, idT, idE; #ifdef DD_DEBUG assert(!Cudd_IsComplement(f)); #endif - id = ((long) f & mask) / sizeof(DdNode); + id = ((ptruint) f & mask) / sizeof(DdNode); /* If already visited, do nothing. */ if (st_is_member(visited, (char *) f) == 1) { - return(1); + return(1); } /* Check for abnormal condition that should never happen. */ @@ -1171,9 +1259,9 @@ ddDoDumpDDcal( /* Check for special case: If constant node, assign constant. */ if (Cudd_IsConstant(f)) { - if (f != DD_ONE(dd) && f != DD_ZERO(dd)) - return(0); - retval = fprintf(fp, "n%lx = %g\n", id, cuddV(f)); + if (f != DD_ONE(dd) && f != DD_ZERO(dd)) + return(0); + retval = fprintf(fp, "n%p = %g\n", (void *) id, cuddV(f)); if (retval == EOF) { return(0); } else { @@ -1188,16 +1276,22 @@ ddDoDumpDDcal( E = Cudd_Regular(cuddE(f)); retval = ddDoDumpDDcal(dd,E,fp,visited,names,mask); if (retval != 1) return(retval); - idT = ((long) T & mask) / sizeof(DdNode); - idE = ((long) E & mask) / sizeof(DdNode); + idT = ((ptruint) T & mask) / sizeof(DdNode); + idE = ((ptruint) E & mask) / sizeof(DdNode); if (names != NULL) { - retval = fprintf(fp, "n%lx = %s * n%lx + %s' * n%lx%s\n", - id, names[f->index], idT, names[f->index], - idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); + retval = fprintf(fp, "n%p = %s * n%p + %s' * n%p%s\n", + (void *) id, names[f->index], + (void *) idT, names[f->index], + (void *) idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); } else { - retval = fprintf(fp, "n%lx = v%d * n%lx + v%d' * n%lx%s\n", - id, f->index, idT, f->index, - idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); +#if SIZEOF_VOID_P == 8 + retval = fprintf(fp, "n%p = v%u * n%p + v%u' * n%p%s\n", +#else + retval = fprintf(fp, "n%p = v%hu * n%p + v%hu' * n%p%s\n", +#endif + (void *) id, f->index, + (void *) idT, f->index, + (void *) idE, Cudd_IsComplement(cuddE(f)) ? "'" : ""); } if (retval == EOF) { return(0); @@ -1232,8 +1326,8 @@ ddDoDumpFactoredForm( FILE * fp, char ** names) { - DdNode *T, *E; - int retval; + DdNode *T, *E; + int retval; #ifdef DD_DEBUG assert(!Cudd_IsComplement(f)); @@ -1248,47 +1342,56 @@ ddDoDumpFactoredForm( T = cuddT(f); E = cuddE(f); if (T != DD_ZERO(dd)) { - if (E != DD_ONE(dd)) { + if (E != DD_ONE(dd)) { + if (names != NULL) { + retval = fprintf(fp, "%s", names[f->index]); + } else { +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp, "x%u", f->index); +#else + retval = fprintf(fp, "x%hu", f->index); +#endif + } + if (retval == EOF) return(0); + } + if (T != DD_ONE(dd)) { + retval = fprintf(fp, "%s(", E != DD_ONE(dd) ? " * " : ""); + if (retval == EOF) return(0); + retval = ddDoDumpFactoredForm(dd,T,fp,names); + if (retval != 1) return(retval); + retval = fprintf(fp, ")"); + if (retval == EOF) return(0); + } + if (E == Cudd_Not(DD_ONE(dd)) || E == DD_ZERO(dd)) return(1); + retval = fprintf(fp, " + "); + if (retval == EOF) return(0); + } + E = Cudd_Regular(E); + if (T != DD_ONE(dd)) { if (names != NULL) { - retval = fprintf(fp, "%s", names[f->index]); + retval = fprintf(fp, "!%s", names[f->index]); } else { - retval = fprintf(fp, "x%d", f->index); +#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 + retval = fprintf(fp, "!x%u", f->index); +#else + retval = fprintf(fp, "!x%hu", f->index); +#endif } if (retval == EOF) return(0); } - if (T != DD_ONE(dd)) { - retval = fprintf(fp, "%s(", E != DD_ONE(dd) ? " * " : ""); + if (E != DD_ONE(dd)) { + retval = fprintf(fp, "%s%s(", T != DD_ONE(dd) ? " * " : "", + E != cuddE(f) ? "!" : ""); if (retval == EOF) return(0); - retval = ddDoDumpFactoredForm(dd,T,fp,names); + retval = ddDoDumpFactoredForm(dd,E,fp,names); if (retval != 1) return(retval); retval = fprintf(fp, ")"); if (retval == EOF) return(0); } - if (E == Cudd_Not(DD_ONE(dd)) || E == DD_ZERO(dd)) return(1); - retval = fprintf(fp, " + "); - if (retval == EOF) return(0); - } - E = Cudd_Regular(E); - if (T != DD_ONE(dd)) { - if (names != NULL) { - retval = fprintf(fp, "!%s", names[f->index]); - } else { - retval = fprintf(fp, "!x%d", f->index); - } - if (retval == EOF) return(0); - } - if (E != DD_ONE(dd)) { - retval = fprintf(fp, "%s%s(", T != DD_ONE(dd) ? " * " : "", - E != cuddE(f) ? "!" : ""); - if (retval == EOF) return(0); - retval = ddDoDumpFactoredForm(dd,E,fp,names); - if (retval != 1) return(retval); - retval = fprintf(fp, ")"); - if (retval == EOF) return(0); - } return(1); } /* end of ddDoDumpFactoredForm */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddGenCof.c b/src/bdd/cudd/cuddGenCof.c index 93e15da0..35c380c0 100644 --- a/src/bdd/cudd/cuddGenCof.c +++ b/src/bdd/cudd/cuddGenCof.c @@ -7,42 +7,71 @@ Synopsis [Generalized cofactors for BDDs and ADDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_bddConstrain() - <li> Cudd_bddRestrict() - <li> Cudd_addConstrain() - <li> Cudd_bddConstrainDecomp() - <li> Cudd_addRestrict() - <li> Cudd_bddCharToVect() - <li> Cudd_bddLICompaction() - <li> Cudd_bddSqueeze() - <li> Cudd_SubsetCompress() - <li> Cudd_SupersetCompress() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddConstrainRecur() - <li> cuddBddRestrictRecur() - <li> cuddAddConstrainRecur() - <li> cuddAddRestrictRecur() - <li> cuddBddLICompaction() - </ul> - Static procedures included in this module: - <ul> - <li> cuddBddConstrainDecomp() - <li> cuddBddCharToVect() - <li> cuddBddLICMarkEdges() - <li> cuddBddLICBuildResult() - <li> cuddBddSqueeze() - </ul> - ] + <ul> + <li> Cudd_bddConstrain() + <li> Cudd_bddRestrict() + <li> Cudd_bddNPAnd() + <li> Cudd_addConstrain() + <li> Cudd_bddConstrainDecomp() + <li> Cudd_addRestrict() + <li> Cudd_bddCharToVect() + <li> Cudd_bddLICompaction() + <li> Cudd_bddSqueeze() + <li> Cudd_SubsetCompress() + <li> Cudd_SupersetCompress() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddBddConstrainRecur() + <li> cuddBddRestrictRecur() + <li> cuddBddNPAndRecur() + <li> cuddAddConstrainRecur() + <li> cuddAddRestrictRecur() + <li> cuddBddLICompaction() + </ul> + Static procedures included in this module: + <ul> + <li> cuddBddConstrainDecomp() + <li> cuddBddCharToVect() + <li> cuddBddLICMarkEdges() + <li> cuddBddLICBuildResult() + <li> cuddBddSqueeze() + </ul> + ] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -53,6 +82,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -85,13 +115,16 @@ typedef struct MarkCacheKey { /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddGenCof.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddGenCof.c,v 1.38 2005/05/14 17:27:11 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -99,17 +132,20 @@ static char rcsid[] DD_UNUSED = "$Id: cuddGenCof.c,v 1.1.1.1 2003/02/24 22:23:52 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int cuddBddConstrainDecomp ARGS((DdManager *dd, DdNode *f, DdNode **decomp)); -static DdNode * cuddBddCharToVect ARGS((DdManager *dd, DdNode *f, DdNode *x)); -static int cuddBddLICMarkEdges ARGS((DdManager *dd, DdNode *f, DdNode *c, st_table *table, st_table *cache)); -static DdNode * cuddBddLICBuildResult ARGS((DdManager *dd, DdNode *f, st_table *cache, st_table *table)); -static int MarkCacheHash ARGS((const char *ptr, int modulus)); -static int MarkCacheCompare ARGS((const char *ptr1, const char *ptr2)); -static enum st_retval MarkCacheCleanUp ARGS((char *key, char *value, char *arg)); -static DdNode * cuddBddSqueeze ARGS((DdManager *dd, DdNode *l, DdNode *u)); +static int cuddBddConstrainDecomp (DdManager *dd, DdNode *f, DdNode **decomp); +static DdNode * cuddBddCharToVect (DdManager *dd, DdNode *f, DdNode *x); +static int cuddBddLICMarkEdges (DdManager *dd, DdNode *f, DdNode *c, st_table *table, st_table *cache); +static DdNode * cuddBddLICBuildResult (DdManager *dd, DdNode *f, st_table *cache, st_table *table); +static int MarkCacheHash (const char *ptr, int modulus); +static int MarkCacheCompare (const char *ptr1, const char *ptr2); +static enum st_retval MarkCacheCleanUp (char *key, char *value, char *arg); +static DdNode * cuddBddSqueeze (DdManager *dd, DdNode *l, DdNode *u); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -149,8 +185,8 @@ Cudd_bddConstrain( DdNode *res; do { - dd->reordered = 0; - res = cuddBddConstrainRecur(dd,f,c); + dd->reordered = 0; + res = cuddBddConstrainRecur(dd,f,c); } while (dd->reordered == 1); return(res); @@ -194,34 +230,34 @@ Cudd_bddRestrict( /* Check if supports intersect. */ retval = Cudd_ClassifySupport(dd,f,c,&commonSupport,&suppF,&suppC); if (retval == 0) { - return(NULL); + return(NULL); } cuddRef(commonSupport); cuddRef(suppF); cuddRef(suppC); Cudd_IterDerefBdd(dd,suppF); if (commonSupport == DD_ONE(dd)) { - Cudd_IterDerefBdd(dd,commonSupport); - Cudd_IterDerefBdd(dd,suppC); - return(f); + Cudd_IterDerefBdd(dd,commonSupport); + Cudd_IterDerefBdd(dd,suppC); + return(f); } Cudd_IterDerefBdd(dd,commonSupport); /* Abstract from c the variables that do not appear in f. */ cplus = Cudd_bddExistAbstract(dd, c, suppC); if (cplus == NULL) { - Cudd_IterDerefBdd(dd,suppC); - return(NULL); + Cudd_IterDerefBdd(dd,suppC); + return(NULL); } cuddRef(cplus); Cudd_IterDerefBdd(dd,suppC); do { - dd->reordered = 0; - res = cuddBddRestrictRecur(dd, f, cplus); + dd->reordered = 0; + res = cuddBddRestrictRecur(dd, f, cplus); } while (dd->reordered == 1); if (res == NULL) { - Cudd_IterDerefBdd(dd,cplus); - return(NULL); + Cudd_IterDerefBdd(dd,cplus); + return(NULL); } cuddRef(res); Cudd_IterDerefBdd(dd,cplus); @@ -230,11 +266,11 @@ Cudd_bddRestrict( sizeF = Cudd_DagSize(f); sizeRes = Cudd_DagSize(res); if (sizeF <= sizeRes) { - Cudd_IterDerefBdd(dd, res); - return(f); + Cudd_IterDerefBdd(dd, res); + return(f); } else { - cuddDeref(res); - return(res); + cuddDeref(res); + return(res); } } /* end of Cudd_bddRestrict */ @@ -242,6 +278,42 @@ Cudd_bddRestrict( /**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] + +******************************************************************************/ +DdNode * +Cudd_bddNPAnd( + DdManager * dd, + DdNode * f, + DdNode * g) +{ + DdNode *res; + + do { + dd->reordered = 0; + res = cuddBddNPAndRecur(dd,f,g); + } while (dd->reordered == 1); + return(res); + +} /* end of Cudd_bddNPAnd */ + + +/**Function******************************************************************** + Synopsis [Computes f constrain c for ADDs.] Description [Computes f constrain c (f @ c), for f an ADD and c a 0-1 @@ -269,8 +341,8 @@ Cudd_addConstrain( DdNode *res; do { - dd->reordered = 0; - res = cuddAddConstrainRecur(dd,f,c); + dd->reordered = 0; + res = cuddAddConstrainRecur(dd,f,c); } while (dd->reordered == 1); return(res); @@ -307,33 +379,33 @@ Cudd_bddConstrainDecomp( /* Create an initialize decomposition array. */ decomp = ABC_ALLOC(DdNode *,dd->size); if (decomp == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < dd->size; i++) { - decomp[i] = NULL; + decomp[i] = NULL; } do { - dd->reordered = 0; - /* Clean up the decomposition array in case reordering took place. */ - for (i = 0; i < dd->size; i++) { - if (decomp[i] != NULL) { - Cudd_IterDerefBdd(dd, decomp[i]); - decomp[i] = NULL; + dd->reordered = 0; + /* Clean up the decomposition array in case reordering took place. */ + for (i = 0; i < dd->size; i++) { + if (decomp[i] != NULL) { + Cudd_IterDerefBdd(dd, decomp[i]); + decomp[i] = NULL; + } } - } - res = cuddBddConstrainDecomp(dd,f,decomp); + res = cuddBddConstrainDecomp(dd,f,decomp); } while (dd->reordered == 1); if (res == 0) { - ABC_FREE(decomp); - return(NULL); + ABC_FREE(decomp); + return(NULL); } /* Missing components are constant ones. */ for (i = 0; i < dd->size; i++) { - if (decomp[i] == NULL) { - decomp[i] = DD_ONE(dd); - cuddRef(decomp[i]); - } + if (decomp[i] == NULL) { + decomp[i] = DD_ONE(dd); + cuddRef(decomp[i]); + } } return(decomp); @@ -369,20 +441,20 @@ Cudd_addRestrict( /* Check if supports intersect. */ supp_f = Cudd_Support(dd, f); if (supp_f == NULL) { - return(NULL); + return(NULL); } cuddRef(supp_f); supp_c = Cudd_Support(dd, c); if (supp_c == NULL) { - Cudd_RecursiveDeref(dd,supp_f); - return(NULL); + Cudd_RecursiveDeref(dd,supp_f); + return(NULL); } cuddRef(supp_c); commonSupport = Cudd_bddLiteralSetIntersection(dd, supp_f, supp_c); if (commonSupport == NULL) { - Cudd_RecursiveDeref(dd,supp_f); - Cudd_RecursiveDeref(dd,supp_c); - return(NULL); + Cudd_RecursiveDeref(dd,supp_f); + Cudd_RecursiveDeref(dd,supp_c); + return(NULL); } cuddRef(commonSupport); Cudd_RecursiveDeref(dd,supp_f); @@ -391,21 +463,21 @@ Cudd_addRestrict( Cudd_RecursiveDeref(dd,commonSupport); if (intersection) { - do { - dd->reordered = 0; - res = cuddAddRestrictRecur(dd, f, c); - } while (dd->reordered == 1); - sizeF = Cudd_DagSize(f); - sizeRes = Cudd_DagSize(res); - if (sizeF <= sizeRes) { - cuddRef(res); - Cudd_RecursiveDeref(dd, res); - return(f); - } else { - return(res); - } + do { + dd->reordered = 0; + res = cuddAddRestrictRecur(dd, f, c); + } while (dd->reordered == 1); + sizeF = Cudd_DagSize(f); + sizeRes = Cudd_DagSize(res); + if (sizeF <= sizeRes) { + cuddRef(res); + Cudd_RecursiveDeref(dd, res); + return(f); + } else { + return(res); + } } else { - return(f); + return(f); } } /* end of Cudd_addRestrict */ @@ -427,7 +499,7 @@ Cudd_addRestrict( 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.] + the package).] SideEffects [None] @@ -447,28 +519,28 @@ Cudd_bddCharToVect( vect = ABC_ALLOC(DdNode *, dd->size); if (vect == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } do { - dd->reordered = 0; - for (i = 0; i < dd->size; i++) { - res = cuddBddCharToVect(dd,f,dd->vars[dd->invperm[i]]); - if (res == NULL) { - /* Clean up the vector array in case reordering took place. */ - for (j = 0; j < i; j++) { - Cudd_IterDerefBdd(dd, vect[dd->invperm[j]]); - } - break; + dd->reordered = 0; + for (i = 0; i < dd->size; i++) { + res = cuddBddCharToVect(dd,f,dd->vars[dd->invperm[i]]); + if (res == NULL) { + /* Clean up the vector array in case reordering took place. */ + for (j = 0; j < i; j++) { + Cudd_IterDerefBdd(dd, vect[dd->invperm[j]]); + } + break; + } + cuddRef(res); + vect[dd->invperm[i]] = res; } - cuddRef(res); - vect[dd->invperm[i]] = res; - } } while (dd->reordered == 1); if (res == NULL) { - ABC_FREE(vect); - return(NULL); + ABC_FREE(vect); + return(NULL); } return(vect); @@ -503,8 +575,8 @@ Cudd_bddLICompaction( DdNode *res; do { - dd->reordered = 0; - res = cuddBddLICompaction(dd,f,c); + dd->reordered = 0; + res = cuddBddLICompaction(dd,f,c); } while (dd->reordered == 1); return(res); @@ -536,8 +608,8 @@ Cudd_bddSqueeze( int sizeRes, sizeL, sizeU; do { - dd->reordered = 0; - res = cuddBddSqueeze(dd,l,u); + dd->reordered = 0; + res = cuddBddSqueeze(dd,l,u); } while (dd->reordered == 1); if (res == NULL) return(NULL); /* We now compare the result with the bounds and return the smallest. @@ -546,17 +618,17 @@ Cudd_bddSqueeze( sizeRes = Cudd_DagSize(res); sizeU = Cudd_DagSize(u); if (sizeU <= sizeRes) { - cuddRef(res); - Cudd_IterDerefBdd(dd,res); - res = u; - sizeRes = sizeU; + cuddRef(res); + Cudd_IterDerefBdd(dd,res); + res = u; + sizeRes = sizeU; } sizeL = Cudd_DagSize(l); if (sizeL <= sizeRes) { - cuddRef(res); - Cudd_IterDerefBdd(dd,res); - res = l; - sizeRes = sizeL; + cuddRef(res); + Cudd_IterDerefBdd(dd,res); + res = l; + sizeRes = sizeL; } return(res); @@ -595,8 +667,8 @@ Cudd_bddMinimize( cuddRef(cplus); res = Cudd_bddLICompaction(dd,f,cplus); if (res == NULL) { - Cudd_IterDerefBdd(dd,cplus); - return(NULL); + Cudd_IterDerefBdd(dd,cplus); + return(NULL); } cuddRef(res); Cudd_IterDerefBdd(dd,cplus); @@ -638,15 +710,15 @@ Cudd_SubsetCompress( cuddRef(tmp1); tmp2 = Cudd_RemapUnderApprox(dd,tmp1,nvars,0,1.0); if (tmp2 == NULL) { - Cudd_IterDerefBdd(dd,tmp1); - return(NULL); + Cudd_IterDerefBdd(dd,tmp1); + return(NULL); } cuddRef(tmp2); Cudd_IterDerefBdd(dd,tmp1); res = Cudd_bddSqueeze(dd,tmp2,f); if (res == NULL) { - Cudd_IterDerefBdd(dd,tmp2); - return(NULL); + Cudd_IterDerefBdd(dd,tmp2); + return(NULL); } cuddRef(res); Cudd_IterDerefBdd(dd,tmp2); @@ -714,9 +786,9 @@ cuddBddConstrainRecur( DdNode * c) { DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r; - DdNode *one, *zero; + DdNode *one, *zero; unsigned int topf, topc; - int index; + int index; int comple = 0; statLine(dd); @@ -724,16 +796,16 @@ cuddBddConstrainRecur( zero = Cudd_Not(one); /* Trivial cases. */ - if (c == one) return(f); - if (c == zero) return(zero); - if (Cudd_IsConstant(f)) return(f); - if (f == c) return(one); - if (f == Cudd_Not(c)) return(zero); + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + if (f == Cudd_Not(c)) return(zero); /* Make canonical to increase the utilization of the cache. */ if (Cudd_IsComplement(f)) { - f = Cudd_Not(f); - comple = 1; + f = Cudd_Not(f); + comple = 1; } /* Now f is a regular pointer to a non-constant node; c is also ** non-constant, but may be complemented. @@ -742,78 +814,78 @@ cuddBddConstrainRecur( /* Check the cache. */ r = cuddCacheLookup2(dd, Cudd_bddConstrain, f, c); if (r != NULL) { - return(Cudd_NotCond(r,comple)); + return(Cudd_NotCond(r,comple)); } /* Recursive step. */ topf = dd->perm[f->index]; topc = dd->perm[Cudd_Regular(c)->index]; if (topf <= topc) { - index = f->index; - Fv = cuddT(f); Fnv = cuddE(f); + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); } else { - index = Cudd_Regular(c)->index; - Fv = Fnv = f; + index = Cudd_Regular(c)->index; + Fv = Fnv = f; } if (topc <= topf) { - Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); - if (Cudd_IsComplement(c)) { - Cv = Cudd_Not(Cv); - Cnv = Cudd_Not(Cnv); - } + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } } else { - Cv = Cnv = c; + Cv = Cnv = c; } if (!Cudd_IsConstant(Cv)) { - t = cuddBddConstrainRecur(dd, Fv, Cv); - if (t == NULL) - return(NULL); + t = cuddBddConstrainRecur(dd, Fv, Cv); + if (t == NULL) + return(NULL); } else if (Cv == one) { - t = Fv; - } else { /* Cv == zero: return Fnv @ Cnv */ - if (Cnv == one) { - r = Fnv; - } else { - r = cuddBddConstrainRecur(dd, Fnv, Cnv); - if (r == NULL) - return(NULL); - } - return(Cudd_NotCond(r,comple)); + t = Fv; + } else { /* Cv == zero: return Fnv @ Cnv */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddBddConstrainRecur(dd, Fnv, Cnv); + if (r == NULL) + return(NULL); + } + return(Cudd_NotCond(r,comple)); } cuddRef(t); if (!Cudd_IsConstant(Cnv)) { - e = cuddBddConstrainRecur(dd, Fnv, Cnv); - if (e == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); - } + e = cuddBddConstrainRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } else if (Cnv == one) { - e = Fnv; - } else { /* Cnv == zero: return Fv @ Cv previously computed */ - cuddDeref(t); - return(Cudd_NotCond(t,comple)); + e = Fnv; + } else { /* Cnv == zero: return Fv @ Cv previously computed */ + cuddDeref(t); + return(Cudd_NotCond(t,comple)); } cuddRef(e); if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - r = Cudd_Not(r); + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); } else { - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } cuddDeref(t); cuddDeref(e); @@ -842,26 +914,26 @@ cuddBddRestrictRecur( DdNode * f, DdNode * c) { - DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; unsigned int topf, topc; - int index; - int comple = 0; + int index; + int comple = 0; statLine(dd); one = DD_ONE(dd); zero = Cudd_Not(one); /* Trivial cases */ - if (c == one) return(f); - if (c == zero) return(zero); - if (Cudd_IsConstant(f)) return(f); - if (f == c) return(one); - if (f == Cudd_Not(c)) return(zero); + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); + if (f == Cudd_Not(c)) return(zero); /* Make canonical to increase the utilization of the cache. */ if (Cudd_IsComplement(f)) { - f = Cudd_Not(f); - comple = 1; + f = Cudd_Not(f); + comple = 1; } /* Now f is a regular pointer to a non-constant node; c is also ** non-constant, but may be complemented. @@ -870,100 +942,100 @@ cuddBddRestrictRecur( /* Check the cache. */ r = cuddCacheLookup2(dd, Cudd_bddRestrict, f, c); if (r != NULL) { - return(Cudd_NotCond(r,comple)); + return(Cudd_NotCond(r,comple)); } topf = dd->perm[f->index]; topc = dd->perm[Cudd_Regular(c)->index]; - if (topc < topf) { /* abstract top variable from c */ - DdNode *d, *s1, *s2; + if (topc < topf) { /* abstract top variable from c */ + DdNode *d, *s1, *s2; - /* Find complements of cofactors of c. */ - if (Cudd_IsComplement(c)) { - s1 = cuddT(Cudd_Regular(c)); - s2 = cuddE(Cudd_Regular(c)); - } else { - s1 = Cudd_Not(cuddT(c)); - s2 = Cudd_Not(cuddE(c)); - } - /* Take the OR by applying DeMorgan. */ - d = cuddBddAndRecur(dd, s1, s2); - if (d == NULL) return(NULL); - d = Cudd_Not(d); - cuddRef(d); - r = cuddBddRestrictRecur(dd, f, d); - if (r == NULL) { + /* Find complements of cofactors of c. */ + if (Cudd_IsComplement(c)) { + s1 = cuddT(Cudd_Regular(c)); + s2 = cuddE(Cudd_Regular(c)); + } else { + s1 = Cudd_Not(cuddT(c)); + s2 = Cudd_Not(cuddE(c)); + } + /* Take the OR by applying DeMorgan. */ + d = cuddBddAndRecur(dd, s1, s2); + if (d == NULL) return(NULL); + d = Cudd_Not(d); + cuddRef(d); + r = cuddBddRestrictRecur(dd, f, d); + if (r == NULL) { + Cudd_IterDerefBdd(dd, d); + return(NULL); + } + cuddRef(r); Cudd_IterDerefBdd(dd, d); - return(NULL); - } - cuddRef(r); - Cudd_IterDerefBdd(dd, d); - cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r); - cuddDeref(r); - return(Cudd_NotCond(r,comple)); + cuddCacheInsert2(dd, Cudd_bddRestrict, f, c, r); + cuddDeref(r); + return(Cudd_NotCond(r,comple)); } /* Recursive step. Here topf <= topc. */ index = f->index; Fv = cuddT(f); Fnv = cuddE(f); if (topc == topf) { - Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); - if (Cudd_IsComplement(c)) { - Cv = Cudd_Not(Cv); - Cnv = Cudd_Not(Cnv); - } + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } } else { - Cv = Cnv = c; + Cv = Cnv = c; } if (!Cudd_IsConstant(Cv)) { - t = cuddBddRestrictRecur(dd, Fv, Cv); - if (t == NULL) return(NULL); + t = cuddBddRestrictRecur(dd, Fv, Cv); + if (t == NULL) return(NULL); } else if (Cv == one) { - t = Fv; - } else { /* Cv == zero: return(Fnv @ Cnv) */ - if (Cnv == one) { - r = Fnv; - } else { - r = cuddBddRestrictRecur(dd, Fnv, Cnv); - if (r == NULL) return(NULL); - } - return(Cudd_NotCond(r,comple)); + t = Fv; + } else { /* Cv == zero: return(Fnv @ Cnv) */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddBddRestrictRecur(dd, Fnv, Cnv); + if (r == NULL) return(NULL); + } + return(Cudd_NotCond(r,comple)); } cuddRef(t); if (!Cudd_IsConstant(Cnv)) { - e = cuddBddRestrictRecur(dd, Fnv, Cnv); - if (e == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); - } + e = cuddBddRestrictRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } else if (Cnv == one) { - e = Fnv; - } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ - cuddDeref(t); - return(Cudd_NotCond(t,comple)); + e = Fnv; + } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ + cuddDeref(t); + return(Cudd_NotCond(t,comple)); } cuddRef(e); if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - r = Cudd_Not(r); + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); } else { - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } cuddDeref(t); cuddDeref(e); @@ -976,6 +1048,147 @@ cuddBddRestrictRecur( /**Function******************************************************************** + Synopsis [Implements the recursive step of Cudd_bddAnd.] + + Description [Implements the recursive step of Cudd_bddNPAnd. + Returns a pointer to the result is successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_bddNPAnd] + +******************************************************************************/ +DdNode * +cuddBddNPAndRecur( + DdManager * manager, + DdNode * f, + DdNode * g) +{ + DdNode *F, *ft, *fe, *G, *gt, *ge; + DdNode *one, *r, *t, *e; + unsigned int topf, topg, index; + + statLine(manager); + one = DD_ONE(manager); + + /* Terminal cases. */ + F = Cudd_Regular(f); + G = Cudd_Regular(g); + if (F == G) { + if (f == g) return(one); + else return(Cudd_Not(one)); + } + if (G == one) { + if (g == one) return(f); + else return(g); + } + if (F == one) { + return(f); + } + + /* At this point f and g are not constant. */ + /* Check cache. */ + if (F->ref != 1 || G->ref != 1) { + r = cuddCacheLookup2(manager, Cudd_bddNPAnd, f, g); + if (r != NULL) return(r); + } + + /* Here we can skip the use of cuddI, because the operands are known + ** to be non-constant. + */ + topf = manager->perm[F->index]; + topg = manager->perm[G->index]; + + if (topg < topf) { /* abstract top variable from g */ + DdNode *d; + + /* Find complements of cofactors of g. */ + if (Cudd_IsComplement(g)) { + gt = cuddT(G); + ge = cuddE(G); + } else { + gt = Cudd_Not(cuddT(g)); + ge = Cudd_Not(cuddE(g)); + } + /* Take the OR by applying DeMorgan. */ + d = cuddBddAndRecur(manager, gt, ge); + if (d == NULL) return(NULL); + d = Cudd_Not(d); + cuddRef(d); + r = cuddBddNPAndRecur(manager, f, d); + if (r == NULL) { + Cudd_IterDerefBdd(manager, d); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(manager, d); + cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r); + cuddDeref(r); + return(r); + } + + /* Compute cofactors. */ + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } + + if (topg == topf) { + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } + } else { + gt = ge = g; + } + + t = cuddBddAndRecur(manager, ft, gt); + if (t == NULL) return(NULL); + cuddRef(t); + + e = cuddBddAndRecur(manager, fe, ge); + if (e == NULL) { + Cudd_IterDerefBdd(manager, t); + return(NULL); + } + cuddRef(e); + + if (t == e) { + r = t; + } else { + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(manager,(int)index,t,e); + if (r == NULL) { + Cudd_IterDerefBdd(manager, t); + Cudd_IterDerefBdd(manager, e); + return(NULL); + } + } + } + cuddDeref(e); + cuddDeref(t); + if (F->ref != 1 || G->ref != 1) + cuddCacheInsert2(manager, Cudd_bddNPAnd, f, g, r); + return(r); + +} /* end of cuddBddNPAndRecur */ + + +/**Function******************************************************************** + Synopsis [Performs the recursive step of Cudd_addConstrain.] Description [Performs the recursive step of Cudd_addConstrain. @@ -993,81 +1206,81 @@ cuddAddConstrainRecur( DdNode * c) { DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r; - DdNode *one, *zero; + DdNode *one, *zero; unsigned int topf, topc; - int index; + int index; statLine(dd); one = DD_ONE(dd); zero = DD_ZERO(dd); /* Trivial cases. */ - if (c == one) return(f); - if (c == zero) return(zero); - if (Cudd_IsConstant(f)) return(f); - if (f == c) return(one); + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); /* Now f and c are non-constant. */ /* Check the cache. */ r = cuddCacheLookup2(dd, Cudd_addConstrain, f, c); if (r != NULL) { - return(r); + return(r); } /* Recursive step. */ topf = dd->perm[f->index]; topc = dd->perm[c->index]; if (topf <= topc) { - index = f->index; - Fv = cuddT(f); Fnv = cuddE(f); + index = f->index; + Fv = cuddT(f); Fnv = cuddE(f); } else { - index = c->index; - Fv = Fnv = f; + index = c->index; + Fv = Fnv = f; } if (topc <= topf) { - Cv = cuddT(c); Cnv = cuddE(c); + Cv = cuddT(c); Cnv = cuddE(c); } else { - Cv = Cnv = c; + Cv = Cnv = c; } if (!Cudd_IsConstant(Cv)) { - t = cuddAddConstrainRecur(dd, Fv, Cv); - if (t == NULL) - return(NULL); + t = cuddAddConstrainRecur(dd, Fv, Cv); + if (t == NULL) + return(NULL); } else if (Cv == one) { - t = Fv; - } else { /* Cv == zero: return Fnv @ Cnv */ - if (Cnv == one) { - r = Fnv; - } else { - r = cuddAddConstrainRecur(dd, Fnv, Cnv); - if (r == NULL) - return(NULL); - } - return(r); + t = Fv; + } else { /* Cv == zero: return Fnv @ Cnv */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddAddConstrainRecur(dd, Fnv, Cnv); + if (r == NULL) + return(NULL); + } + return(r); } cuddRef(t); if (!Cudd_IsConstant(Cnv)) { - e = cuddAddConstrainRecur(dd, Fnv, Cnv); - if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } + e = cuddAddConstrainRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } } else if (Cnv == one) { - e = Fnv; - } else { /* Cnv == zero: return Fv @ Cv previously computed */ - cuddDeref(t); - return(t); + e = Fnv; + } else { /* Cnv == zero: return Fv @ Cv previously computed */ + cuddDeref(t); + return(t); } cuddRef(e); r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - Cudd_RecursiveDeref(dd, t); - return(NULL); + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); } cuddDeref(t); cuddDeref(e); @@ -1096,97 +1309,97 @@ cuddAddRestrictRecur( DdNode * f, DdNode * c) { - DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; + DdNode *Fv, *Fnv, *Cv, *Cnv, *t, *e, *r, *one, *zero; unsigned int topf, topc; - int index; + int index; statLine(dd); one = DD_ONE(dd); zero = DD_ZERO(dd); /* Trivial cases */ - if (c == one) return(f); - if (c == zero) return(zero); - if (Cudd_IsConstant(f)) return(f); - if (f == c) return(one); + if (c == one) return(f); + if (c == zero) return(zero); + if (Cudd_IsConstant(f)) return(f); + if (f == c) return(one); /* Now f and c are non-constant. */ /* Check the cache. */ r = cuddCacheLookup2(dd, Cudd_addRestrict, f, c); if (r != NULL) { - return(r); + return(r); } topf = dd->perm[f->index]; topc = dd->perm[c->index]; - if (topc < topf) { /* abstract top variable from c */ - DdNode *d, *s1, *s2; - - /* Find cofactors of c. */ - s1 = cuddT(c); - s2 = cuddE(c); - /* Take the OR by applying DeMorgan. */ - d = cuddAddApplyRecur(dd, Cudd_addOr, s1, s2); - if (d == NULL) return(NULL); - cuddRef(d); - r = cuddAddRestrictRecur(dd, f, d); - if (r == NULL) { + if (topc < topf) { /* abstract top variable from c */ + DdNode *d, *s1, *s2; + + /* Find cofactors of c. */ + s1 = cuddT(c); + s2 = cuddE(c); + /* Take the OR by applying DeMorgan. */ + d = cuddAddApplyRecur(dd, Cudd_addOr, s1, s2); + if (d == NULL) return(NULL); + cuddRef(d); + r = cuddAddRestrictRecur(dd, f, d); + if (r == NULL) { + Cudd_RecursiveDeref(dd, d); + return(NULL); + } + cuddRef(r); Cudd_RecursiveDeref(dd, d); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDeref(dd, d); - cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r); - cuddDeref(r); - return(r); + cuddCacheInsert2(dd, Cudd_addRestrict, f, c, r); + cuddDeref(r); + return(r); } /* Recursive step. Here topf <= topc. */ index = f->index; Fv = cuddT(f); Fnv = cuddE(f); if (topc == topf) { - Cv = cuddT(c); Cnv = cuddE(c); + Cv = cuddT(c); Cnv = cuddE(c); } else { - Cv = Cnv = c; + Cv = Cnv = c; } if (!Cudd_IsConstant(Cv)) { - t = cuddAddRestrictRecur(dd, Fv, Cv); - if (t == NULL) return(NULL); + t = cuddAddRestrictRecur(dd, Fv, Cv); + if (t == NULL) return(NULL); } else if (Cv == one) { - t = Fv; - } else { /* Cv == zero: return(Fnv @ Cnv) */ - if (Cnv == one) { - r = Fnv; - } else { - r = cuddAddRestrictRecur(dd, Fnv, Cnv); - if (r == NULL) return(NULL); - } - return(r); + t = Fv; + } else { /* Cv == zero: return(Fnv @ Cnv) */ + if (Cnv == one) { + r = Fnv; + } else { + r = cuddAddRestrictRecur(dd, Fnv, Cnv); + if (r == NULL) return(NULL); + } + return(r); } cuddRef(t); if (!Cudd_IsConstant(Cnv)) { - e = cuddAddRestrictRecur(dd, Fnv, Cnv); - if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); - } + e = cuddAddRestrictRecur(dd, Fnv, Cnv); + if (e == NULL) { + Cudd_RecursiveDeref(dd, t); + return(NULL); + } } else if (Cnv == one) { - e = Fnv; - } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ - cuddDeref(t); - return(t); + e = Fnv; + } else { /* Cnv == zero: return (Fv @ Cv) previously computed */ + cuddDeref(t); + return(t); } cuddRef(e); r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); if (r == NULL) { - Cudd_RecursiveDeref(dd, e); - Cudd_RecursiveDeref(dd, t); - return(NULL); + Cudd_RecursiveDeref(dd, e); + Cudd_RecursiveDeref(dd, t); + return(NULL); } cuddDeref(t); cuddDeref(e); @@ -1240,27 +1453,27 @@ cuddBddLICompaction( ** appears. Hence, the same node and constrain may give different results ** in successive invocations. */ - marktable = st_init_table(st_ptrcmp, st_ptrhash);; + marktable = st_init_table(st_ptrcmp,st_ptrhash); if (marktable == NULL) { - return(NULL); + return(NULL); } markcache = st_init_table(MarkCacheCompare,MarkCacheHash); if (markcache == NULL) { - st_free_table(marktable); - return(NULL); + st_free_table(marktable); + return(NULL); } if (cuddBddLICMarkEdges(dd,f,c,marktable,markcache) == CUDD_OUT_OF_MEM) { - st_foreach(markcache, (ST_PFSR)MarkCacheCleanUp, NULL); - st_free_table(marktable); - st_free_table(markcache); - return(NULL); + st_foreach(markcache, MarkCacheCleanUp, NULL); + st_free_table(marktable); + st_free_table(markcache); + return(NULL); } - st_foreach(markcache, (ST_PFSR)MarkCacheCleanUp, NULL); + st_foreach(markcache, MarkCacheCleanUp, NULL); st_free_table(markcache); - buildcache = st_init_table(st_ptrcmp, st_ptrhash);; + buildcache = st_init_table(st_ptrcmp,st_ptrhash); if (buildcache == NULL) { - st_free_table(marktable); - return(NULL); + st_free_table(marktable); + return(NULL); } res = cuddBddLICBuildResult(dd,f,buildcache,marktable); st_free_table(buildcache); @@ -1304,13 +1517,13 @@ cuddBddConstrainDecomp( fv = cuddT(F); fvn = cuddE(F); if (F == f) { - fv = Cudd_Not(fv); - fvn = Cudd_Not(fvn); + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); } /* Compute abstraction of top variable. */ fAbs = cuddBddAndRecur(dd, fv, fvn); if (fAbs == NULL) { - return(0); + return(0); } cuddRef(fAbs); fAbs = Cudd_Not(fAbs); @@ -1318,15 +1531,15 @@ cuddBddConstrainDecomp( ** decomposition. */ ok = cuddBddConstrainDecomp(dd, fAbs, decomp); if (ok == 0) { - Cudd_IterDerefBdd(dd,fAbs); - return(0); + Cudd_IterDerefBdd(dd,fAbs); + return(0); } /* Compute the component of the decomposition corresponding to the ** top variable and store it in the decomposition array. */ result = cuddBddConstrainRecur(dd, f, fAbs); if (result == NULL) { - Cudd_IterDerefBdd(dd,fAbs); - return(0); + Cudd_IterDerefBdd(dd,fAbs); + return(0); } cuddRef(result); decomp[F->index] = result; @@ -1365,7 +1578,7 @@ cuddBddCharToVect( /* Check the cache. */ res = cuddCacheLookup2(dd, cuddBddCharToVect, f, x); if (res != NULL) { - return(res); + return(res); } F = Cudd_Regular(f); @@ -1383,9 +1596,9 @@ cuddBddCharToVect( fE = Cudd_NotCond(cuddE(F),comple); if (topf == level) { - if (fT == zero) return(zero); - if (fE == zero) return(one); - return(x); + if (fT == zero) return(zero); + if (fE == zero) return(one); + return(x); } /* Here topf < level. */ @@ -1394,20 +1607,20 @@ cuddBddCharToVect( T = cuddBddCharToVect(dd, fT, x); if (T == NULL) { - return(NULL); + return(NULL); } cuddRef(T); E = cuddBddCharToVect(dd, fE, x); if (E == NULL) { - Cudd_IterDerefBdd(dd,T); - return(NULL); + Cudd_IterDerefBdd(dd,T); + return(NULL); } cuddRef(E); res = cuddBddIteRecur(dd, dd->vars[F->index], T, E); if (res == NULL) { - Cudd_IterDerefBdd(dd,T); - Cudd_IterDerefBdd(dd,E); - return(NULL); + Cudd_IterDerefBdd(dd,T); + Cudd_IterDerefBdd(dd,E); + return(NULL); } cuddDeref(T); cuddDeref(E); @@ -1441,7 +1654,6 @@ cuddBddLICMarkEdges( DdNode *Fv, *Fnv, *Cv, *Cnv; DdNode *one, *zero; unsigned int topf, topc; - int index; int comple; int resT, resE, res, retval; char **slot; @@ -1465,75 +1677,73 @@ cuddBddLICMarkEdges( /* Check the cache. */ key = ABC_ALLOC(MarkCacheKey, 1); if (key == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); } key->f = f; key->c = c; - if (st_lookup(cache, (char *)key, (char **)&res)) { - ABC_FREE(key); - if (comple) { - if (res == DD_LIC_0) res = DD_LIC_1; - else if (res == DD_LIC_1) res = DD_LIC_0; - } - return(res); + if (st_lookup_int(cache, (char *)key, &res)) { + ABC_FREE(key); + if (comple) { + if (res == DD_LIC_0) res = DD_LIC_1; + else if (res == DD_LIC_1) res = DD_LIC_0; + } + return(res); } /* Recursive step. */ topf = dd->perm[f->index]; topc = cuddI(dd,Cudd_Regular(c)->index); if (topf <= topc) { - index = f->index; - Fv = cuddT(f); Fnv = cuddE(f); + Fv = cuddT(f); Fnv = cuddE(f); } else { - index = Cudd_Regular(c)->index; - Fv = Fnv = f; + Fv = Fnv = f; } if (topc <= topf) { - /* We know that c is not constant because f is not. */ - Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); - if (Cudd_IsComplement(c)) { - Cv = Cudd_Not(Cv); - Cnv = Cudd_Not(Cnv); - } + /* We know that c is not constant because f is not. */ + Cv = cuddT(Cudd_Regular(c)); Cnv = cuddE(Cudd_Regular(c)); + if (Cudd_IsComplement(c)) { + Cv = Cudd_Not(Cv); + Cnv = Cudd_Not(Cnv); + } } else { - Cv = Cnv = c; + Cv = Cnv = c; } resT = cuddBddLICMarkEdges(dd, Fv, Cv, table, cache); if (resT == CUDD_OUT_OF_MEM) { - ABC_FREE(key); - return(CUDD_OUT_OF_MEM); + ABC_FREE(key); + return(CUDD_OUT_OF_MEM); } resE = cuddBddLICMarkEdges(dd, Fnv, Cnv, table, cache); if (resE == CUDD_OUT_OF_MEM) { - ABC_FREE(key); - return(CUDD_OUT_OF_MEM); + ABC_FREE(key); + return(CUDD_OUT_OF_MEM); } /* Update edge markings. */ if (topf <= topc) { - retval = st_find_or_add(table, (char *)f, (char ***)&slot); - if (retval == 0) { - *slot = (char *) (ptrint)((resT << 2) | resE); - } else if (retval == 1) { - *slot = (char *) (ptrint)((int)((ptrint) *slot) | (resT << 2) | resE); - } else { - ABC_FREE(key); - return(CUDD_OUT_OF_MEM); - } + retval = st_find_or_add(table, (char *)f, (char ***)&slot); + if (retval == 0) { + *slot = (char *) (ptrint)((resT << 2) | resE); + } else if (retval == 1) { + *slot = (char *) (ptrint)((int)((ptrint) *slot) | (resT << 2) | resE); + } else { + ABC_FREE(key); + return(CUDD_OUT_OF_MEM); + } } /* Cache result. */ res = resT | resE; if (st_insert(cache, (char *)key, (char *)(ptrint)res) == ST_OUT_OF_MEM) { - ABC_FREE(key); - return(CUDD_OUT_OF_MEM); + ABC_FREE(key); + return(CUDD_OUT_OF_MEM); } /* Take into account possible complementation. */ if (comple) { - if (res == DD_LIC_0) res = DD_LIC_1; - else if (res == DD_LIC_1) res = DD_LIC_0; + if (res == DD_LIC_0) res = DD_LIC_1; + else if (res == DD_LIC_1) res = DD_LIC_0; } return(res); @@ -1561,8 +1771,7 @@ cuddBddLICBuildResult( { DdNode *Fv, *Fnv, *r, *t, *e; DdNode *one, *zero; - unsigned int topf; - int index; + int index; int comple; int markT, markE, markings; @@ -1575,75 +1784,74 @@ cuddBddLICBuildResult( f = Cudd_Regular(f); /* Check the cache. */ - if (st_lookup(cache, (char *)f, (char **)&r)) { - return(Cudd_NotCond(r,comple)); + if (st_lookup(cache, (const char *)f, (char **)&r)) { + return(Cudd_NotCond(r,comple)); } /* Retrieve the edge markings. */ - if (st_lookup(table, (char *)f, (char **)&markings) == 0) - return(NULL); + if (st_lookup_int(table, (char *)f, &markings) == 0) + return(NULL); markT = markings >> 2; markE = markings & 3; - topf = dd->perm[f->index]; index = f->index; Fv = cuddT(f); Fnv = cuddE(f); if (markT == DD_LIC_NL) { - t = cuddBddLICBuildResult(dd,Fv,cache,table); - if (t == NULL) { - return(NULL); - } + t = cuddBddLICBuildResult(dd,Fv,cache,table); + if (t == NULL) { + return(NULL); + } } else if (markT == DD_LIC_1) { - t = one; + t = one; } else { - t = zero; + t = zero; } cuddRef(t); if (markE == DD_LIC_NL) { - e = cuddBddLICBuildResult(dd,Fnv,cache,table); - if (e == NULL) { - Cudd_IterDerefBdd(dd,t); - return(NULL); - } + e = cuddBddLICBuildResult(dd,Fnv,cache,table); + if (e == NULL) { + Cudd_IterDerefBdd(dd,t); + return(NULL); + } } else if (markE == DD_LIC_1) { - e = one; + e = one; } else { - e = zero; + e = zero; } cuddRef(e); if (markT == DD_LIC_DC && markE != DD_LIC_DC) { - r = e; + r = e; } else if (markT != DD_LIC_DC && markE == DD_LIC_DC) { - r = t; - } else { - if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - r = Cudd_Not(r); + r = t; } else { - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); + if (Cudd_IsComplement(t)) { + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } } - } cuddDeref(t); cuddDeref(e); if (st_insert(cache, (char *)f, (char *)r) == ST_OUT_OF_MEM) { - cuddRef(r); - Cudd_IterDerefBdd(dd,r); - return(NULL); + cuddRef(r); + Cudd_IterDerefBdd(dd,r); + return(NULL); } return(Cudd_NotCond(r,comple)); @@ -1669,9 +1877,9 @@ MarkCacheHash( int modulus) { int val = 0; - const MarkCacheKey *entry; + MarkCacheKey *entry; - entry = (const MarkCacheKey *) ptr; + entry = (MarkCacheKey *) ptr; val = (int) (ptrint) entry->f; val = val * 997 + (int) (ptrint) entry->c; @@ -1771,7 +1979,7 @@ cuddBddSqueeze( statLine(dd); if (l == u) { - return(l); + return(l); } one = DD_ONE(dd); zero = Cudd_Not(one); @@ -1785,11 +1993,11 @@ cuddBddSqueeze( /* Make canonical to increase the utilization of the cache. */ if (Cudd_IsComplement(u)) { - DdNode *temp; - temp = Cudd_Not(l); - l = Cudd_Not(u); - u = temp; - comple = 1; + DdNode *temp; + temp = Cudd_Not(l); + l = Cudd_Not(u); + u = temp; + comple = 1; } /* At this point u is regular and non-constant; l is non-constant, but ** may be complemented. */ @@ -1799,89 +2007,89 @@ cuddBddSqueeze( /* Check the cache. */ r = cuddCacheLookup2(dd, Cudd_bddSqueeze, l, u); if (r != NULL) { - return(Cudd_NotCond(r,comple)); + return(Cudd_NotCond(r,comple)); } /* Recursive step. */ topu = dd->perm[u->index]; topl = dd->perm[Cudd_Regular(l)->index]; if (topu <= topl) { - index = u->index; - ut = cuddT(u); ue = cuddE(u); + index = u->index; + ut = cuddT(u); ue = cuddE(u); } else { - index = Cudd_Regular(l)->index; - ut = ue = u; + index = Cudd_Regular(l)->index; + ut = ue = u; } if (topl <= topu) { - lt = cuddT(Cudd_Regular(l)); le = cuddE(Cudd_Regular(l)); - if (Cudd_IsComplement(l)) { - lt = Cudd_Not(lt); - le = Cudd_Not(le); - } + lt = cuddT(Cudd_Regular(l)); le = cuddE(Cudd_Regular(l)); + if (Cudd_IsComplement(l)) { + lt = Cudd_Not(lt); + le = Cudd_Not(le); + } } else { - lt = le = l; + lt = le = l; } /* If one interval is contained in the other, use the smaller ** interval. This corresponds to one-sided matching. */ if ((lt == zero || Cudd_bddLeq(dd,lt,le)) && - (ut == one || Cudd_bddLeq(dd,ue,ut))) { /* remap */ - r = cuddBddSqueeze(dd, le, ue); - if (r == NULL) - return(NULL); - return(Cudd_NotCond(r,comple)); + (ut == one || Cudd_bddLeq(dd,ue,ut))) { /* remap */ + r = cuddBddSqueeze(dd, le, ue); + if (r == NULL) + return(NULL); + return(Cudd_NotCond(r,comple)); } else if ((le == zero || Cudd_bddLeq(dd,le,lt)) && - (ue == one || Cudd_bddLeq(dd,ut,ue))) { /* remap */ - r = cuddBddSqueeze(dd, lt, ut); - if (r == NULL) - return(NULL); - return(Cudd_NotCond(r,comple)); + (ue == one || Cudd_bddLeq(dd,ut,ue))) { /* remap */ + r = cuddBddSqueeze(dd, lt, ut); + if (r == NULL) + return(NULL); + return(Cudd_NotCond(r,comple)); } else if ((le == zero || Cudd_bddLeq(dd,le,Cudd_Not(ut))) && - (ue == one || Cudd_bddLeq(dd,Cudd_Not(lt),ue))) { /* c-remap */ - t = cuddBddSqueeze(dd, lt, ut); - cuddRef(t); - if (Cudd_IsComplement(t)) { - r = cuddUniqueInter(dd, index, Cudd_Not(t), t); - if (r == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - r = Cudd_Not(r); - } else { - r = cuddUniqueInter(dd, index, t, Cudd_Not(t)); - if (r == NULL) { - Cudd_IterDerefBdd(dd, t); - return(NULL); + (ue == one || Cudd_bddLeq(dd,Cudd_Not(lt),ue))) { /* c-remap */ + t = cuddBddSqueeze(dd, lt, ut); + cuddRef(t); + if (Cudd_IsComplement(t)) { + r = cuddUniqueInter(dd, index, Cudd_Not(t), t); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); + } else { + r = cuddUniqueInter(dd, index, t, Cudd_Not(t)); + if (r == NULL) { + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } - } - cuddDeref(t); - if (r == NULL) - return(NULL); - cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); - return(Cudd_NotCond(r,comple)); + cuddDeref(t); + if (r == NULL) + return(NULL); + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); } else if ((lt == zero || Cudd_bddLeq(dd,lt,Cudd_Not(ue))) && - (ut == one || Cudd_bddLeq(dd,Cudd_Not(le),ut))) { /* c-remap */ - e = cuddBddSqueeze(dd, le, ue); - cuddRef(e); - if (Cudd_IsComplement(e)) { - r = cuddUniqueInter(dd, index, Cudd_Not(e), e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - return(NULL); + (ut == one || Cudd_bddLeq(dd,Cudd_Not(le),ut))) { /* c-remap */ + e = cuddBddSqueeze(dd, le, ue); + cuddRef(e); + if (Cudd_IsComplement(e)) { + r = cuddUniqueInter(dd, index, Cudd_Not(e), e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + } else { + r = cuddUniqueInter(dd, index, e, Cudd_Not(e)); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + return(NULL); + } + r = Cudd_Not(r); } - } else { - r = cuddUniqueInter(dd, index, e, Cudd_Not(e)); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - return(NULL); - } - r = Cudd_Not(r); - } - cuddDeref(e); - if (r == NULL) - return(NULL); - cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); - return(Cudd_NotCond(r,comple)); + cuddDeref(e); + if (r == NULL) + return(NULL); + cuddCacheInsert2(dd, Cudd_bddSqueeze, l, u, r); + return(Cudd_NotCond(r,comple)); } #if 0 @@ -1891,61 +2099,61 @@ cuddBddSqueeze( ** This approach corresponds to two-sided matching, and is very ** expensive. */ if (Cudd_bddLeq(dd,lt,ue) && Cudd_bddLeq(dd,le,ut)) { - DdNode *au, *al; - au = cuddBddAndRecur(dd,ut,ue); - if (au == NULL) - return(NULL); - cuddRef(au); - al = cuddBddAndRecur(dd,Cudd_Not(lt),Cudd_Not(le)); - if (al == NULL) { - Cudd_IterDerefBdd(dd,au); - return(NULL); - } - cuddRef(al); - al = Cudd_Not(al); - ar = cuddBddSqueeze(dd, al, au); - if (ar == NULL) { + DdNode *au, *al; + au = cuddBddAndRecur(dd,ut,ue); + if (au == NULL) + return(NULL); + cuddRef(au); + al = cuddBddAndRecur(dd,Cudd_Not(lt),Cudd_Not(le)); + if (al == NULL) { + Cudd_IterDerefBdd(dd,au); + return(NULL); + } + cuddRef(al); + al = Cudd_Not(al); + ar = cuddBddSqueeze(dd, al, au); + if (ar == NULL) { + Cudd_IterDerefBdd(dd,au); + Cudd_IterDerefBdd(dd,al); + return(NULL); + } + cuddRef(ar); Cudd_IterDerefBdd(dd,au); Cudd_IterDerefBdd(dd,al); - return(NULL); - } - cuddRef(ar); - Cudd_IterDerefBdd(dd,au); - Cudd_IterDerefBdd(dd,al); } else { - ar = NULL; + ar = NULL; } #endif t = cuddBddSqueeze(dd, lt, ut); if (t == NULL) { - return(NULL); + return(NULL); } cuddRef(t); e = cuddBddSqueeze(dd, le, ue); if (e == NULL) { - Cudd_IterDerefBdd(dd,t); - return(NULL); + Cudd_IterDerefBdd(dd,t); + return(NULL); } cuddRef(e); if (Cudd_IsComplement(t)) { - t = Cudd_Not(t); - e = Cudd_Not(e); - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } - r = Cudd_Not(r); + t = Cudd_Not(t); + e = Cudd_Not(e); + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } + r = Cudd_Not(r); } else { - r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); - if (r == NULL) { - Cudd_IterDerefBdd(dd, e); - Cudd_IterDerefBdd(dd, t); - return(NULL); - } + r = (t == e) ? t : cuddUniqueInter(dd, index, t, e); + if (r == NULL) { + Cudd_IterDerefBdd(dd, e); + Cudd_IterDerefBdd(dd, t); + return(NULL); + } } cuddDeref(t); cuddDeref(e); @@ -1955,12 +2163,12 @@ cuddBddSqueeze( ** it is better than the one obtained by recursion. */ cuddRef(r); if (ar != NULL) { - if (Cudd_DagSize(ar) <= Cudd_DagSize(r)) { - Cudd_IterDerefBdd(dd, r); - r = ar; - } else { - Cudd_IterDerefBdd(dd, ar); - } + if (Cudd_DagSize(ar) <= Cudd_DagSize(r)) { + Cudd_IterDerefBdd(dd, r); + r = ar; + } else { + Cudd_IterDerefBdd(dd, ar); + } } cuddDeref(r); #endif @@ -1969,5 +2177,7 @@ cuddBddSqueeze( return(Cudd_NotCond(r,comple)); } /* end of cuddBddSqueeze */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddGenetic.c b/src/bdd/cudd/cuddGenetic.c index d2739c85..8c168440 100644 --- a/src/bdd/cudd/cuddGenetic.c +++ b/src/bdd/cudd/cuddGenetic.c @@ -7,23 +7,23 @@ Synopsis [Genetic algorithm for variable reordering.] Description [Internal procedures included in this file: - <ul> - <li> cuddGa() - </ul> - Static procedures included in this module: - <ul> - <li> make_random() - <li> sift_up() - <li> build_dd() - <li> largest() - <li> rand_int() - <li> array_hash() - <li> array_compare() - <li> find_best() - <li> find_average_fitness() - <li> PMX() - <li> roulette() - </ul> + <ul> + <li> cuddGa() + </ul> + Static procedures included in this module: + <ul> + <li> make_random() + <li> sift_up() + <li> build_dd() + <li> largest() + <li> rand_int() + <li> array_hash() + <li> array_compare() + <li> find_best() + <li> find_average_fitness() + <li> PMX() + <li> roulette() + </ul> The genetic algorithm implemented here is as follows. We start with the current DD order. We sift this order and use this as the @@ -46,10 +46,37 @@ Author [Curt Musfeldt, Alan Shuler, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -59,6 +86,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -76,11 +104,11 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddGenetic.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddGenetic.c,v 1.28 2004/08/13 18:04:48 fabio Exp $"; #endif -static int popsize; /* the size of the population */ -static int numvars; /* the number of input variables in the ckt. */ +static int popsize; /* the size of the population */ +static int numvars; /* the number of input variables in the ckt. */ /* storedd stores the population orders and sizes. This table has two ** extra rows and one extras column. The two extra rows are used for the ** offspring produced by a crossover. Each row stores one order and its @@ -90,12 +118,12 @@ static int numvars; /* the number of input variables in the ckt. */ ** it is a two-dimensional structure. */ static int *storedd; -static st_table *computed; /* hash table to identify existing orders */ -static int *repeat; /* how many times an order is present */ -static int large; /* stores the index of the population with - ** the largest number of nodes in the DD */ +static st_table *computed; /* hash table to identify existing orders */ +static int *repeat; /* how many times an order is present */ +static int large; /* stores the index of the population with + ** the largest number of nodes in the DD */ static int result; -static int cross; /* the number of crossovers to perform */ +static int cross; /* the number of crossovers to perform */ /*---------------------------------------------------------------------------*/ /* Macro declarations */ @@ -106,6 +134,9 @@ static int cross; /* the number of crossovers to perform */ */ #define STOREDD(i,j) storedd[(i)*(numvars+1)+(j)] +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -113,20 +144,25 @@ static int cross; /* the number of crossovers to perform */ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int make_random ARGS((DdManager *table, int lower)); -static int sift_up ARGS((DdManager *table, int x, int x_low)); -static int build_dd ARGS((DdManager *table, int num, int lower, int upper)); -static int largest ARGS(()); -static int rand_int ARGS((int a)); -static int array_hash ARGS((const char *array, int modulus)); -static int array_compare ARGS((const char *array1, const char *array2)); -static int find_best ARGS(()); -static double find_average_fitness ARGS(()); -static int PMX ARGS((int maxvar)); -static int roulette ARGS((int *p1, int *p2)); +static int make_random (DdManager *table, int lower); +static int sift_up (DdManager *table, int x, int x_low); +static int build_dd (DdManager *table, int num, int lower, int upper); +static int largest (void); +static int rand_int (int a); +static int array_hash (const char *array, int modulus); +static int array_compare (const char *array1, const char *array2); +static int find_best (void); +#ifdef DD_STATS +static double find_average_fitness (void); +#endif +static int PMX (int maxvar); +static int roulette (int *p1, int *p2); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -158,10 +194,12 @@ cuddGa( int lower /* lowest level to be reordered */, int upper /* highest level to be reorderded */) { - int i,n,m; /* dummy/loop vars */ - int index; - double average_fitness; - int small; /* index of smallest DD in population */ + int i,n,m; /* dummy/loop vars */ + int index; +#ifdef DD_STATS + double average_fitness; +#endif + int small; /* index of smallest DD in population */ /* Do an initial sifting to produce at least one reasonable individual. */ if (!cuddSifting(table,lower,upper)) return(0); @@ -169,20 +207,20 @@ cuddGa( /* Get the initial values. */ numvars = upper - lower + 1; /* number of variables to be reordered */ if (table->populationSize == 0) { - popsize = 3 * numvars; /* population size is 3 times # of vars */ - if (popsize > 120) { - popsize = 120; /* Maximum population size is 120 */ - } + popsize = 3 * numvars; /* population size is 3 times # of vars */ + if (popsize > 120) { + popsize = 120; /* Maximum population size is 120 */ + } } else { - popsize = table->populationSize; /* user specified value */ + popsize = table->populationSize; /* user specified value */ } - if (popsize < 4) popsize = 4; /* enforce minimum population size */ + if (popsize < 4) popsize = 4; /* enforce minimum population size */ /* Allocate population table. */ storedd = ABC_ALLOC(int,(popsize+2)*(numvars+1)); if (storedd == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } /* Initialize the computed table. This table is made up of two data @@ -195,39 +233,39 @@ cuddGa( */ repeat = ABC_ALLOC(int,popsize); if (repeat == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(storedd); - return(0); + table->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(storedd); + return(0); } for (i = 0; i < popsize; i++) { - repeat[i] = 0; + repeat[i] = 0; } computed = st_init_table(array_compare,array_hash); if (computed == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(storedd); - ABC_FREE(repeat); - return(0); + table->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(storedd); + ABC_FREE(repeat); + return(0); } /* Copy the current DD and its size to the population table. */ for (i = 0; i < numvars; i++) { - STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */ + STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */ } STOREDD(0,numvars) = table->keys - table->isolated; /* size of initial DD */ /* Store the initial order in the computed table. */ if (st_insert(computed,(char *)storedd,(char *) 0) == ST_OUT_OF_MEM) { - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); } repeat[0]++; /* Insert the reverse order as second element of the population. */ for (i = 0; i < numvars; i++) { - STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */ + STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */ } /* Now create the random orders. make_random fills the population @@ -236,32 +274,32 @@ cuddGa( ** the results in the computed table. */ if (!make_random(table,lower)) { - table->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); - } - for (i = 1; i < popsize; i++) { - result = build_dd(table,i,lower,upper); /* build and sift order */ - if (!result) { + table->errorCode = CUDD_MEMORY_OUT; ABC_FREE(storedd); ABC_FREE(repeat); st_free_table(computed); return(0); } - if (st_lookup(computed,(char *)&STOREDD(i,0),(char **)&index)) { - repeat[index]++; - } else { - if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) == - ST_OUT_OF_MEM) { - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); + for (i = 1; i < popsize; i++) { + result = build_dd(table,i,lower,upper); /* build and sift order */ + if (!result) { + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); + } + if (st_lookup_int(computed,(char *)&STOREDD(i,0),&index)) { + repeat[index]++; + } else { + if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) == + ST_OUT_OF_MEM) { + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[i]++; } - repeat[i]++; - } } #if 0 @@ -269,104 +307,104 @@ cuddGa( /* Print the initial population. */ (void) fprintf(table->out,"Initial population after sifting\n"); for (m = 0; m < popsize; m++) { - for (i = 0; i < numvars; i++) { - (void) fprintf(table->out," %2d",STOREDD(m,i)); - } - (void) fprintf(table->out," : %3d (%d)\n", - STOREDD(m,numvars),repeat[m]); + for (i = 0; i < numvars; i++) { + (void) fprintf(table->out," %2d",STOREDD(m,i)); + } + (void) fprintf(table->out," : %3d (%d)\n", + STOREDD(m,numvars),repeat[m]); } #endif #endif small = find_best(); - average_fitness = find_average_fitness(); #ifdef DD_STATS + average_fitness = find_average_fitness(); (void) fprintf(table->out,"\nInitial population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness); #endif /* Decide how many crossovers should be tried. */ if (table->numberXovers == 0) { - cross = 3*numvars; - if (cross > 60) { /* do a maximum of 50 crossovers */ - cross = 60; - } + cross = 3*numvars; + if (cross > 60) { /* do a maximum of 50 crossovers */ + cross = 60; + } } else { - cross = table->numberXovers; /* use user specified value */ + cross = table->numberXovers; /* use user specified value */ } /* Perform the crossovers to get the best order. */ for (m = 0; m < cross; m++) { - if (!PMX(table->size)) { /* perform one crossover */ - table->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); - } - /* The offsprings are left in the last two entries of the - ** population table. These are now considered in turn. - */ - for (i = popsize; i <= popsize+1; i++) { - result = build_dd(table,i,lower,upper); /* build and sift child */ - if (!result) { - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); - } - large = largest(); /* find the largest DD in population */ - - /* If the new child is smaller than the largest DD in the current - ** population, enter it into the population in place of the - ** largest DD. - */ - if (STOREDD(i,numvars) < STOREDD(large,numvars)) { - /* Look up the largest DD in the computed table. - ** Decrease its repetition count. If the repetition count - ** goes to 0, remove the largest DD from the computed table. - */ - result = st_lookup(computed,(char *)&STOREDD(large,0),(char - **)&index); - if (!result) { + if (!PMX(table->size)) { /* perform one crossover */ + table->errorCode = CUDD_MEMORY_OUT; ABC_FREE(storedd); ABC_FREE(repeat); st_free_table(computed); return(0); } - repeat[index]--; - if (repeat[index] == 0) { - int *pointer = &STOREDD(index,0); - result = st_delete(computed, (const char **)&pointer,NULL); + /* The offsprings are left in the last two entries of the + ** population table. These are now considered in turn. + */ + for (i = popsize; i <= popsize+1; i++) { + result = build_dd(table,i,lower,upper); /* build and sift child */ if (!result) { - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); } - } - /* Copy the new individual to the entry of the - ** population table just made available and update the - ** computed table. - */ - for (n = 0; n <= numvars; n++) { - STOREDD(large,n) = STOREDD(i,n); - } - if (st_lookup(computed,(char *)&STOREDD(large,0),(char - **)&index)) { - repeat[index]++; - } else { - if (st_insert(computed,(char *)&STOREDD(large,0), - (char *)(long)large) == ST_OUT_OF_MEM) { - ABC_FREE(storedd); - ABC_FREE(repeat); - st_free_table(computed); - return(0); + large = largest(); /* find the largest DD in population */ + + /* If the new child is smaller than the largest DD in the current + ** population, enter it into the population in place of the + ** largest DD. + */ + if (STOREDD(i,numvars) < STOREDD(large,numvars)) { + /* Look up the largest DD in the computed table. + ** Decrease its repetition count. If the repetition count + ** goes to 0, remove the largest DD from the computed table. + */ + result = st_lookup_int(computed,(char *)&STOREDD(large,0), + &index); + if (!result) { + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[index]--; + if (repeat[index] == 0) { + int *pointer = &STOREDD(index,0); + result = st_delete(computed, (const char **)&pointer, NULL); + if (!result) { + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); + } + } + /* Copy the new individual to the entry of the + ** population table just made available and update the + ** computed table. + */ + for (n = 0; n <= numvars; n++) { + STOREDD(large,n) = STOREDD(i,n); + } + if (st_lookup_int(computed,(char *)&STOREDD(large,0), + &index)) { + repeat[index]++; + } else { + if (st_insert(computed,(char *)&STOREDD(large,0), + (char *)(long)large) == ST_OUT_OF_MEM) { + ABC_FREE(storedd); + ABC_FREE(repeat); + st_free_table(computed); + return(0); + } + repeat[large]++; + } } - repeat[large]++; - } } } - } /* Find the smallest DD in the population and build it; ** that will be the result. @@ -412,47 +450,47 @@ make_random( DdManager * table, int lower) { - int i,j; /* loop variables */ - int *used; /* is a number already in a permutation */ - int next; /* next random number without repetitions */ + int i,j; /* loop variables */ + int *used; /* is a number already in a permutation */ + int next; /* next random number without repetitions */ used = ABC_ALLOC(int,numvars); if (used == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } #if 0 #ifdef DD_STATS (void) fprintf(table->out,"Initial population before sifting\n"); for (i = 0; i < 2; i++) { - for (j = 0; j < numvars; j++) { - (void) fprintf(table->out," %2d",STOREDD(i,j)); - } - (void) fprintf(table->out,"\n"); + for (j = 0; j < numvars; j++) { + (void) fprintf(table->out," %2d",STOREDD(i,j)); + } + (void) fprintf(table->out,"\n"); } #endif #endif for (i = 2; i < popsize; i++) { - for (j = 0; j < numvars; j++) { - used[j] = 0; - } - /* Generate a permutation of {0...numvars-1} and use it to - ** permute the variables in the layesr from lower to upper. - */ - for (j = 0; j < numvars; j++) { - do { - next = rand_int(numvars-1); - } while (used[next] != 0); - used[next] = 1; - STOREDD(i,j) = table->invperm[next+lower]; - } + for (j = 0; j < numvars; j++) { + used[j] = 0; + } + /* Generate a permutation of {0...numvars-1} and use it to + ** permute the variables in the layesr from lower to upper. + */ + for (j = 0; j < numvars; j++) { + do { + next = rand_int(numvars-1); + } while (used[next] != 0); + used[next] = 1; + STOREDD(i,j) = table->invperm[next+lower]; + } #if 0 #ifdef DD_STATS - /* Print the order just generated. */ - for (j = 0; j < numvars; j++) { - (void) fprintf(table->out," %2d",STOREDD(i,j)); - } - (void) fprintf(table->out,"\n"); + /* Print the order just generated. */ + for (j = 0; j < numvars; j++) { + (void) fprintf(table->out," %2d",STOREDD(i,j)); + } + (void) fprintf(table->out,"\n"); #endif #endif } @@ -486,12 +524,12 @@ sift_up( y = cuddNextLow(table,x); while (y >= x_low) { - size = cuddSwapInPlace(table,y,x); - if (size == 0) { - return(0); - } - x = y; - y = cuddNextLow(table,x); + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); } return(1); @@ -518,21 +556,21 @@ build_dd( int lower, int upper) { - int i,j; /* loop vars */ - int position; - int index; - int limit; /* how large the DD for this order can grow */ - int size; + int i,j; /* loop vars */ + int position; + int index; + int limit; /* how large the DD for this order can grow */ + int size; /* Check the computed table. If the order already exists, it ** suffices to copy the size from the existing entry. */ - if (computed && st_lookup(computed,(char *)&STOREDD(num,0),(char **)&index)) { - STOREDD(num,numvars) = STOREDD(index,numvars); + if (computed && st_lookup_int(computed,(char *)&STOREDD(num,0),&index)) { + STOREDD(num,numvars) = STOREDD(index,numvars); #ifdef DD_STATS - (void) fprintf(table->out,"\nCache hit for index %d", index); + (void) fprintf(table->out,"\nCache hit for index %d", index); #endif - return(1); + return(1); } /* Stop if the DD grows 20 times larges than the reference size. */ @@ -544,12 +582,12 @@ build_dd( ** up to the second position, and so on. */ for (j = 0; j < numvars; j++) { - i = STOREDD(num,j); - position = table->perm[i]; - result = sift_up(table,position,j+lower); - if (!result) return(0); - size = table->keys - table->isolated; - if (size > limit) break; + i = STOREDD(num,j); + position = table->perm[i]; + result = sift_up(table,position,j+lower); + if (!result) return(0); + size = table->keys - table->isolated; + if (size > limit) break; } /* Sift the DD just built. */ @@ -561,7 +599,7 @@ build_dd( /* Copy order and size to table. */ for (j = 0; j < numvars; j++) { - STOREDD(num,j) = table->invperm[lower+j]; + STOREDD(num,j) = table->invperm[lower+j]; } STOREDD(num,numvars) = table->keys - table->isolated; /* size of new DD */ return(1); @@ -583,18 +621,17 @@ build_dd( ******************************************************************************/ static int -largest( - ) +largest(void) { - int i; /* loop var */ + int i; /* loop var */ int big; /* temporary holder to return result */ big = 0; while (repeat[big] > 1) big++; for (i = big + 1; i < popsize; i++) { - if (STOREDD(i,numvars) >= STOREDD(big,numvars) && repeat[i] <= 1) { - big = i; - } + if (STOREDD(i,numvars) >= STOREDD(big,numvars) && repeat[i] <= 1) { + big = i; + } } return(big); @@ -640,12 +677,12 @@ array_hash( { int val = 0; int i; - const int *intarray; + int *intarray; - intarray = (const int *) array; + intarray = (int *) array; for (i = 0; i < numvars; i++) { - val = val * 997 + intarray[i]; + val = val * 997 + intarray[i]; } return ((val < 0) ? -val : val) % modulus; @@ -677,7 +714,7 @@ array_compare( intarray2 = (int *) array2; for (i = 0; i < numvars; i++) { - if (intarray1[i] != intarray2[i]) return(1); + if (intarray1[i] != intarray2[i]) return(1); } return(0); @@ -696,16 +733,15 @@ array_compare( ******************************************************************************/ static int -find_best( - ) +find_best(void) { int i,small; small = 0; for (i = 1; i < popsize; i++) { - if (STOREDD(i,numvars) < STOREDD(small,numvars)) { - small = i; - } + if (STOREDD(i,numvars) < STOREDD(small,numvars)) { + small = i; + } } return(small); @@ -723,21 +759,22 @@ find_best( SeeAlso [] ******************************************************************************/ +#ifdef DD_STATS static double -find_average_fitness( - ) +find_average_fitness(void) { int i; int total_fitness = 0; double average_fitness; for (i = 0; i < popsize; i++) { - total_fitness += STOREDD(i,numvars); + total_fitness += STOREDD(i,numvars); } average_fitness = (double) total_fitness / (double) popsize; return(average_fitness); } /* end of find_average_fitness */ +#endif /**Function******************************************************************** @@ -757,28 +794,28 @@ static int PMX( int maxvar) { - int cut1,cut2; /* the two cut positions (random) */ - int mom,dad; /* the two randomly chosen parents */ - int *inv1; /* inverse permutations for repair algo */ - int *inv2; - int i; /* loop vars */ - int u,v; /* aux vars */ + int cut1,cut2; /* the two cut positions (random) */ + int mom,dad; /* the two randomly chosen parents */ + int *inv1; /* inverse permutations for repair algo */ + int *inv2; + int i; /* loop vars */ + int u,v; /* aux vars */ inv1 = ABC_ALLOC(int,maxvar); if (inv1 == NULL) { - return(0); + return(0); } inv2 = ABC_ALLOC(int,maxvar); if (inv2 == NULL) { - ABC_FREE(inv1); - return(0); + ABC_FREE(inv1); + return(0); } /* Choose two orders from the population using roulette wheel. */ if (!roulette(&mom,&dad)) { - ABC_FREE(inv1); - ABC_FREE(inv2); - return(0); + ABC_FREE(inv1); + ABC_FREE(inv2); + return(0); } /* Choose two random cut positions. A cut in position i means that @@ -788,68 +825,68 @@ PMX( */ cut1 = rand_int(numvars-1); do { - cut2 = rand_int(numvars-1); + cut2 = rand_int(numvars-1); } while (cut1 == cut2); #if 0 /* Print out the parents. */ (void) fprintf(table->out, - "Crossover of %d (mom) and %d (dad) between %d and %d\n", - mom,dad,cut1,cut2); + "Crossover of %d (mom) and %d (dad) between %d and %d\n", + mom,dad,cut1,cut2); for (i = 0; i < numvars; i++) { - if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); - (void) fprintf(table->out,"%2d ",STOREDD(mom,i)); + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(mom,i)); } (void) fprintf(table->out,"\n"); for (i = 0; i < numvars; i++) { - if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); - (void) fprintf(table->out,"%2d ",STOREDD(dad,i)); + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(dad,i)); } (void) fprintf(table->out,"\n"); #endif /* Initialize the inverse permutations: -1 means yet undetermined. */ for (i = 0; i < maxvar; i++) { - inv1[i] = -1; - inv2[i] = -1; + inv1[i] = -1; + inv2[i] = -1; } /* Copy the portions whithin the cuts. */ for (i = cut1; i != cut2; i = (i == numvars-1) ? 0 : i+1) { - STOREDD(popsize,i) = STOREDD(dad,i); - inv1[STOREDD(popsize,i)] = i; - STOREDD(popsize+1,i) = STOREDD(mom,i); - inv2[STOREDD(popsize+1,i)] = i; + STOREDD(popsize,i) = STOREDD(dad,i); + inv1[STOREDD(popsize,i)] = i; + STOREDD(popsize+1,i) = STOREDD(mom,i); + inv2[STOREDD(popsize+1,i)] = i; } /* Now apply the repair algorithm outside the cuts. */ for (i = cut2; i != cut1; i = (i == numvars-1 ) ? 0 : i+1) { - v = i; - do { - u = STOREDD(mom,v); - v = inv1[u]; - } while (v != -1); - STOREDD(popsize,i) = u; - inv1[u] = i; - v = i; - do { - u = STOREDD(dad,v); - v = inv2[u]; - } while (v != -1); - STOREDD(popsize+1,i) = u; - inv2[u] = i; + v = i; + do { + u = STOREDD(mom,v); + v = inv1[u]; + } while (v != -1); + STOREDD(popsize,i) = u; + inv1[u] = i; + v = i; + do { + u = STOREDD(dad,v); + v = inv2[u]; + } while (v != -1); + STOREDD(popsize+1,i) = u; + inv2[u] = i; } #if 0 /* Print the results of crossover. */ for (i = 0; i < numvars; i++) { - if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); - (void) fprintf(table->out,"%2d ",STOREDD(popsize,i)); + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(popsize,i)); } (void) fprintf(table->out,"\n"); for (i = 0; i < numvars; i++) { - if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); - (void) fprintf(table->out,"%2d ",STOREDD(popsize+1,i)); + if (i == cut1 || i == cut2) (void) fprintf(table->out,"|"); + (void) fprintf(table->out,"%2d ",STOREDD(popsize+1,i)); } (void) fprintf(table->out,"\n"); #endif @@ -884,14 +921,14 @@ roulette( wheel = ABC_ALLOC(double,popsize); if (wheel == NULL) { - return(0); + return(0); } /* The fitness of an individual is the reciprocal of its size. */ wheel[0] = 1.0 / (double) STOREDD(0,numvars); for (i = 1; i < popsize; i++) { - wheel[i] = wheel[i-1] + 1.0 / (double) STOREDD(i,numvars); + wheel[i] = wheel[i-1] + 1.0 / (double) STOREDD(i,numvars); } /* Get a random number between 0 and wheel[popsize-1] (that is, @@ -902,7 +939,7 @@ roulette( /* Find the lucky element by scanning the wheel. */ for (i = 0; i < popsize; i++) { - if (spin <= wheel[i]) break; + if (spin <= wheel[i]) break; } *p1 = i; @@ -910,10 +947,10 @@ roulette( ** distinct from the first. */ do { - spin = wheel[popsize-1] * (double) Cudd_Random() / 2147483561.0; - for (i = 0; i < popsize; i++) { - if (spin <= wheel[i]) break; - } + spin = wheel[popsize-1] * (double) Cudd_Random() / 2147483561.0; + for (i = 0; i < popsize; i++) { + if (spin <= wheel[i]) break; + } } while (i == *p1); *p2 = i; @@ -922,5 +959,7 @@ roulette( } /* end of roulette */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddGroup.c b/src/bdd/cudd/cuddGroup.c index 8e637603..fc848259 100644 --- a/src/bdd/cudd/cuddGroup.c +++ b/src/bdd/cudd/cuddGroup.c @@ -7,45 +7,72 @@ Synopsis [Functions for group sifting.] Description [External procedures included in this file: - <ul> - <li> Cudd_MakeTreeNode() - </ul> - Internal procedures included in this file: - <ul> - <li> cuddTreeSifting() - </ul> - Static procedures included in this module: - <ul> - <li> ddTreeSiftingAux() - <li> ddCountInternalMtrNodes() - <li> ddReorderChildren() - <li> ddFindNodeHiLo() - <li> ddUniqueCompareGroup() - <li> ddGroupSifting() - <li> ddCreateGroup() - <li> ddGroupSiftingAux() - <li> ddGroupSiftingUp() - <li> ddGroupSiftingDown() - <li> ddGroupMove() - <li> ddGroupMoveBackward() - <li> ddGroupSiftingBackward() - <li> ddMergeGroups() - <li> ddDissolveGroup() - <li> ddNoCheck() - <li> ddSecDiffCheck() - <li> ddExtSymmCheck() - <li> ddVarGroupCheck() - <li> ddSetVarHandled() - <li> ddResetVarHandled() - <li> ddIsVarHandled() - </ul>] + <ul> + <li> Cudd_MakeTreeNode() + </ul> + Internal procedures included in this file: + <ul> + <li> cuddTreeSifting() + </ul> + Static procedures included in this module: + <ul> + <li> ddTreeSiftingAux() + <li> ddCountInternalMtrNodes() + <li> ddReorderChildren() + <li> ddFindNodeHiLo() + <li> ddUniqueCompareGroup() + <li> ddGroupSifting() + <li> ddCreateGroup() + <li> ddGroupSiftingAux() + <li> ddGroupSiftingUp() + <li> ddGroupSiftingDown() + <li> ddGroupMove() + <li> ddGroupMoveBackward() + <li> ddGroupSiftingBackward() + <li> ddMergeGroups() + <li> ddDissolveGroup() + <li> ddNoCheck() + <li> ddSecDiffCheck() + <li> ddExtSymmCheck() + <li> ddVarGroupCheck() + <li> ddSetVarHandled() + <li> ddResetVarHandled() + <li> ddIsVarHandled() + </ul>] Author [Shipra Panda, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -55,17 +82,18 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ /* Constants for lazy sifting */ -#define DD_NORMAL_SIFT 0 -#define DD_LAZY_SIFT 1 +#define DD_NORMAL_SIFT 0 +#define DD_LAZY_SIFT 1 /* Constants for sifting up and down */ -#define DD_SIFT_DOWN 0 -#define DD_SIFT_UP 1 +#define DD_SIFT_DOWN 0 +#define DD_SIFT_UP 1 /*---------------------------------------------------------------------------*/ /* Stucture declarations */ @@ -75,18 +103,26 @@ ABC_NAMESPACE_IMPL_START /* Type declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + typedef int (*DD_CHKFP)(DdManager *, int, int); +#ifdef __cplusplus +} +#endif + /*---------------------------------------------------------------------------*/ /* Variable declarations */ /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddGroup.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddGroup.c,v 1.44 2009/02/21 18:24:10 fabio Exp $"; #endif -static int *entry; -extern int ddTotalNumberSwapping; +static int *entry; +extern int ddTotalNumberSwapping; #ifdef DD_STATS -extern int ddTotalNISwaps; +extern int ddTotalNISwaps; static int extsymmcalls; static int extsymm; static int secdiffcalls; @@ -94,49 +130,55 @@ static int secdiff; static int secdiffmisfire; #endif #ifdef DD_DEBUG -static int pr = 0; /* flag to enable printing while debugging */ - /* by depositing a 1 into it */ +static int pr = 0; /* flag to enable printing while debugging */ + /* by depositing a 1 into it */ #endif -static int originalSize; -static int originalLevel; +static unsigned int originalSize; /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + /**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int ddTreeSiftingAux ARGS((DdManager *table, MtrNode *treenode, Cudd_ReorderingType method, int TimeStop)); +static int ddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); #ifdef DD_STATS -static int ddCountInternalMtrNodes ARGS((DdManager *table, MtrNode *treenode)); +static int ddCountInternalMtrNodes (DdManager *table, MtrNode *treenode); #endif -static int ddReorderChildren ARGS((DdManager *table, MtrNode *treenode, Cudd_ReorderingType method, int TimeStop)); -static void ddFindNodeHiLo ARGS((DdManager *table, MtrNode *treenode, int *lower, int *upper)); -static int ddUniqueCompareGroup ARGS((int *ptrX, int *ptrY)); -static int ddGroupSifting ARGS((DdManager *table, int lower, int upper, int (*checkFunction)(DdManager *, int, int), int lazyFlag)); -static void ddCreateGroup ARGS((DdManager *table, int x, int y)); -static int ddGroupSiftingAux ARGS((DdManager *table, int x, int xLow, int xHigh, int (*checkFunction)(DdManager *, int, int), int lazyFlag)); -static int ddGroupSiftingUp ARGS((DdManager *table, int y, int xLow, int (*checkFunction)(DdManager *, int, int), Move **moves)); -static int ddGroupSiftingDown ARGS((DdManager *table, int x, int xHigh, int (*checkFunction)(DdManager *, int, int), Move **moves)); -static int ddGroupMove ARGS((DdManager *table, int x, int y, Move **moves)); -static int ddGroupMoveBackward ARGS((DdManager *table, int x, int y)); -static int ddGroupSiftingBackward ARGS((DdManager *table, Move *moves, int size, int upFlag, int lazyFlag)); -static void ddMergeGroups ARGS((DdManager *table, MtrNode *treenode, int low, int high)); -static void ddDissolveGroup ARGS((DdManager *table, int x, int y)); -static int ddNoCheck ARGS((DdManager *table, int x, int y)); -static int ddSecDiffCheck ARGS((DdManager *table, int x, int y)); -static int ddExtSymmCheck ARGS((DdManager *table, int x, int y)); -static int ddVarGroupCheck ARGS((DdManager * table, int x, int y)); -static int ddSetVarHandled ARGS((DdManager *dd, int index)); -static int ddResetVarHandled ARGS((DdManager *dd, int index)); -static int ddIsVarHandled ARGS((DdManager *dd, int index)); +static int ddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +static void ddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper); +static int ddUniqueCompareGroup (int *ptrX, int *ptrY); +static int ddGroupSifting (DdManager *table, int lower, int upper, DD_CHKFP checkFunction, int lazyFlag); +static void ddCreateGroup (DdManager *table, int x, int y); +static int ddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh, DD_CHKFP checkFunction, int lazyFlag); +static int ddGroupSiftingUp (DdManager *table, int y, int xLow, DD_CHKFP checkFunction, Move **moves); +static int ddGroupSiftingDown (DdManager *table, int x, int xHigh, DD_CHKFP checkFunction, Move **moves); +static int ddGroupMove (DdManager *table, int x, int y, Move **moves); +static int ddGroupMoveBackward (DdManager *table, int x, int y); +static int ddGroupSiftingBackward (DdManager *table, Move *moves, int size, int upFlag, int lazyFlag); +static void ddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high); +static void ddDissolveGroup (DdManager *table, int x, int y); +static int ddNoCheck (DdManager *table, int x, int y); +static int ddSecDiffCheck (DdManager *table, int x, int y); +static int ddExtSymmCheck (DdManager *table, int x, int y); +static int ddVarGroupCheck (DdManager * table, int x, int y); +static int ddSetVarHandled (DdManager *dd, int index); +static int ddResetVarHandled (DdManager *dd, int index); +static int ddIsVarHandled (DdManager *dd, int index); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -179,15 +221,15 @@ Cudd_MakeTreeNode( level = (low < (unsigned int) dd->size) ? dd->perm[low] : low; if (level + size - 1> (int) MTR_MAXHIGH) - return(NULL); + return(NULL); /* If the tree does not exist yet, create it. */ tree = dd->tree; if (tree == NULL) { - dd->tree = tree = Mtr_InitGroupTree(0, dd->size); - if (tree == NULL) - return(NULL); - tree->index = dd->invperm[0]; + dd->tree = tree = Mtr_InitGroupTree(0, dd->size); + if (tree == NULL) + return(NULL); + tree->index = dd->invperm[0]; } /* Extend the upper bound of the tree if necessary. This allows the @@ -198,7 +240,7 @@ Cudd_MakeTreeNode( /* Create the group. */ group = Mtr_MakeGroup(tree, level, size, type); if (group == NULL) - return(NULL); + return(NULL); /* Initialize the index field to the index of the variable currently ** in position low. This field will be updated by the reordering @@ -231,8 +273,7 @@ Cudd_MakeTreeNode( int cuddTreeSifting( DdManager * table /* DD table */, - Cudd_ReorderingType method /* reordering method for the groups of leaves */, - int TimeStop) + Cudd_ReorderingType method /* reordering method for the groups of leaves */) { int i; int nvars; @@ -245,8 +286,8 @@ cuddTreeSifting( */ tempTree = table->tree == NULL; if (tempTree) { - table->tree = Mtr_InitGroupTree(0,table->size); - table->tree->index = table->invperm[0]; + table->tree = Mtr_InitGroupTree(0,table->size); + table->tree->index = table->invperm[0]; } nvars = table->size; @@ -264,8 +305,8 @@ cuddTreeSifting( (void) fprintf(table->out,"\n"); if (!tempTree) - (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", - ddCountInternalMtrNodes(table,table->tree)); + (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", + ddCountInternalMtrNodes(table,table->tree)); #endif /* Initialize the group of each subtable to itself. Initially @@ -277,25 +318,25 @@ cuddTreeSifting( /* Reorder. */ - result = ddTreeSiftingAux(table, table->tree, method, TimeStop); + result = ddTreeSiftingAux(table, table->tree, method); -#ifdef DD_STATS /* print stats */ +#ifdef DD_STATS /* print stats */ if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && - (table->groupcheck == CUDD_GROUP_CHECK7 || - table->groupcheck == CUDD_GROUP_CHECK5)) { - (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); - (void) fprintf(table->out,"extsymm = %d",extsymm); + (table->groupcheck == CUDD_GROUP_CHECK7 || + table->groupcheck == CUDD_GROUP_CHECK5)) { + (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); + (void) fprintf(table->out,"extsymm = %d",extsymm); } if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && - table->groupcheck == CUDD_GROUP_CHECK7) { - (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); - (void) fprintf(table->out,"secdiff = %d\n",secdiff); - (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); + table->groupcheck == CUDD_GROUP_CHECK7) { + (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); + (void) fprintf(table->out,"secdiff = %d\n",secdiff); + (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); } #endif if (tempTree) - Cudd_FreeTree(table); + Cudd_FreeTree(table); return(result); } /* end of cuddTreeSifting */ @@ -320,8 +361,7 @@ static int ddTreeSiftingAux( DdManager * table, MtrNode * treenode, - Cudd_ReorderingType method, - int TimeStop) + Cudd_ReorderingType method) { MtrNode *auxnode; int res; @@ -333,24 +373,24 @@ ddTreeSiftingAux( auxnode = treenode; while (auxnode != NULL) { - if (auxnode->child != NULL) { - if (!ddTreeSiftingAux(table, auxnode->child, method, TimeStop)) - return(0); - saveCheck = table->groupcheck; - table->groupcheck = CUDD_NO_CHECK; - if (method != CUDD_REORDER_LAZY_SIFT) - res = ddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT, TimeStop); - else - res = ddReorderChildren(table, auxnode, CUDD_REORDER_LAZY_SIFT, TimeStop); - table->groupcheck = saveCheck; - - if (res == 0) - return(0); - } else if (auxnode->size > 1) { - if (!ddReorderChildren(table, auxnode, method, TimeStop)) - return(0); - } - auxnode = auxnode->younger; + if (auxnode->child != NULL) { + if (!ddTreeSiftingAux(table, auxnode->child, method)) + return(0); + saveCheck = table->groupcheck; + table->groupcheck = CUDD_NO_CHECK; + if (method != CUDD_REORDER_LAZY_SIFT) + res = ddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); + else + res = ddReorderChildren(table, auxnode, CUDD_REORDER_LAZY_SIFT); + table->groupcheck = saveCheck; + + if (res == 0) + return(0); + } else if (auxnode->size > 1) { + if (!ddReorderChildren(table, auxnode, method)) + return(0); + } + auxnode = auxnode->younger; } return(1); @@ -381,12 +421,12 @@ ddCountInternalMtrNodes( nodeCount = 0; auxnode = treenode; while (auxnode != NULL) { - if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { - nodeCount++; - count = ddCountInternalMtrNodes(table,auxnode->child); - nodeCount += count; - } - auxnode = auxnode->younger; + if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { + nodeCount++; + count = ddCountInternalMtrNodes(table,auxnode->child); + nodeCount += count; + } + auxnode = auxnode->younger; } return(nodeCount); @@ -413,8 +453,7 @@ static int ddReorderChildren( DdManager * table, MtrNode * treenode, - Cudd_ReorderingType method, - int TimeStop) + Cudd_ReorderingType method) { int lower; int upper; @@ -424,125 +463,125 @@ ddReorderChildren( ddFindNodeHiLo(table,treenode,&lower,&upper); /* If upper == -1 these variables do not exist yet. */ if (upper == -1) - return(1); + return(1); if (treenode->flags == MTR_FIXED) { - result = 1; + result = 1; } else { #ifdef DD_STATS - (void) fprintf(table->out," "); + (void) fprintf(table->out," "); #endif - switch (method) { - case CUDD_REORDER_RANDOM: - case CUDD_REORDER_RANDOM_PIVOT: - result = cuddSwapping(table,lower,upper,method); - break; - case CUDD_REORDER_SIFT: - result = cuddSifting(table,lower,upper); - break; - case CUDD_REORDER_SIFT_CONVERGE: - do { - initialSize = table->keys - table->isolated; - result = cuddSifting(table,lower,upper); - if (initialSize <= table->keys - table->isolated) + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + result = cuddSwapping(table,lower,upper,method); break; + case CUDD_REORDER_SIFT: + result = cuddSifting(table,lower,upper); + break; + case CUDD_REORDER_SIFT_CONVERGE: + do { + initialSize = table->keys - table->isolated; + result = cuddSifting(table,lower,upper); + if (initialSize <= table->keys - table->isolated) + break; #ifdef DD_STATS - else - (void) fprintf(table->out,"\n"); + else + (void) fprintf(table->out,"\n"); #endif - } while (result != 0); - break; - case CUDD_REORDER_SYMM_SIFT: - result = cuddSymmSifting(table,lower,upper,TimeStop); - break; - case CUDD_REORDER_SYMM_SIFT_CONV: - result = cuddSymmSiftingConv(table,lower,upper); - break; - case CUDD_REORDER_GROUP_SIFT: - if (table->groupcheck == CUDD_NO_CHECK) { - result = ddGroupSifting(table,lower,upper,ddNoCheck, - DD_NORMAL_SIFT); - } else if (table->groupcheck == CUDD_GROUP_CHECK5) { - result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, - DD_NORMAL_SIFT); - } else if (table->groupcheck == CUDD_GROUP_CHECK7) { - result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, - DD_NORMAL_SIFT); - } else { - (void) fprintf(table->err, - "Unknown group ckecking method\n"); - result = 0; - } - break; - case CUDD_REORDER_GROUP_SIFT_CONV: - do { - initialSize = table->keys - table->isolated; - if (table->groupcheck == CUDD_NO_CHECK) { - result = ddGroupSifting(table,lower,upper,ddNoCheck, - DD_NORMAL_SIFT); - } else if (table->groupcheck == CUDD_GROUP_CHECK5) { - result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, - DD_NORMAL_SIFT); - } else if (table->groupcheck == CUDD_GROUP_CHECK7) { - result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, - DD_NORMAL_SIFT); - } else { - (void) fprintf(table->err, - "Unknown group ckecking method\n"); - result = 0; - } + } while (result != 0); + break; + case CUDD_REORDER_SYMM_SIFT: + result = cuddSymmSifting(table,lower,upper); + break; + case CUDD_REORDER_SYMM_SIFT_CONV: + result = cuddSymmSiftingConv(table,lower,upper); + break; + case CUDD_REORDER_GROUP_SIFT: + if (table->groupcheck == CUDD_NO_CHECK) { + result = ddGroupSifting(table,lower,upper,ddNoCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK5) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK7) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else { + (void) fprintf(table->err, + "Unknown group ckecking method\n"); + result = 0; + } + break; + case CUDD_REORDER_GROUP_SIFT_CONV: + do { + initialSize = table->keys - table->isolated; + if (table->groupcheck == CUDD_NO_CHECK) { + result = ddGroupSifting(table,lower,upper,ddNoCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK5) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else if (table->groupcheck == CUDD_GROUP_CHECK7) { + result = ddGroupSifting(table,lower,upper,ddExtSymmCheck, + DD_NORMAL_SIFT); + } else { + (void) fprintf(table->err, + "Unknown group ckecking method\n"); + result = 0; + } #ifdef DD_STATS - (void) fprintf(table->out,"\n"); + (void) fprintf(table->out,"\n"); #endif - result = cuddWindowReorder(table,lower,upper, - CUDD_REORDER_WINDOW4); - if (initialSize <= table->keys - table->isolated) - break; + result = cuddWindowReorder(table,lower,upper, + CUDD_REORDER_WINDOW4); + if (initialSize <= table->keys - table->isolated) + break; #ifdef DD_STATS - else - (void) fprintf(table->out,"\n"); + else + (void) fprintf(table->out,"\n"); #endif - } while (result != 0); - break; - case CUDD_REORDER_WINDOW2: - case CUDD_REORDER_WINDOW3: - case CUDD_REORDER_WINDOW4: - case CUDD_REORDER_WINDOW2_CONV: - case CUDD_REORDER_WINDOW3_CONV: - case CUDD_REORDER_WINDOW4_CONV: - result = cuddWindowReorder(table,lower,upper,method); - break; - case CUDD_REORDER_ANNEALING: - result = cuddAnnealing(table,lower,upper); - break; - case CUDD_REORDER_GENETIC: - result = cuddGa(table,lower,upper); - break; - case CUDD_REORDER_LINEAR: - result = cuddLinearAndSifting(table,lower,upper); - break; - case CUDD_REORDER_LINEAR_CONVERGE: - do { - initialSize = table->keys - table->isolated; - result = cuddLinearAndSifting(table,lower,upper); - if (initialSize <= table->keys - table->isolated) + } while (result != 0); + break; + case CUDD_REORDER_WINDOW2: + case CUDD_REORDER_WINDOW3: + case CUDD_REORDER_WINDOW4: + case CUDD_REORDER_WINDOW2_CONV: + case CUDD_REORDER_WINDOW3_CONV: + case CUDD_REORDER_WINDOW4_CONV: + result = cuddWindowReorder(table,lower,upper,method); break; + case CUDD_REORDER_ANNEALING: + result = cuddAnnealing(table,lower,upper); + break; + case CUDD_REORDER_GENETIC: + result = cuddGa(table,lower,upper); + break; + case CUDD_REORDER_LINEAR: + result = cuddLinearAndSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR_CONVERGE: + do { + initialSize = table->keys - table->isolated; + result = cuddLinearAndSifting(table,lower,upper); + if (initialSize <= table->keys - table->isolated) + break; #ifdef DD_STATS - else - (void) fprintf(table->out,"\n"); + else + (void) fprintf(table->out,"\n"); #endif - } while (result != 0); - break; - case CUDD_REORDER_EXACT: - result = cuddExact(table,lower,upper); - break; - case CUDD_REORDER_LAZY_SIFT: - result = ddGroupSifting(table,lower,upper,ddVarGroupCheck, - DD_LAZY_SIFT); - break; - default: - return(0); - } + } while (result != 0); + break; + case CUDD_REORDER_EXACT: + result = cuddExact(table,lower,upper); + break; + case CUDD_REORDER_LAZY_SIFT: + result = ddGroupSifting(table,lower,upper,ddVarGroupCheck, + DD_LAZY_SIFT); + break; + default: + return(0); + } } /* Create a single group for all the variables that were sifted, @@ -589,42 +628,42 @@ ddFindNodeHiLo( ** the values of upper that no reordering is needed. */ if ((int) treenode->low >= table->size) { - *lower = table->size; - *upper = -1; - return; + *lower = table->size; + *upper = -1; + return; } *lower = low = (unsigned int) table->perm[treenode->index]; high = (int) (low + treenode->size - 1); if (high >= table->size) { - /* This is the case of a partially existing group. The aim is to - ** reorder as many variables as safely possible. If the tree - ** node is terminal, we just reorder the subset of the group - ** that is currently in existence. If the group has - ** subgroups, then we only reorder those subgroups that are - ** fully instantiated. This way we avoid breaking up a group. - */ - MtrNode *auxnode = treenode->child; - if (auxnode == NULL) { - *upper = (unsigned int) table->size - 1; - } else { - /* Search the subgroup that strands the table->size line. - ** If the first group starts at 0 and goes past table->size - ** upper will get -1, thus correctly signaling that no reordering - ** should take place. + /* This is the case of a partially existing group. The aim is to + ** reorder as many variables as safely possible. If the tree + ** node is terminal, we just reorder the subset of the group + ** that is currently in existence. If the group has + ** subgroups, then we only reorder those subgroups that are + ** fully instantiated. This way we avoid breaking up a group. */ - while (auxnode != NULL) { - int thisLower = table->perm[auxnode->low]; - int thisUpper = thisLower + auxnode->size - 1; - if (thisUpper >= table->size && thisLower < table->size) - *upper = (unsigned int) thisLower - 1; - auxnode = auxnode->younger; + MtrNode *auxnode = treenode->child; + if (auxnode == NULL) { + *upper = (unsigned int) table->size - 1; + } else { + /* Search the subgroup that strands the table->size line. + ** If the first group starts at 0 and goes past table->size + ** upper will get -1, thus correctly signaling that no reordering + ** should take place. + */ + while (auxnode != NULL) { + int thisLower = table->perm[auxnode->low]; + int thisUpper = thisLower + auxnode->size - 1; + if (thisUpper >= table->size && thisLower < table->size) + *upper = (unsigned int) thisLower - 1; + auxnode = auxnode->younger; + } } - } } else { - /* Normal case: All the variables of the group exist. */ - *upper = (unsigned int) high; + /* Normal case: All the variables of the group exist. */ + *upper = (unsigned int) high; } #ifdef DD_DEBUG @@ -656,7 +695,7 @@ ddUniqueCompareGroup( { #if 0 if (entry[*ptrY] == entry[*ptrX]) { - return((*ptrX) - (*ptrY)); + return((*ptrX) - (*ptrY)); } #endif return(entry[*ptrY] - entry[*ptrX]); @@ -682,21 +721,21 @@ ddGroupSifting( DdManager * table, int lower, int upper, - int (*checkFunction)(DdManager *, int, int), + DD_CHKFP checkFunction, int lazyFlag) { - int *var; - int i,j,x,xInit; - int nvars; - int classes; - int result; - int *sifted; - int merged; - int dissolve; + int *var; + int i,j,x,xInit; + int nvars; + int classes; + int result; + int *sifted; + int merged; + int dissolve; #ifdef DD_STATS unsigned previousSize; #endif - int xindex; + int xindex; nvars = table->size; @@ -705,140 +744,140 @@ ddGroupSifting( sifted = NULL; var = ABC_ALLOC(int,nvars); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddGroupSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; } entry = ABC_ALLOC(int,nvars); if (entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddGroupSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; } sifted = ABC_ALLOC(int,nvars); if (sifted == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddGroupSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddGroupSiftingOutOfMem; } /* Here we consider only one representative for each group. */ for (i = 0, classes = 0; i < nvars; i++) { - sifted[i] = 0; - x = table->perm[i]; - if ((unsigned) x >= table->subtables[x].next) { - entry[i] = table->subtables[x].keys; - var[classes] = i; - classes++; - } + sifted[i] = 0; + x = table->perm[i]; + if ((unsigned) x >= table->subtables[x].next) { + entry[i] = table->subtables[x].keys; + var[classes] = i; + classes++; + } } qsort((void *)var,classes,sizeof(int), - (int (*)(const void *, const void *)) ddUniqueCompareGroup); + (DD_QSFP) ddUniqueCompareGroup); if (lazyFlag) { - for (i = 0; i < nvars; i ++) { - ddResetVarHandled(table, i); - } + for (i = 0; i < nvars; i ++) { + ddResetVarHandled(table, i); + } } /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { - if (ddTotalNumberSwapping >= table->siftMaxSwap) - break; - xindex = var[i]; - if (sifted[xindex] == 1) /* variable already sifted as part of group */ - continue; + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + xindex = var[i]; + if (sifted[xindex] == 1) /* variable already sifted as part of group */ + continue; x = table->perm[xindex]; /* find current level of this variable */ - if (x < lower || x > upper || table->subtables[x].bindVar == 1) - continue; + if (x < lower || x > upper || table->subtables[x].bindVar == 1) + continue; #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif #ifdef DD_DEBUG - /* x is bottom of group */ + /* x is bottom of group */ assert((unsigned) x >= table->subtables[x].next); #endif - if ((unsigned) x == table->subtables[x].next) { - dissolve = 1; - result = ddGroupSiftingAux(table,x,lower,upper,checkFunction, - lazyFlag); - } else { - dissolve = 0; - result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); - } - if (!result) goto ddGroupSiftingOutOfMem; - - /* check for aggregation */ - merged = 0; - if (lazyFlag == 0 && table->groupcheck == CUDD_GROUP_CHECK7) { - x = table->perm[xindex]; /* find current level */ - if ((unsigned) x == table->subtables[x].next) { /* not part of a group */ - if (x != upper && sifted[table->invperm[x+1]] == 0 && - (unsigned) x+1 == table->subtables[x+1].next) { - if (ddSecDiffCheck(table,x,x+1)) { - merged =1; - ddCreateGroup(table,x,x+1); - } + if ((unsigned) x == table->subtables[x].next) { + dissolve = 1; + result = ddGroupSiftingAux(table,x,lower,upper,checkFunction, + lazyFlag); + } else { + dissolve = 0; + result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); } - if (x != lower && sifted[table->invperm[x-1]] == 0 && - (unsigned) x-1 == table->subtables[x-1].next) { - if (ddSecDiffCheck(table,x-1,x)) { - merged =1; - ddCreateGroup(table,x-1,x); + if (!result) goto ddGroupSiftingOutOfMem; + + /* check for aggregation */ + merged = 0; + if (lazyFlag == 0 && table->groupcheck == CUDD_GROUP_CHECK7) { + x = table->perm[xindex]; /* find current level */ + if ((unsigned) x == table->subtables[x].next) { /* not part of a group */ + if (x != upper && sifted[table->invperm[x+1]] == 0 && + (unsigned) x+1 == table->subtables[x+1].next) { + if (ddSecDiffCheck(table,x,x+1)) { + merged =1; + ddCreateGroup(table,x,x+1); + } + } + if (x != lower && sifted[table->invperm[x-1]] == 0 && + (unsigned) x-1 == table->subtables[x-1].next) { + if (ddSecDiffCheck(table,x-1,x)) { + merged =1; + ddCreateGroup(table,x-1,x); + } + } } } - } - } - if (merged) { /* a group was created */ - /* move x to bottom of group */ - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - /* sift */ - result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); - if (!result) goto ddGroupSiftingOutOfMem; + if (merged) { /* a group was created */ + /* move x to bottom of group */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + /* sift */ + result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag); + if (!result) goto ddGroupSiftingOutOfMem; #ifdef DD_STATS - if (table->keys < previousSize + table->isolated) { - (void) fprintf(table->out,"_"); - } else if (table->keys > previousSize + table->isolated) { - (void) fprintf(table->out,"^"); - } else { - (void) fprintf(table->out,"*"); - } - fflush(table->out); - } else { - if (table->keys < previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > previousSize + table->isolated) { - (void) fprintf(table->out,"+"); + if (table->keys < previousSize + table->isolated) { + (void) fprintf(table->out,"_"); + } else if (table->keys > previousSize + table->isolated) { + (void) fprintf(table->out,"^"); + } else { + (void) fprintf(table->out,"*"); + } + fflush(table->out); } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > previousSize + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } + } - /* Mark variables in the group just sifted. */ - x = table->perm[xindex]; - if ((unsigned) x != table->subtables[x].next) { - xInit = x; - do { - j = table->invperm[x]; - sifted[j] = 1; - x = table->subtables[x].next; - } while (x != xInit); - - /* Dissolve the group if it was created. */ - if (lazyFlag == 0 && dissolve) { - do { - j = table->subtables[x].next; - table->subtables[x].next = x; - x = j; - } while (x != xInit); + /* Mark variables in the group just sifted. */ + x = table->perm[xindex]; + if ((unsigned) x != table->subtables[x].next) { + xInit = x; + do { + j = table->invperm[x]; + sifted[j] = 1; + x = table->subtables[x].next; + } while (x != xInit); + + /* Dissolve the group if it was created. */ + if (lazyFlag == 0 && dissolve) { + do { + j = table->subtables[x].next; + table->subtables[x].next = x; + x = j; + } while (x != xInit); + } } - } #ifdef DD_DEBUG - if (pr > 0) (void) fprintf(table->out,"ddGroupSifting:"); + if (pr > 0) (void) fprintf(table->out,"ddGroupSifting:"); #endif if (lazyFlag) ddSetVarHandled(table, xindex); @@ -851,9 +890,9 @@ ddGroupSifting( return(1); ddGroupSiftingOutOfMem: - if (entry != NULL) ABC_FREE(entry); + if (entry != NULL) ABC_FREE(entry); if (var != NULL) ABC_FREE(var); - if (sifted != NULL) ABC_FREE(sifted); + if (sifted != NULL) ABC_FREE(sifted); return(0); @@ -887,7 +926,7 @@ ddCreateGroup( /* Find bottom of second group. */ gybot = y; while ((unsigned) gybot < table->subtables[gybot].next) - gybot = table->subtables[gybot].next; + gybot = table->subtables[gybot].next; /* Link groups. */ table->subtables[x].next = y; @@ -919,11 +958,11 @@ ddGroupSiftingAux( int x, int xLow, int xHigh, - int (*checkFunction)(DdManager *, int, int), + DD_CHKFP checkFunction, int lazyFlag) { Move *move; - Move *moves; /* list of moves */ + Move *moves; /* list of moves */ int initialSize; int result; int y; @@ -931,78 +970,76 @@ ddGroupSiftingAux( #ifdef DD_DEBUG if (pr > 0) (void) fprintf(table->out, - "ddGroupSiftingAux from %d to %d\n",xLow,xHigh); + "ddGroupSiftingAux from %d to %d\n",xLow,xHigh); assert((unsigned) x >= table->subtables[x].next); /* x is bottom of group */ #endif initialSize = table->keys - table->isolated; moves = NULL; - originalSize = initialSize; /* for lazy sifting */ + originalSize = initialSize; /* for lazy sifting */ /* If we have a singleton, we check for aggregation in both ** directions before we sift. */ if ((unsigned) x == table->subtables[x].next) { - /* Will go down first, unless x == xHigh: - ** Look for aggregation above x. - */ - for (y = x; y > xLow; y--) { - if (!checkFunction(table,y-1,y)) - break; - topbot = table->subtables[y-1].next; /* find top of y-1's group */ - table->subtables[y-1].next = y; - table->subtables[x].next = topbot; /* x is bottom of group so its */ - /* next is top of y-1's group */ - y = topbot + 1; /* add 1 for y--; new y is top of group */ - } - /* Will go up first unless x == xlow: - ** Look for aggregation below x. - */ - for (y = x; y < xHigh; y++) { - if (!checkFunction(table,y,y+1)) - break; - /* find bottom of y+1's group */ - topbot = y + 1; - while ((unsigned) topbot < table->subtables[topbot].next) { - topbot = table->subtables[topbot].next; + /* Will go down first, unless x == xHigh: + ** Look for aggregation above x. + */ + for (y = x; y > xLow; y--) { + if (!checkFunction(table,y-1,y)) + break; + topbot = table->subtables[y-1].next; /* find top of y-1's group */ + table->subtables[y-1].next = y; + table->subtables[x].next = topbot; /* x is bottom of group so its */ + /* next is top of y-1's group */ + y = topbot + 1; /* add 1 for y--; new y is top of group */ + } + /* Will go up first unless x == xlow: + ** Look for aggregation below x. + */ + for (y = x; y < xHigh; y++) { + if (!checkFunction(table,y,y+1)) + break; + /* find bottom of y+1's group */ + topbot = y + 1; + while ((unsigned) topbot < table->subtables[topbot].next) { + topbot = table->subtables[topbot].next; + } + table->subtables[topbot].next = table->subtables[y].next; + table->subtables[y].next = y + 1; + y = topbot - 1; /* subtract 1 for y++; new y is bottom of group */ } - table->subtables[topbot].next = table->subtables[y].next; - table->subtables[y].next = y + 1; - y = topbot - 1; /* subtract 1 for y++; new y is bottom of group */ - } } /* Now x may be in the middle of a group. ** Find bottom of x's group. */ while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - - originalLevel = x; /* for lazy sifting */ + x = table->subtables[x].next; if (x == xLow) { /* Sift down */ #ifdef DD_DEBUG - /* x must be a singleton */ - assert((unsigned) x == table->subtables[x].next); + /* x must be a singleton */ + assert((unsigned) x == table->subtables[x].next); #endif - if (x == xHigh) return(1); /* just one variable */ + if (x == xHigh) return(1); /* just one variable */ if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) goto ddGroupSiftingAuxOutOfMem; - /* at this point x == xHigh, unless early term */ + /* at this point x == xHigh, unless early term */ - /* move backward and stop at best position */ - result = ddGroupSiftingBackward(table,moves,initialSize, - DD_SIFT_DOWN,lazyFlag); + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_DOWN,lazyFlag); #ifdef DD_DEBUG - assert(table->keys - table->isolated <= (unsigned) initialSize); + assert(table->keys - table->isolated <= (unsigned) initialSize); #endif if (!result) goto ddGroupSiftingAuxOutOfMem; } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ #ifdef DD_DEBUG - /* x is bottom of group */ + /* x is bottom of group */ assert((unsigned) x >= table->subtables[x].next); #endif /* Find top of x's group */ @@ -1010,28 +1047,28 @@ ddGroupSiftingAux( if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) goto ddGroupSiftingAuxOutOfMem; - /* at this point x == xLow, unless early term */ + /* at this point x == xLow, unless early term */ - /* move backward and stop at best position */ - result = ddGroupSiftingBackward(table,moves,initialSize, - DD_SIFT_UP,lazyFlag); + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_UP,lazyFlag); #ifdef DD_DEBUG - assert(table->keys - table->isolated <= (unsigned) initialSize); + assert(table->keys - table->isolated <= (unsigned) initialSize); #endif if (!result) goto ddGroupSiftingAuxOutOfMem; } else if (x - xLow > xHigh - x) { /* must go down first: shorter */ if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) goto ddGroupSiftingAuxOutOfMem; - /* at this point x == xHigh, unless early term */ + /* at this point x == xHigh, unless early term */ /* Find top of group */ - if (moves) { - x = moves->y; - } - while ((unsigned) x < table->subtables[x].next) + if (moves) { + x = moves->y; + } + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; x = table->subtables[x].next; - x = table->subtables[x].next; #ifdef DD_DEBUG /* x should be the top of a group */ assert((unsigned) x <= table->subtables[x].next); @@ -1040,11 +1077,11 @@ ddGroupSiftingAux( if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) goto ddGroupSiftingAuxOutOfMem; - /* move backward and stop at best position */ - result = ddGroupSiftingBackward(table,moves,initialSize, - DD_SIFT_UP,lazyFlag); + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_UP,lazyFlag); #ifdef DD_DEBUG - assert(table->keys - table->isolated <= (unsigned) initialSize); + assert(table->keys - table->isolated <= (unsigned) initialSize); #endif if (!result) goto ddGroupSiftingAuxOutOfMem; @@ -1054,13 +1091,13 @@ ddGroupSiftingAux( if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves)) goto ddGroupSiftingAuxOutOfMem; - /* at this point x == xHigh, unless early term */ + /* at this point x == xHigh, unless early term */ if (moves) { - x = moves->x; - } - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; + x = moves->x; + } + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; #ifdef DD_DEBUG /* x is bottom of a group */ assert((unsigned) x >= table->subtables[x].next); @@ -1069,18 +1106,18 @@ ddGroupSiftingAux( if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves)) goto ddGroupSiftingAuxOutOfMem; - /* move backward and stop at best position */ - result = ddGroupSiftingBackward(table,moves,initialSize, - DD_SIFT_DOWN,lazyFlag); + /* move backward and stop at best position */ + result = ddGroupSiftingBackward(table,moves,initialSize, + DD_SIFT_DOWN,lazyFlag); #ifdef DD_DEBUG - assert(table->keys - table->isolated <= (unsigned) initialSize); + assert(table->keys - table->isolated <= (unsigned) initialSize); #endif if (!result) goto ddGroupSiftingAuxOutOfMem; } while (moves != NULL) { move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); + cuddDeallocMove(table, moves); moves = move; } @@ -1089,7 +1126,7 @@ ddGroupSiftingAux( ddGroupSiftingAuxOutOfMem: while (moves != NULL) { move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); + cuddDeallocMove(table, moves); moves = move; } @@ -1118,7 +1155,7 @@ ddGroupSiftingUp( DdManager * table, int y, int xLow, - int (*checkFunction)(DdManager *, int, int), + DD_CHKFP checkFunction, Move ** moves) { Move *move; @@ -1131,7 +1168,7 @@ ddGroupSiftingUp( int zindex; int z; int isolated; - int L; /* lower bound on DD size */ + int L; /* lower bound on DD size */ #ifdef DD_DEBUG int checkL; #endif @@ -1150,99 +1187,97 @@ ddGroupSiftingUp( limitSize = L = table->keys - table->isolated; gybot = y; while ((unsigned) gybot < table->subtables[gybot].next) - gybot = table->subtables[gybot].next; + gybot = table->subtables[gybot].next; for (z = xLow + 1; z <= gybot; z++) { - zindex = table->invperm[z]; - if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - L -= table->subtables[z].keys - isolated; - } + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L -= table->subtables[z].keys - isolated; + } } - originalLevel = y; /* for lazy sifting */ - x = cuddNextLow(table,y); while (x >= xLow && L <= limitSize) { #ifdef DD_DEBUG - gybot = y; - while ((unsigned) gybot < table->subtables[gybot].next) - gybot = table->subtables[gybot].next; - checkL = table->keys - table->isolated; - for (z = xLow + 1; z <= gybot; z++) { - zindex = table->invperm[z]; - if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - checkL -= table->subtables[z].keys - isolated; + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + if (pr > 0 && L != checkL) { + (void) fprintf(table->out, + "Inaccurate lower bound: L = %d checkL = %d\n", + L, checkL); } - } - if (pr > 0 && L != checkL) { - (void) fprintf(table->out, - "Inaccurate lower bound: L = %d checkL = %d\n", - L, checkL); - } #endif gxtop = table->subtables[x].next; if (checkFunction(table,x,y)) { - /* Group found, attach groups */ - table->subtables[x].next = y; - i = table->subtables[y].next; - while (table->subtables[i].next != (unsigned) y) - i = table->subtables[i].next; - table->subtables[i].next = gxtop; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddGroupSiftingUpOutOfMem; - move->x = x; - move->y = y; - move->flags = MTR_NEWNODE; - move->size = table->keys - table->isolated; - move->next = *moves; - *moves = move; + /* Group found, attach groups */ + table->subtables[x].next = y; + i = table->subtables[y].next; + while (table->subtables[i].next != (unsigned) y) + i = table->subtables[i].next; + table->subtables[i].next = gxtop; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_NEWNODE; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; } else if (table->subtables[x].next == (unsigned) x && - table->subtables[y].next == (unsigned) y) { + table->subtables[y].next == (unsigned) y) { /* x and y are self groups */ - xindex = table->invperm[x]; + xindex = table->invperm[x]; size = cuddSwapInPlace(table,x,y); #ifdef DD_DEBUG assert(table->subtables[x].next == (unsigned) x); assert(table->subtables[y].next == (unsigned) y); #endif if (size == 0) goto ddGroupSiftingUpOutOfMem; - /* Update the lower bound. */ - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[xindex]->ref == 1; - L += table->subtables[y].keys - isolated; - } + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } move = (Move *)cuddDynamicAllocNode(table); if (move == NULL) goto ddGroupSiftingUpOutOfMem; move->x = x; move->y = y; - move->flags = MTR_DEFAULT; + move->flags = MTR_DEFAULT; move->size = size; move->next = *moves; *moves = move; #ifdef DD_DEBUG - if (pr > 0) (void) fprintf(table->out, - "ddGroupSiftingUp (2 single groups):\n"); + if (pr > 0) (void) fprintf(table->out, + "ddGroupSiftingUp (2 single groups):\n"); #endif if ((double) size > (double) limitSize * table->maxGrowth) - return(1); + return(1); if (size < limitSize) limitSize = size; } else { /* Group move */ size = ddGroupMove(table,x,y,moves); - if (size == 0) goto ddGroupSiftingUpOutOfMem; - /* Update the lower bound. */ - z = (*moves)->y; - do { - zindex = table->invperm[z]; - if (cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - L += table->subtables[z].keys - isolated; - } - z = table->subtables[z].next; - } while (z != (int) (*moves)->y); + if (size == 0) goto ddGroupSiftingUpOutOfMem; + /* Update the lower bound. */ + z = (*moves)->y; + do { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L += table->subtables[z].keys - isolated; + } + z = table->subtables[z].next; + } while (z != (int) (*moves)->y); if ((double) size > (double) limitSize * table->maxGrowth) - return(1); + return(1); if (size < limitSize) limitSize = size; } y = gxtop; @@ -1254,7 +1289,7 @@ ddGroupSiftingUp( ddGroupSiftingUpOutOfMem: while (*moves != NULL) { move = (*moves)->next; - cuddDeallocNode(table, (DdNode *) *moves); + cuddDeallocMove(table, *moves); *moves = move; } return(0); @@ -1278,7 +1313,7 @@ ddGroupSiftingDown( DdManager * table, int x, int xHigh, - int (*checkFunction)(DdManager *, int, int), + DD_CHKFP checkFunction, Move ** moves) { Move *move; @@ -1286,7 +1321,7 @@ ddGroupSiftingDown( int size; int limitSize; int gxtop,gybot; - int R; /* upper bound on node decrease */ + int R; /* upper bound on node decrease */ int xindex, yindex; int isolated, allVars; int z; @@ -1303,71 +1338,69 @@ ddGroupSiftingDown( y = x; allVars = 1; do { - if (table->subtables[y].keys != 1) { - allVars = 0; - break; - } - y = table->subtables[y].next; + if (table->subtables[y].keys != 1) { + allVars = 0; + break; + } + y = table->subtables[y].next; } while (table->subtables[y].next != (unsigned) x); if (allVars) - return(1); - + return(1); + /* Initialize R. */ xindex = table->invperm[x]; gxtop = table->subtables[x].next; limitSize = size = table->keys - table->isolated; R = 0; for (z = xHigh; z > gxtop; z--) { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - R += table->subtables[z].keys - isolated; - } + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } } - originalLevel = x; /* for lazy sifting */ - y = cuddNextHigh(table,x); while (y <= xHigh && size - R < limitSize) { #ifdef DD_DEBUG - gxtop = table->subtables[x].next; - checkR = 0; - for (z = xHigh; z > gxtop; z--) { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - checkR += table->subtables[z].keys - isolated; + gxtop = table->subtables[x].next; + checkR = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } } - } - assert(R >= checkR); + assert(R >= checkR); #endif - /* Find bottom of y group. */ + /* Find bottom of y group. */ gybot = table->subtables[y].next; while (table->subtables[gybot].next != (unsigned) y) gybot = table->subtables[gybot].next; if (checkFunction(table,x,y)) { - /* Group found: attach groups and record move. */ - gxtop = table->subtables[x].next; - table->subtables[x].next = y; - table->subtables[gybot].next = gxtop; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) goto ddGroupSiftingDownOutOfMem; - move->x = x; - move->y = y; - move->flags = MTR_NEWNODE; - move->size = table->keys - table->isolated; - move->next = *moves; - *moves = move; + /* Group found: attach groups and record move. */ + gxtop = table->subtables[x].next; + table->subtables[x].next = y; + table->subtables[gybot].next = gxtop; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) goto ddGroupSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->flags = MTR_NEWNODE; + move->size = table->keys - table->isolated; + move->next = *moves; + *moves = move; } else if (table->subtables[x].next == (unsigned) x && - table->subtables[y].next == (unsigned) y) { + table->subtables[y].next == (unsigned) y) { /* x and y are self groups */ - /* Update upper bound on node decrease. */ - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[yindex]->ref == 1; - R -= table->subtables[y].keys - isolated; - } + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } size = cuddSwapInPlace(table,x,y); #ifdef DD_DEBUG assert(table->subtables[x].next == (unsigned) x); @@ -1375,19 +1408,19 @@ ddGroupSiftingDown( #endif if (size == 0) goto ddGroupSiftingDownOutOfMem; - /* Record move. */ + /* Record move. */ move = (Move *) cuddDynamicAllocNode(table); if (move == NULL) goto ddGroupSiftingDownOutOfMem; move->x = x; move->y = y; - move->flags = MTR_DEFAULT; + move->flags = MTR_DEFAULT; move->size = size; move->next = *moves; *moves = move; #ifdef DD_DEBUG if (pr > 0) (void) fprintf(table->out, - "ddGroupSiftingDown (2 single groups):\n"); + "ddGroupSiftingDown (2 single groups):\n"); #endif if ((double) size > (double) limitSize * table->maxGrowth) return(1); @@ -1396,32 +1429,32 @@ ddGroupSiftingDown( x = y; y = cuddNextHigh(table,x); } else { /* Group move */ - /* Update upper bound on node decrease: first phase. */ - gxtop = table->subtables[x].next; - z = gxtop + 1; - do { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - R -= table->subtables[z].keys - isolated; - } - z++; - } while (z <= gybot); + /* Update upper bound on node decrease: first phase. */ + gxtop = table->subtables[x].next; + z = gxtop + 1; + do { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R -= table->subtables[z].keys - isolated; + } + z++; + } while (z <= gybot); size = ddGroupMove(table,x,y,moves); if (size == 0) goto ddGroupSiftingDownOutOfMem; if ((double) size > (double) limitSize * table->maxGrowth) - return(1); + return(1); if (size < limitSize) limitSize = size; - /* Update upper bound on node decrease: second phase. */ - gxtop = table->subtables[gybot].next; - for (z = gxtop + 1; z <= gybot; z++) { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - R += table->subtables[z].keys - isolated; - } - } + /* Update upper bound on node decrease: second phase. */ + gxtop = table->subtables[gybot].next; + for (z = gxtop + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } } x = gybot; y = cuddNextHigh(table,x); @@ -1432,7 +1465,7 @@ ddGroupSiftingDown( ddGroupSiftingDownOutOfMem: while (*moves != NULL) { move = (*moves)->next; - cuddDeallocNode(table, (DdNode *) *moves); + cuddDeallocMove(table, *moves); *moves = move; } @@ -1461,12 +1494,12 @@ ddGroupMove( Move *move; int size; int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; - int swapx=-1,swapy=-1; // Suppress "might be used uninitialized" + int swapx,swapy; #if defined(DD_DEBUG) && defined(DD_VERBOSE) int initialSize,bestSize; #endif -#if DD_DEBUG +#ifdef DD_DEBUG /* We assume that x < y */ assert(x < y); #endif @@ -1489,8 +1522,8 @@ ddGroupMove( size = cuddSwapInPlace(table,x,y); if (size == 0) goto ddGroupMoveOutOfMem; #if defined(DD_DEBUG) && defined(DD_VERBOSE) - if (size < bestSize) - bestSize = size; + if (size < bestSize) + bestSize = size; #endif swapx = x; swapy = y; y = x; @@ -1501,7 +1534,7 @@ ddGroupMove( } #if defined(DD_DEBUG) && defined(DD_VERBOSE) if ((bestSize < initialSize) && (bestSize < size)) - (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); + (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); #endif /* fix groups */ @@ -1539,7 +1572,7 @@ ddGroupMove( ddGroupMoveOutOfMem: while (*moves != NULL) { move = (*moves)->next; - cuddDeallocNode(table, (DdNode *) *moves); + cuddDeallocMove(table, *moves); *moves = move; } return(0); @@ -1567,7 +1600,7 @@ ddGroupMoveBackward( int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; -#if DD_DEBUG +#ifdef DD_DEBUG /* We assume that x < y */ assert(x < y); #endif @@ -1636,73 +1669,75 @@ ddGroupSiftingBackward( DdManager * table, Move * moves, int size, - int upFlag, + int upFlag, int lazyFlag) { Move *move; int res; - Move *end_move = NULL; + Move *end_move; int diff, tmp_diff; - int index, pairlev; + int index; + unsigned int pairlev; if (lazyFlag) { - end_move = NULL; + end_move = NULL; - /* Find the minimum size, and the earliest position at which it + /* Find the minimum size, and the earliest position at which it ** was achieved. */ - for (move = moves; move != NULL; move = move->next) { - if (move->size < size) { - size = move->size; - end_move = move; - } else if (move->size == size) { - if (end_move == NULL) end_move = move; - } - } - - /* Find among the moves that give minimum size the one that - ** minimizes the distance from the corresponding variable. */ - if (moves != NULL) { - diff = Cudd_ReadSize(table) + 1; - index = (upFlag == 1) ? - table->invperm[moves->x] : table->invperm[moves->y]; - pairlev = table->perm[Cudd_bddReadPairIndex(table, index)]; - for (move = moves; move != NULL; move = move->next) { - if (move->size == size) { - if (upFlag == 1) { - tmp_diff = (move->x > pairlev) ? - move->x - pairlev : pairlev - move->x; - } else { - tmp_diff = (move->y > pairlev) ? - move->y - pairlev : pairlev - move->y; + if (move->size < size) { + size = move->size; + end_move = move; + } else if (move->size == size) { + if (end_move == NULL) end_move = move; } - if (tmp_diff < diff) { - diff = tmp_diff; - end_move = move; - } } + + /* Find among the moves that give minimum size the one that + ** minimizes the distance from the corresponding variable. */ + if (moves != NULL) { + diff = Cudd_ReadSize(table) + 1; + index = (upFlag == 1) ? + table->invperm[moves->x] : table->invperm[moves->y]; + pairlev = + (unsigned) table->perm[Cudd_bddReadPairIndex(table, index)]; + + for (move = moves; move != NULL; move = move->next) { + if (move->size == size) { + if (upFlag == 1) { + tmp_diff = (move->x > pairlev) ? + move->x - pairlev : pairlev - move->x; + } else { + tmp_diff = (move->y > pairlev) ? + move->y - pairlev : pairlev - move->y; + } + if (tmp_diff < diff) { + diff = tmp_diff; + end_move = move; + } + } + } } - } } else { - /* Find the minimum size. */ - for (move = moves; move != NULL; move = move->next) { - if (move->size < size) { - size = move->size; - } - } + /* Find the minimum size. */ + for (move = moves; move != NULL; move = move->next) { + if (move->size < size) { + size = move->size; + } + } } /* In case of lazy sifting, end_move identifies the position at ** which we want to stop. Otherwise, we stop as soon as we meet ** the minimum size. */ for (move = moves; move != NULL; move = move->next) { - if (lazyFlag) { - if (move == end_move) return(1); - } else { - if (move->size == size) return(1); - } + if (lazyFlag) { + if (move == end_move) return(1); + } else { + if (move->size == size) return(1); + } if ((table->subtables[move->x].next == move->x) && - (table->subtables[move->y].next == move->y)) { + (table->subtables[move->y].next == move->y)) { res = cuddSwapInPlace(table,(int)move->x,(int)move->y); if (!res) return(0); #ifdef DD_DEBUG @@ -1711,12 +1746,12 @@ ddGroupSiftingBackward( assert(table->subtables[move->y].next == move->y); #endif } else { /* Group move necessary */ - if (move->flags == MTR_NEWNODE) { - ddDissolveGroup(table,(int)move->x,(int)move->y); - } else { - res = ddGroupMoveBackward(table,(int)move->x,(int)move->y); - if (!res) return(0); - } + if (move->flags == MTR_NEWNODE) { + ddDissolveGroup(table,(int)move->x,(int)move->y); + } else { + res = ddGroupMoveBackward(table,(int)move->x,(int)move->y); + if (!res) return(0); + } } } @@ -1752,9 +1787,9 @@ ddMergeGroups( ** this is the topmost group. In such a case we do not merge lest ** we lose the symmetry information. */ if (treenode != table->tree) { - for (i = low; i < high; i++) - table->subtables[i].next = i+1; - table->subtables[high].next = low; + for (i = low; i < high; i++) + table->subtables[i].next = i+1; + table->subtables[high].next = low; } /* Adjust the index fields of the tree nodes. If a node is the @@ -1763,11 +1798,11 @@ ddMergeGroups( newindex = table->invperm[low]; auxnode = treenode; do { - auxnode->index = newindex; - if (auxnode->parent == NULL || - (int) auxnode->parent->index != saveindex) - break; - auxnode = auxnode->parent; + auxnode->index = newindex; + if (auxnode->parent == NULL || + (int) auxnode->parent->index != saveindex) + break; + auxnode = auxnode->parent; } while (1); return; @@ -1796,8 +1831,8 @@ ddDissolveGroup( /* find top and bottom of the two groups */ boty = y; while ((unsigned) boty < table->subtables[boty].next) - boty = table->subtables[boty].next; - + boty = table->subtables[boty].next; + topx = table->subtables[boty].next; table->subtables[boty].next = y; @@ -1864,24 +1899,24 @@ ddSecDiffCheck( threshold = table->recomb / 100.0; if (Sx < threshold) { - xindex = table->invperm[x]; - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { + xindex = table->invperm[x]; + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { #if defined(DD_DEBUG) && defined(DD_VERBOSE) - (void) fprintf(table->out, - "Second difference for %d = %g Pos(%d)\n", - table->invperm[x],Sx,x); + (void) fprintf(table->out, + "Second difference for %d = %g Pos(%d)\n", + table->invperm[x],Sx,x); #endif #ifdef DD_STATS - secdiff++; + secdiff++; #endif - return(1); - } else { + return(1); + } else { #ifdef DD_STATS - secdiffmisfire++; + secdiffmisfire++; #endif - return(0); - } + return(0); + } } return(0); @@ -1907,14 +1942,14 @@ ddExtSymmCheck( { DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10; DdNode *one; - int comple; /* f0 is complemented */ - int notproj; /* f is not a projection function */ - int arccount; /* number of arcs from layer x to layer y */ - int TotalRefCount; /* total reference count of layer y minus 1 */ - int counter; /* number of nodes of layer x that are allowed */ - /* to violate extended symmetry conditions */ - int arccounter; /* number of arcs into layer y that are allowed */ - /* to come from layers other than x */ + unsigned comple; /* f0 is complemented */ + int notproj; /* f is not a projection function */ + int arccount; /* number of arcs from layer x to layer y */ + int TotalRefCount; /* total reference count of layer y minus 1 */ + int counter; /* number of nodes of layer x that are allowed */ + /* to violate extended symmetry conditions */ + int arccounter; /* number of arcs into layer y that are allowed */ + /* to come from layers other than x */ int i; int xindex; int yindex; @@ -1928,7 +1963,7 @@ ddExtSymmCheck( /* If the two variables do not interact, we do not want to merge them. */ if (!cuddTestInteract(table,xindex,yindex)) - return(0); + return(0); #ifdef DD_DEBUG /* Checks that x and y do not contain just the projection functions. @@ -1937,10 +1972,10 @@ ddExtSymmCheck( ** any other variable. */ if (table->subtables[x].keys == 1) { - assert(table->vars[xindex]->ref != 1); + assert(table->vars[xindex]->ref != 1); } if (table->subtables[y].keys == 1) { - assert(table->vars[yindex]->ref != 1); + assert(table->vars[yindex]->ref != 1); } #endif @@ -1950,89 +1985,89 @@ ddExtSymmCheck( arccount = 0; counter = (int) (table->subtables[x].keys * - (table->symmviolation/100.0) + 0.5); + (table->symmviolation/100.0) + 0.5); one = DD_ONE(table); slots = table->subtables[x].slots; list = table->subtables[x].nodelist; for (i = 0; i < slots; i++) { - f = list[i]; - while (f != sentinel) { - /* Find f1, f0, f11, f10, f01, f00. */ - f1 = cuddT(f); - f0 = Cudd_Regular(cuddE(f)); - comple = Cudd_IsComplement(cuddE(f)); - notproj = f1 != one || f0 != one || f->ref != (DdHalfWord) 1; - if (f1->index == yindex) { - arccount++; - f11 = cuddT(f1); f10 = cuddE(f1); - } else { - if ((int) f0->index != yindex) { - /* If f is an isolated projection function it is - ** allowed to bypass layer y. + f = list[i]; + while (f != sentinel) { + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + f0 = Cudd_Regular(cuddE(f)); + comple = Cudd_IsComplement(cuddE(f)); + notproj = f1 != one || f0 != one || f->ref != (DdHalfWord) 1; + if (f1->index == (unsigned) yindex) { + arccount++; + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + if ((int) f0->index != yindex) { + /* If f is an isolated projection function it is + ** allowed to bypass layer y. + */ + if (notproj) { + if (counter == 0) + return(0); + counter--; /* f bypasses layer y */ + } + } + f11 = f10 = f1; + } + if ((int) f0->index == yindex) { + arccount++; + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + + /* Unless we are looking at a projection function + ** without external references except the one from the + ** table, we insist that f01 == f10 or f11 == f00 */ if (notproj) { - if (counter == 0) - return(0); - counter--; /* f bypasses layer y */ + if (f01 != f10 && f11 != f00) { + if (counter == 0) + return(0); + counter--; + } } - } - f11 = f10 = f1; - } - if ((int) f0->index == yindex) { - arccount++; - f01 = cuddT(f0); f00 = cuddE(f0); - } else { - f01 = f00 = f0; - } - if (comple) { - f01 = Cudd_Not(f01); - f00 = Cudd_Not(f00); - } - - /* Unless we are looking at a projection function - ** without external references except the one from the - ** table, we insist that f01 == f10 or f11 == f00 - */ - if (notproj) { - if (f01 != f10 && f11 != f00) { - if (counter == 0) - return(0); - counter--; - } - } - f = f->next; - } /* while */ + f = f->next; + } /* while */ } /* for */ /* Calculate the total reference counts of y */ - TotalRefCount = -1; /* -1 for projection function */ + TotalRefCount = -1; /* -1 for projection function */ slots = table->subtables[y].slots; list = table->subtables[y].nodelist; for (i = 0; i < slots; i++) { - f = list[i]; - while (f != sentinel) { - TotalRefCount += f->ref; - f = f->next; - } + f = list[i]; + while (f != sentinel) { + TotalRefCount += f->ref; + f = f->next; + } } arccounter = (int) (table->subtables[y].keys * - (table->arcviolation/100.0) + 0.5); + (table->arcviolation/100.0) + 0.5); res = arccount >= TotalRefCount - arccounter; #if defined(DD_DEBUG) && defined(DD_VERBOSE) if (res) { - (void) fprintf(table->out, - "Found extended symmetry! x = %d\ty = %d\tPos(%d,%d)\n", - xindex,yindex,x,y); + (void) fprintf(table->out, + "Found extended symmetry! x = %d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); } #endif #ifdef DD_STATS if (res) - extsymm++; + extsymm++; #endif return(res); @@ -2061,16 +2096,16 @@ ddVarGroupCheck( if (Cudd_bddIsVarToBeUngrouped(table, xindex)) return(0); if (Cudd_bddReadPairIndex(table, xindex) == yindex) { - if (ddIsVarHandled(table, xindex) || - ddIsVarHandled(table, yindex)) { - if (Cudd_bddIsVarToBeGrouped(table, xindex) || - Cudd_bddIsVarToBeGrouped(table, yindex) ) { - if (table->keys - table->isolated <= (unsigned)originalSize) { - return(1); - } + if (ddIsVarHandled(table, xindex) || + ddIsVarHandled(table, yindex)) { + if (Cudd_bddIsVarToBeGrouped(table, xindex) || + Cudd_bddIsVarToBeGrouped(table, yindex) ) { + if (table->keys - table->isolated <= originalSize) { + return(1); + } + } } } - } return(0); @@ -2146,5 +2181,7 @@ ddIsVarHandled( return dd->subtables[dd->perm[index]].varHandled; } /* end of ddIsVarHandled */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddHarwell.c b/src/bdd/cudd/cuddHarwell.c index af552148..75e328ea 100644 --- a/src/bdd/cudd/cuddHarwell.c +++ b/src/bdd/cudd/cuddHarwell.c @@ -7,17 +7,44 @@ Synopsis [Function to read a matrix in Harwell format.] Description [External procedures included in this module: - <ul> - <li> Cudd_addHarwell() - </ul> - ] + <ul> + <li> Cudd_addHarwell() + </ul> + ] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -27,6 +54,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -47,7 +75,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddHarwell.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddHarwell.c,v 1.9 2004/08/13 18:04:49 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -116,16 +144,16 @@ Cudd_addHarwell( DdNode *cubex, *cubey, *minterm1; int u, v, err, i, j, nv; double val; - DdNode **lx = NULL, **ly = NULL, **lxn = NULL, **lyn = NULL; /* local copies of x, y, xn, yn_ */ /* Suppress "might be used uninitialized */ - int lnx, lny; /* local copies of nx and ny */ + DdNode **lx, **ly, **lxn, **lyn; /* local copies of x, y, xn, yn_ */ + int lnx, lny; /* local copies of nx and ny */ char title[73], key[9], mxtype[4], rhstyp[4]; int totcrd, ptrcrd, indcrd, valcrd, rhscrd, nrow, ncol, nnzero, neltvl, - nrhs, nrhsix; + nrhs, nrhsix; int *colptr, *rowind; #if 0 int nguess, nexact; - int *rhsptr, *rhsind; + int *rhsptr, *rhsind; #endif if (*nx < 0 || *ny < 0) return(0); @@ -136,7 +164,7 @@ Cudd_addHarwell( /* Read the header */ err = fscanf(fp, "%72c %8c", title, key); if (err == EOF) { - return(0); + return(0); } else if (err != 2) { return(0); } @@ -146,7 +174,7 @@ Cudd_addHarwell( err = fscanf(fp, "%d %d %d %d %d", &totcrd, &ptrcrd, &indcrd, &valcrd, &rhscrd); if (err == EOF) { - return(0); + return(0); } else if (err != 5) { return(0); } @@ -154,55 +182,55 @@ Cudd_addHarwell( err = fscanf(fp, "%3s %d %d %d %d", mxtype, &nrow, &ncol, &nnzero, &neltvl); if (err == EOF) { - return(0); + return(0); } else if (err != 5) { return(0); } /* Skip FORTRAN formats */ if (rhscrd == 0) { - err = fscanf(fp, "%*s %*s %*s \n"); + err = fscanf(fp, "%*s %*s %*s \n"); } else { - err = fscanf(fp, "%*s %*s %*s %*s \n"); + err = fscanf(fp, "%*s %*s %*s %*s \n"); } if (err == EOF) { - return(0); + return(0); } else if (err != 0) { return(0); } /* Print out some stuff if requested to be verbose */ if (pr>0) { - (void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key, - mxtype, nrow, ncol, nnzero); - if (pr>1) (void) fprintf(dd->out,"%s\n", title); + (void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key, + mxtype, nrow, ncol, nnzero); + if (pr>1) (void) fprintf(dd->out,"%s\n", title); } /* Check matrix type */ if (mxtype[0] != 'R' || mxtype[1] != 'U' || mxtype[2] != 'A') { - (void) fprintf(dd->err,"%s: Illegal matrix type: %s\n", - key, mxtype); - return(0); + (void) fprintf(dd->err,"%s: Illegal matrix type: %s\n", + key, mxtype); + return(0); } if (neltvl != 0) return(0); /* Read optional 5-th line */ if (rhscrd != 0) { - err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix); - if (err == EOF) { - return(0); - } else if (err != 3) { - return(0); - } - rhstyp[3] = (char) 0; - if (rhstyp[0] != 'F') { - (void) fprintf(dd->err, - "%s: Sparse right-hand side not yet supported\n", key); - return(0); - } - if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs); + err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix); + if (err == EOF) { + return(0); + } else if (err != 3) { + return(0); + } + rhstyp[3] = (char) 0; + if (rhstyp[0] != 'F') { + (void) fprintf(dd->err, + "%s: Sparse right-hand side not yet supported\n", key); + return(0); + } + if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs); } else { - nrhs = 0; + nrhs = 0; } /* Compute the number of variables */ @@ -210,109 +238,109 @@ Cudd_addHarwell( /* row and column numbers start from 0 */ u = nrow - 1; for (i=0; u > 0; i++) { - u >>= 1; + u >>= 1; } lnx = i; if (nrhs == 0) { - v = ncol - 1; + v = ncol - 1; } else { - v = 2* (ddMax(ncol, nrhs) - 1); + v = 2* (ddMax(ncol, nrhs) - 1); } for (i=0; v > 0; i++) { - v >>= 1; + v >>= 1; } lny = i; /* Allocate or reallocate arrays for variables as needed */ if (*nx == 0) { - if (lnx > 0) { - *x = lx = ABC_ALLOC(DdNode *,lnx); + if (lnx > 0) { + *x = lx = ABC_ALLOC(DdNode *,lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = ABC_ALLOC(DdNode *,lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + *x = *xn = NULL; + } + } else if (lnx > *nx) { + *x = lx = ABC_REALLOC(DdNode *, *x, lnx); if (lx == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - *xn = lxn = ABC_ALLOC(DdNode *,lnx); + *xn = lxn = ABC_REALLOC(DdNode *, *xn, lnx); if (lxn == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } } else { - *x = *xn = NULL; - } - } else if (lnx > *nx) { - *x = lx = ABC_REALLOC(DdNode *, *x, lnx); - if (lx == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - *xn = lxn = ABC_REALLOC(DdNode *, *xn, lnx); - if (lxn == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - } else { - lx = *x; - lxn = *xn; + lx = *x; + lxn = *xn; } if (*ny == 0) { - if (lny >0) { - *y = ly = ABC_ALLOC(DdNode *,lny); + if (lny >0) { + *y = ly = ABC_ALLOC(DdNode *,lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = ABC_ALLOC(DdNode *,lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + } else { + *y = *yn_ = NULL; + } + } else if (lny > *ny) { + *y = ly = ABC_REALLOC(DdNode *, *y, lny); if (ly == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - *yn_ = lyn = ABC_ALLOC(DdNode *,lny); + *yn_ = lyn = ABC_REALLOC(DdNode *, *yn_, lny); if (lyn == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } } else { - *y = *yn_ = NULL; - } - } else if (lny > *ny) { - *y = ly = ABC_REALLOC(DdNode *, *y, lny); - if (ly == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - *yn_ = lyn = ABC_REALLOC(DdNode *, *yn_, lny); - if (lyn == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - } else { - ly = *y; - lyn = *yn_; + ly = *y; + lyn = *yn_; } /* Create new variables as needed */ for (i= *nx,nv=bx+(*nx)*sx; i < lnx; i++,nv+=sx) { - do { - dd->reordered = 0; - lx[i] = cuddUniqueInter(dd, nv, one, zero); - } while (dd->reordered == 1); - if (lx[i] == NULL) return(0); + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); cuddRef(lx[i]); - do { - dd->reordered = 0; - lxn[i] = cuddUniqueInter(dd, nv, zero, one); - } while (dd->reordered == 1); - if (lxn[i] == NULL) return(0); + do { + dd->reordered = 0; + lxn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lxn[i] == NULL) return(0); cuddRef(lxn[i]); } for (i= *ny,nv=by+(*ny)*sy; i < lny; i++,nv+=sy) { - do { - dd->reordered = 0; - ly[i] = cuddUniqueInter(dd, nv, one, zero); - } while (dd->reordered == 1); - if (ly[i] == NULL) return(0); - cuddRef(ly[i]); - do { - dd->reordered = 0; - lyn[i] = cuddUniqueInter(dd, nv, zero, one); - } while (dd->reordered == 1); - if (lyn[i] == NULL) return(0); - cuddRef(lyn[i]); + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + do { + dd->reordered = 0; + lyn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lyn[i] == NULL) return(0); + cuddRef(lyn[i]); } /* Update matrix parameters */ @@ -320,213 +348,213 @@ Cudd_addHarwell( *ny = lny; *m = nrow; if (nrhs == 0) { - *n = ncol; + *n = ncol; } else { - *n = (1 << (lny - 1)) + nrhs; + *n = (1 << (lny - 1)) + nrhs; } /* Read structure data */ colptr = ABC_ALLOC(int, ncol+1); if (colptr == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } rowind = ABC_ALLOC(int, nnzero); if (rowind == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i=0; i<ncol+1; i++) { - err = fscanf(fp, " %d ", &u); - if (err == EOF){ - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } else if (err != 1) { - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } - colptr[i] = u - 1; + err = fscanf(fp, " %d ", &u); + if (err == EOF){ + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } else if (err != 1) { + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + colptr[i] = u - 1; } if (colptr[0] != 0) { - (void) fprintf(dd->err,"%s: Unexpected colptr[0] (%d)\n", - key,colptr[0]); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } - for (i=0; i<nnzero; i++) { - err = fscanf(fp, " %d ", &u); - if (err == EOF){ - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } else if (err != 1) { + (void) fprintf(dd->err,"%s: Unexpected colptr[0] (%d)\n", + key,colptr[0]); ABC_FREE(colptr); ABC_FREE(rowind); return(0); } - rowind[i] = u - 1; + for (i=0; i<nnzero; i++) { + err = fscanf(fp, " %d ", &u); + if (err == EOF){ + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } else if (err != 1) { + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + rowind[i] = u - 1; } *E = zero; cuddRef(*E); for (j=0; j<ncol; j++) { - v = j; - cubey = one; cuddRef(cubey); - for (nv = lny - 1; nv>=0; nv--) { - if (v & 1) { - w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); - } else { - w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); - } - if (w == NULL) { - Cudd_RecursiveDeref(dd, cubey); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, cubey); - cubey = w; - v >>= 1; - } - for (i=colptr[j]; i<colptr[j+1]; i++) { - u = rowind[i]; - err = fscanf(fp, " %lf ", &val); - if (err == EOF || err != 1){ - Cudd_RecursiveDeref(dd, cubey); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } - /* Create new Constant node if necessary */ - cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val); - if (cubex == NULL) { - Cudd_RecursiveDeref(dd, cubey); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } - cuddRef(cubex); - - for (nv = lnx - 1; nv>=0; nv--) { - if (u & 1) { - w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); - } else { - w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); - } - if (w == NULL) { + v = j; + cubey = one; cuddRef(cubey); + for (nv = lny - 1; nv>=0; nv--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + cuddRef(w); Cudd_RecursiveDeref(dd, cubey); - Cudd_RecursiveDeref(dd, cubex); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); + cubey = w; + v >>= 1; } - cuddRef(w); - Cudd_RecursiveDeref(dd, cubex); - cubex = w; - u >>= 1; - } - minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); - if (minterm1 == NULL) { - Cudd_RecursiveDeref(dd, cubey); - Cudd_RecursiveDeref(dd, cubex); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); + for (i=colptr[j]; i<colptr[j+1]; i++) { + u = rowind[i]; + err = fscanf(fp, " %lf ", &val); + if (err == EOF || err != 1){ + Cudd_RecursiveDeref(dd, cubey); + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + /* Create new Constant node if necessary */ + cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val); + if (cubex == NULL) { + Cudd_RecursiveDeref(dd, cubey); + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + cuddRef(cubex); + + for (nv = lnx - 1; nv>=0; nv--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubex); + cubex = w; + u >>= 1; + } + minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); + if (minterm1 == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + cuddRef(minterm1); + Cudd_RecursiveDeref(dd, cubex); + w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + ABC_FREE(colptr); + ABC_FREE(rowind); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; } - cuddRef(minterm1); - Cudd_RecursiveDeref(dd, cubex); - w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); - if (w == NULL) { Cudd_RecursiveDeref(dd, cubey); - ABC_FREE(colptr); - ABC_FREE(rowind); - return(0); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, minterm1); - Cudd_RecursiveDeref(dd, *E); - *E = w; - } - Cudd_RecursiveDeref(dd, cubey); } ABC_FREE(colptr); ABC_FREE(rowind); /* Read right-hand sides */ for (j=0; j<nrhs; j++) { - v = j + (1<< (lny-1)); - cubey = one; cuddRef(cubey); - for (nv = lny - 1; nv>=0; nv--) { - if (v & 1) { - w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); - } else { - w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); - } - if (w == NULL) { - Cudd_RecursiveDeref(dd, cubey); - return(0); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, cubey); - cubey = w; - v >>= 1; - } - for (i=0; i<nrow; i++) { - u = i; - err = fscanf(fp, " %lf ", &val); - if (err == EOF || err != 1){ - Cudd_RecursiveDeref(dd, cubey); - return(0); - } - /* Create new Constant node if necessary */ - if (val == (double) 0.0) continue; - cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val); - if (cubex == NULL) { - Cudd_RecursiveDeref(dd, cubey); - return(0); - } - cuddRef(cubex); - - for (nv = lnx - 1; nv>=0; nv--) { - if (u & 1) { - w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); - } else { - w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); - } - if (w == NULL) { + v = j + (1<< (lny-1)); + cubey = one; cuddRef(cubey); + for (nv = lny - 1; nv>=0; nv--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + cuddRef(w); Cudd_RecursiveDeref(dd, cubey); - Cudd_RecursiveDeref(dd, cubex); - return(0); + cubey = w; + v >>= 1; } - cuddRef(w); - Cudd_RecursiveDeref(dd, cubex); - cubex = w; - u >>= 1; - } - minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); - if (minterm1 == NULL) { - Cudd_RecursiveDeref(dd, cubey); - Cudd_RecursiveDeref(dd, cubex); - return(0); + for (i=0; i<nrow; i++) { + u = i; + err = fscanf(fp, " %lf ", &val); + if (err == EOF || err != 1){ + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + /* Create new Constant node if necessary */ + if (val == (double) 0.0) continue; + cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val); + if (cubex == NULL) { + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + cuddRef(cubex); + + for (nv = lnx - 1; nv>=0; nv--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, cubex); + cubex = w; + u >>= 1; + } + minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex); + if (minterm1 == NULL) { + Cudd_RecursiveDeref(dd, cubey); + Cudd_RecursiveDeref(dd, cubex); + return(0); + } + cuddRef(minterm1); + Cudd_RecursiveDeref(dd, cubex); + w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); + if (w == NULL) { + Cudd_RecursiveDeref(dd, cubey); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, *E); + *E = w; } - cuddRef(minterm1); - Cudd_RecursiveDeref(dd, cubex); - w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1); - if (w == NULL) { Cudd_RecursiveDeref(dd, cubey); - return(0); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, minterm1); - Cudd_RecursiveDeref(dd, *E); - *E = w; - } - Cudd_RecursiveDeref(dd, cubey); } return(1); @@ -542,5 +570,7 @@ Cudd_addHarwell( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddInit.c b/src/bdd/cudd/cuddInit.c index a970dd5b..857e638c 100644 --- a/src/bdd/cudd/cuddInit.c +++ b/src/bdd/cudd/cuddInit.c @@ -7,35 +7,61 @@ Synopsis [Functions to initialize and shut down the DD manager.] Description [External procedures included in this module: - <ul> - <li> Cudd_Init() - <li> Cudd_Quit() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddZddInitUniv() - <li> cuddZddFreeUniv() - </ul> - ] + <ul> + <li> Cudd_Init() + <li> Cudd_Quit() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddZddInitUniv() + <li> cuddZddFreeUniv() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#define CUDD_MAIN -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START -#undef CUDD_MAIN + /*---------------------------------------------------------------------------*/ /* Constant declarations */ @@ -57,7 +83,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddInit.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddInit.c,v 1.33 2007/07/01 05:10:50 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -108,19 +134,19 @@ Cudd_Init( DdNode *one, *zero; unsigned int maxCacheSize; unsigned int looseUpTo; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; if (maxMemory == 0) { - maxMemory = getSoftDataLimit(); + maxMemory = getSoftDataLimit(); } looseUpTo = (unsigned int) ((maxMemory / sizeof(DdNode)) / - DD_MAX_LOOSE_FRACTION); + DD_MAX_LOOSE_FRACTION); unique = cuddInitTable(numVars,numVarsZ,numSlots,looseUpTo); - unique->maxmem = (unsigned) maxMemory / 10 * 9; if (unique == NULL) return(NULL); + unique->maxmem = (unsigned long) maxMemory / 10 * 9; maxCacheSize = (unsigned int) ((maxMemory / sizeof(DdCache)) / - DD_MAX_CACHE_FRACTION); + DD_MAX_CACHE_FRACTION); result = cuddInitCache(unique,cacheSize,maxCacheSize); if (result == 0) return(NULL); @@ -129,7 +155,7 @@ Cudd_Init( unique->stash = ABC_ALLOC(char,(maxMemory / DD_STASH_FRACTION) + 4); MMoutOfMemory = saveHandler; if (unique->stash == NULL) { - (void) fprintf(unique->err,"Unable to set aside memory\n"); + (void) fprintf(unique->err,"Unable to set aside memory\n"); } /* Initialize constants. */ @@ -141,9 +167,9 @@ Cudd_Init( cuddRef(unique->zero); #ifdef HAVE_IEEE_754 if (DD_PLUS_INF_VAL != DD_PLUS_INF_VAL * 3 || - DD_PLUS_INF_VAL != DD_PLUS_INF_VAL / 3) { - (void) fprintf(unique->err,"Warning: Crippled infinite values\n"); - (void) fprintf(unique->err,"Recompile without -DHAVE_IEEE_754\n"); + DD_PLUS_INF_VAL != DD_PLUS_INF_VAL / 3) { + (void) fprintf(unique->err,"Warning: Crippled infinite values\n"); + (void) fprintf(unique->err,"Recompile without -DHAVE_IEEE_754\n"); } #endif unique->plusinfinity = cuddUniqueConst(unique,DD_PLUS_INF_VAL); @@ -160,17 +186,17 @@ Cudd_Init( /* Create the projection functions. */ unique->vars = ABC_ALLOC(DdNodePtr,unique->maxSize); if (unique->vars == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(NULL); + unique->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < unique->size; i++) { - unique->vars[i] = cuddUniqueInter(unique,i,one,zero); - if (unique->vars[i] == NULL) return(0); - cuddRef(unique->vars[i]); + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) return(0); + cuddRef(unique->vars[i]); } if (unique->sizeZ) - cuddZddInitUniv(unique); + cuddZddInitUniv(unique); unique->memused += sizeof(DdNode *) * unique->maxSize; @@ -226,29 +252,29 @@ int cuddZddInitUniv( DdManager * zdd) { - DdNode *p, *res; - int i; + DdNode *p, *res; + int i; zdd->univ = ABC_ALLOC(DdNodePtr, zdd->sizeZ); if (zdd->univ == NULL) { - zdd->errorCode = CUDD_MEMORY_OUT; - return(0); + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); } res = DD_ONE(zdd); cuddRef(res); for (i = zdd->sizeZ - 1; i >= 0; i--) { - unsigned int index = zdd->invpermZ[i]; - p = res; - res = cuddUniqueInterZdd(zdd, index, p, p); - if (res == NULL) { - Cudd_RecursiveDerefZdd(zdd,p); - ABC_FREE(zdd->univ); - return(0); - } - cuddRef(res); - cuddDeref(p); - zdd->univ[i] = res; + unsigned int index = zdd->invpermZ[i]; + p = res; + res = cuddUniqueInterZdd(zdd, index, p, p); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd,p); + ABC_FREE(zdd->univ); + return(0); + } + cuddRef(res); + cuddDeref(p); + zdd->univ[i] = res; } #ifdef DD_VERBOSE @@ -276,8 +302,8 @@ cuddZddFreeUniv( DdManager * zdd) { if (zdd->univ) { - Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]); - ABC_FREE(zdd->univ); + Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]); + ABC_FREE(zdd->univ); } } /* end of cuddZddFreeUniv */ @@ -287,5 +313,7 @@ cuddZddFreeUniv( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddInt.h b/src/bdd/cudd/cuddInt.h index ca24a8aa..09892ba5 100644 --- a/src/bdd/cudd/cuddInt.h +++ b/src/bdd/cudd/cuddInt.h @@ -12,12 +12,39 @@ Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado - Revision [$Id: cuddInt.h,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $] + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.] + + Revision [$Id: cuddInt.h,v 1.139 2009/03/08 02:49:02 fabio Exp $] ******************************************************************************/ @@ -25,7 +52,6 @@ #define _CUDDINT - /*---------------------------------------------------------------------------*/ /* Nested includes */ /*---------------------------------------------------------------------------*/ @@ -71,65 +97,65 @@ ABC_NAMESPACE_HEADER_START /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define DD_MAXREF ((DdHalfWord) ~0) +#define DD_MAXREF ((DdHalfWord) ~0) -#define DD_DEFAULT_RESIZE 10 /* how many extra variables */ - /* should be added when resizing */ -#define DD_MEM_CHUNK 1022 +#define DD_DEFAULT_RESIZE 10 /* how many extra variables */ + /* should be added when resizing */ +#define DD_MEM_CHUNK 1022 /* These definitions work for CUDD_VALUE_TYPE == double */ -#define DD_ONE_VAL (1.0) -#define DD_ZERO_VAL (0.0) -#define DD_EPSILON (1.0e-12) +#define DD_ONE_VAL (1.0) +#define DD_ZERO_VAL (0.0) +#define DD_EPSILON (1.0e-12) /* The definitions of +/- infinity in terms of HUGE_VAL work on ** the DECstations and on many other combinations of OS/compiler. */ #ifdef HAVE_IEEE_754 -# define DD_PLUS_INF_VAL (HUGE_VAL) +# define DD_PLUS_INF_VAL (HUGE_VAL) #else -# define DD_PLUS_INF_VAL (10e301) -# define DD_CRI_HI_MARK (10e150) -# define DD_CRI_LO_MARK (-(DD_CRI_HI_MARK)) +# define DD_PLUS_INF_VAL (10e301) +# define DD_CRI_HI_MARK (10e150) +# define DD_CRI_LO_MARK (-(DD_CRI_HI_MARK)) #endif -#define DD_MINUS_INF_VAL (-(DD_PLUS_INF_VAL)) +#define DD_MINUS_INF_VAL (-(DD_PLUS_INF_VAL)) -#define DD_NON_CONSTANT ((DdNode *) 1) /* for Cudd_bddIteConstant */ +#define DD_NON_CONSTANT ((DdNode *) 1) /* for Cudd_bddIteConstant */ /* Unique table and cache management constants. */ -#define DD_MAX_SUBTABLE_DENSITY 4 /* tells when to resize a subtable */ +#define DD_MAX_SUBTABLE_DENSITY 4 /* tells when to resize a subtable */ /* gc when this percent are dead (measured w.r.t. slots, not keys) ** The first limit (LO) applies normally. The second limit applies when ** the package believes more space for the unique table (i.e., more dead ** nodes) would improve performance, and the unique table is not already ** too large. The third limit applies when memory is low. */ -#define DD_GC_FRAC_LO DD_MAX_SUBTABLE_DENSITY * 0.25 -#define DD_GC_FRAC_HI DD_MAX_SUBTABLE_DENSITY * 1.0 -#define DD_GC_FRAC_MIN 0.2 -#define DD_MIN_HIT 30 /* resize cache when hit ratio - above this percentage (default) */ -#define DD_MAX_LOOSE_FRACTION 5 /* 1 / (max fraction of memory used for - unique table in fast growth mode) */ -#define DD_MAX_CACHE_FRACTION 3 /* 1 / (max fraction of memory used for - computed table if resizing enabled) */ -#define DD_STASH_FRACTION 64 /* 1 / (fraction of memory set - aside for emergencies) */ +#define DD_GC_FRAC_LO DD_MAX_SUBTABLE_DENSITY * 0.25 +#define DD_GC_FRAC_HI DD_MAX_SUBTABLE_DENSITY * 1.0 +#define DD_GC_FRAC_MIN 0.2 +#define DD_MIN_HIT 30 /* resize cache when hit ratio + above this percentage (default) */ +#define DD_MAX_LOOSE_FRACTION 5 /* 1 / (max fraction of memory used for + unique table in fast growth mode) */ +#define DD_MAX_CACHE_FRACTION 3 /* 1 / (max fraction of memory used for + computed table if resizing enabled) */ +#define DD_STASH_FRACTION 64 /* 1 / (fraction of memory set + aside for emergencies) */ #define DD_MAX_CACHE_TO_SLOTS_RATIO 4 /* used to limit the cache size */ /* Variable ordering default parameter values. */ -#define DD_SIFT_MAX_VAR 1000 -#define DD_SIFT_MAX_SWAPS 2000000 -#define DD_DEFAULT_RECOMB 0 -#define DD_MAX_REORDER_GROWTH 1.2 -#define DD_FIRST_REORDER 4004 /* 4 for the constants */ -#define DD_DYN_RATIO 2 /* when to dynamically reorder */ +#define DD_SIFT_MAX_VAR 1000 +#define DD_SIFT_MAX_SWAPS 2000000 +#define DD_DEFAULT_RECOMB 0 +#define DD_MAX_REORDER_GROWTH 1.2 +#define DD_FIRST_REORDER 4004 /* 4 for the constants */ +#define DD_DYN_RATIO 2 /* when to dynamically reorder */ /* Primes for cache hash functions. */ -#define DD_P1 12582917 -#define DD_P2 4256249 -#define DD_P3 741457 -#define DD_P4 1618033999 +#define DD_P1 12582917 +#define DD_P2 4256249 +#define DD_P3 741457 +#define DD_P4 1618033999 /* Cache tags for 3-operand operators. These tags are stored in the ** least significant bits of the cache operand pointers according to @@ -143,29 +169,30 @@ ABC_NAMESPACE_HEADER_START ** entry. It can by any even digit between 0 and e. This gives a total ** of 5 bits for the tag proper, which means a maximum of 32 three-operand ** operations. */ -#define DD_ADD_ITE_TAG 0x02 -#define DD_BDD_AND_ABSTRACT_TAG 0x06 -#define DD_BDD_XOR_EXIST_ABSTRACT_TAG 0x0a -#define DD_BDD_ITE_TAG 0x0e -#define DD_ADD_BDD_DO_INTERVAL_TAG 0x22 -#define DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG 0x26 -#define DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG 0x2a -#define DD_BDD_COMPOSE_RECUR_TAG 0x2e -#define DD_ADD_COMPOSE_RECUR_TAG 0x42 -#define DD_ADD_NON_SIM_COMPOSE_TAG 0x46 -#define DD_EQUIV_DC_TAG 0x4a -#define DD_ZDD_ITE_TAG 0x4e -#define DD_ADD_ITE_CONSTANT_TAG 0x62 -#define DD_ADD_EVAL_CONST_TAG 0x66 -#define DD_BDD_ITE_CONSTANT_TAG 0x6a -#define DD_ADD_OUT_SUM_TAG 0x6e -#define DD_BDD_LEQ_UNLESS_TAG 0x82 -#define DD_ADD_TRIANGLE_TAG 0x86 +#define DD_ADD_ITE_TAG 0x02 +#define DD_BDD_AND_ABSTRACT_TAG 0x06 +#define DD_BDD_XOR_EXIST_ABSTRACT_TAG 0x0a +#define DD_BDD_ITE_TAG 0x0e +#define DD_ADD_BDD_DO_INTERVAL_TAG 0x22 +#define DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG 0x26 +#define DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG 0x2a +#define DD_BDD_COMPOSE_RECUR_TAG 0x2e +#define DD_ADD_COMPOSE_RECUR_TAG 0x42 +#define DD_ADD_NON_SIM_COMPOSE_TAG 0x46 +#define DD_EQUIV_DC_TAG 0x4a +#define DD_ZDD_ITE_TAG 0x4e +#define DD_ADD_ITE_CONSTANT_TAG 0x62 +#define DD_ADD_EVAL_CONST_TAG 0x66 +#define DD_BDD_ITE_CONSTANT_TAG 0x6a +#define DD_ADD_OUT_SUM_TAG 0x6e +#define DD_BDD_LEQ_UNLESS_TAG 0x82 +#define DD_ADD_TRIANGLE_TAG 0x86 /* Generator constants. */ #define CUDD_GEN_CUBES 0 -#define CUDD_GEN_NODES 1 -#define CUDD_GEN_ZDD_PATHS 2 +#define CUDD_GEN_PRIMES 1 +#define CUDD_GEN_NODES 2 +#define CUDD_GEN_ZDD_PATHS 3 #define CUDD_GEN_EMPTY 0 #define CUDD_GEN_NONEMPTY 1 @@ -175,26 +202,37 @@ ABC_NAMESPACE_HEADER_START /*---------------------------------------------------------------------------*/ struct DdGen { - DdManager *manager; - int type; - int status; + DdManager *manager; + int type; + int status; union { - struct { - int *cube; - CUDD_VALUE_TYPE value; - } cubes; - struct { - st_table *visited; - st_generator *stGen; - } nodes; + struct { + int *cube; + CUDD_VALUE_TYPE value; + } cubes; + struct { + int *cube; + DdNode *ub; + } primes; + struct { + int size; + } nodes; } gen; struct { - int sp; - DdNode **stack; + int sp; +#ifdef __osf__ +#pragma pointer_size save +#pragma pointer_size short +#endif + DdNode **stack; +#ifdef __osf__ +#pragma pointer_size restore +#endif } stack; - DdNode *node; + DdNode *node; }; + /*---------------------------------------------------------------------------*/ /* Type declarations */ /*---------------------------------------------------------------------------*/ @@ -204,9 +242,9 @@ struct DdGen { ** are passed the manager as argument; they should return 1 if ** successful and 0 otherwise. */ -typedef struct DdHook { /* hook list element */ - int (*f) ARGS((DdManager *, char *, void *)); /* function to be called */ - struct DdHook *next; /* next element in the list */ +typedef struct DdHook { /* hook list element */ + DD_HFP f; /* function to be called */ + struct DdHook *next; /* next element in the list */ } DdHook; #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 @@ -271,173 +309,173 @@ typedef struct DdHashTable { } DdHashTable; typedef struct DdCache { - DdNode *f,*g; /* DDs */ - ptruint h; /* either operator or DD */ - DdNode *data; /* already constructed DD */ + DdNode *f,*g; /* DDs */ + ptruint h; /* either operator or DD */ + DdNode *data; /* already constructed DD */ #ifdef DD_CACHE_PROFILE ptrint count; #endif } DdCache; -typedef struct DdSubtable { /* subtable for one index */ - DdNode **nodelist; /* hash table */ - int shift; /* shift for hash function */ - unsigned int slots; /* size of the hash table */ - unsigned int keys; /* number of nodes stored in this table */ - unsigned int maxKeys; /* slots * DD_MAX_SUBTABLE_DENSITY */ - unsigned int dead; /* number of dead nodes in this table */ - unsigned int next; /* index of next variable in group */ - int bindVar; /* flag to bind this variable to its level */ +typedef struct DdSubtable { /* subtable for one index */ + DdNode **nodelist; /* hash table */ + int shift; /* shift for hash function */ + unsigned int slots; /* size of the hash table */ + unsigned int keys; /* number of nodes stored in this table */ + unsigned int maxKeys; /* slots * DD_MAX_SUBTABLE_DENSITY */ + unsigned int dead; /* number of dead nodes in this table */ + unsigned int next; /* index of next variable in group */ + int bindVar; /* flag to bind this variable to its level */ /* Fields for lazy sifting. */ Cudd_VariableType varType; /* variable type (ps, ns, pi) */ int pairIndex; /* corresponding variable index (ps <-> ns) */ - int varHandled; /* flag: 1 means variable is already handled */ + int varHandled; /* flag: 1 means variable is already handled */ Cudd_LazyGroupType varToBeGrouped; /* tells what grouping to apply */ } DdSubtable; -struct DdManager { /* specialized DD symbol table */ +struct DdManager { /* specialized DD symbol table */ /* Constants */ - DdNode sentinel; /* for collision lists */ - DdNode *one; /* constant 1 */ - DdNode *zero; /* constant 0 */ - DdNode *plusinfinity; /* plus infinity */ - DdNode *minusinfinity; /* minus infinity */ - DdNode *background; /* background value */ + DdNode sentinel; /* for collision lists */ + DdNode *one; /* constant 1 */ + DdNode *zero; /* constant 0 */ + DdNode *plusinfinity; /* plus infinity */ + DdNode *minusinfinity; /* minus infinity */ + DdNode *background; /* background value */ /* Computed Table */ - DdCache *acache; /* address of allocated memory for cache */ - DdCache *cache; /* the cache-based computed table */ + DdCache *acache; /* address of allocated memory for cache */ + DdCache *cache; /* the cache-based computed table */ unsigned int cacheSlots; /* total number of cache entries */ - int cacheShift; /* shift value for cache hash function */ - double cacheMisses; /* number of cache misses (since resizing) */ - double cacheHits; /* number of cache hits (since resizing) */ - double minHit; /* hit percentage above which to resize */ - int cacheSlack; /* slots still available for resizing */ - unsigned int maxCacheHard; /* hard limit for cache size */ + int cacheShift; /* shift value for cache hash function */ + double cacheMisses; /* number of cache misses (since resizing) */ + double cacheHits; /* number of cache hits (since resizing) */ + double minHit; /* hit percentage above which to resize */ + int cacheSlack; /* slots still available for resizing */ + unsigned int maxCacheHard; /* hard limit for cache size */ /* Unique Table */ - int size; /* number of unique subtables */ - int sizeZ; /* for ZDD */ - int maxSize; /* max number of subtables before resizing */ - int maxSizeZ; /* for ZDD */ - DdSubtable *subtables; /* array of unique subtables */ - DdSubtable *subtableZ; /* for ZDD */ - DdSubtable constants; /* unique subtable for the constants */ - unsigned int slots; /* total number of hash buckets */ - unsigned int keys; /* total number of BDD and ADD nodes */ - unsigned int keysZ; /* total number of ZDD nodes */ - unsigned int dead; /* total number of dead BDD and ADD nodes */ - unsigned int deadZ; /* total number of dead ZDD nodes */ - unsigned int maxLive; /* maximum number of live nodes */ - unsigned int minDead; /* do not GC if fewer than these dead */ - double gcFrac; /* gc when this fraction is dead */ - int gcEnabled; /* gc is enabled */ - unsigned int looseUpTo; /* slow growth beyond this limit */ - /* (measured w.r.t. slots, not keys) */ - unsigned int initSlots; /* initial size of a subtable */ - DdNode **stack; /* stack for iterative procedures */ - double allocated; /* number of nodes allocated */ - /* (not during reordering) */ - double reclaimed; /* number of nodes brought back from the dead */ - int isolated; /* isolated projection functions */ - int *perm; /* current variable perm. (index to level) */ - int *permZ; /* for ZDD */ - int *invperm; /* current inv. var. perm. (level to index) */ - int *invpermZ; /* for ZDD */ - DdNode **vars; /* projection functions */ - int *map; /* variable map for fast swap */ - DdNode **univ; /* ZDD 1 for each variable */ - int linearSize; /* number of rows and columns of linear */ - long *interact; /* interacting variable matrix */ - long *linear; /* linear transform matrix */ + int size; /* number of unique subtables */ + int sizeZ; /* for ZDD */ + int maxSize; /* max number of subtables before resizing */ + int maxSizeZ; /* for ZDD */ + DdSubtable *subtables; /* array of unique subtables */ + DdSubtable *subtableZ; /* for ZDD */ + DdSubtable constants; /* unique subtable for the constants */ + unsigned int slots; /* total number of hash buckets */ + unsigned int keys; /* total number of BDD and ADD nodes */ + unsigned int keysZ; /* total number of ZDD nodes */ + unsigned int dead; /* total number of dead BDD and ADD nodes */ + unsigned int deadZ; /* total number of dead ZDD nodes */ + unsigned int maxLive; /* maximum number of live nodes */ + unsigned int minDead; /* do not GC if fewer than these dead */ + double gcFrac; /* gc when this fraction is dead */ + int gcEnabled; /* gc is enabled */ + unsigned int looseUpTo; /* slow growth beyond this limit */ + /* (measured w.r.t. slots, not keys) */ + unsigned int initSlots; /* initial size of a subtable */ + DdNode **stack; /* stack for iterative procedures */ + double allocated; /* number of nodes allocated */ + /* (not during reordering) */ + double reclaimed; /* number of nodes brought back from the dead */ + int isolated; /* isolated projection functions */ + int *perm; /* current variable perm. (index to level) */ + int *permZ; /* for ZDD */ + int *invperm; /* current inv. var. perm. (level to index) */ + int *invpermZ; /* for ZDD */ + DdNode **vars; /* projection functions */ + int *map; /* variable map for fast swap */ + DdNode **univ; /* ZDD 1 for each variable */ + int linearSize; /* number of rows and columns of linear */ + long *interact; /* interacting variable matrix */ + long *linear; /* linear transform matrix */ /* Memory Management */ - DdNode **memoryList; /* memory manager for symbol table */ - DdNode *nextFree; /* list of free nodes */ - char *stash; /* memory reserve */ + DdNode **memoryList; /* memory manager for symbol table */ + DdNode *nextFree; /* list of free nodes */ + char *stash; /* memory reserve */ #ifndef DD_NO_DEATH_ROW - DdNode **deathRow; /* queue for dereferencing */ - int deathRowDepth; /* number of slots in the queue */ - int nextDead; /* index in the queue */ - unsigned deadMask; /* mask for circular index update */ + DdNode **deathRow; /* queue for dereferencing */ + int deathRowDepth; /* number of slots in the queue */ + int nextDead; /* index in the queue */ + unsigned deadMask; /* mask for circular index update */ #endif /* General Parameters */ CUDD_VALUE_TYPE epsilon; /* tolerance on comparisons */ /* Dynamic Reordering Parameters */ - int reordered; /* flag set at the end of reordering */ - int reorderings; /* number of calls to Cudd_ReduceHeap */ - int siftMaxVar; /* maximum number of vars sifted */ - int siftMaxSwap; /* maximum number of swaps per sifting */ - double maxGrowth; /* maximum growth during reordering */ - double maxGrowthAlt; /* alternate maximum growth for reordering */ - int reordCycle; /* how often to apply alternate threshold */ - int autoDyn; /* automatic dynamic reordering flag (BDD) */ - int autoDynZ; /* automatic dynamic reordering flag (ZDD) */ + int reordered; /* flag set at the end of reordering */ + int reorderings; /* number of calls to Cudd_ReduceHeap */ + int siftMaxVar; /* maximum number of vars sifted */ + int siftMaxSwap; /* maximum number of swaps per sifting */ + double maxGrowth; /* maximum growth during reordering */ + double maxGrowthAlt; /* alternate maximum growth for reordering */ + int reordCycle; /* how often to apply alternate threshold */ + int autoDyn; /* automatic dynamic reordering flag (BDD) */ + int autoDynZ; /* automatic dynamic reordering flag (ZDD) */ Cudd_ReorderingType autoMethod; /* default reordering method */ Cudd_ReorderingType autoMethodZ; /* default reordering method (ZDD) */ - int realign; /* realign ZDD order after BDD reordering */ - int realignZ; /* realign BDD order after ZDD reordering */ - unsigned int nextDyn; /* reorder if this size is reached */ - unsigned int countDead; /* if 0, count deads to trigger reordering */ - MtrNode *tree; /* Variable group tree (BDD) */ - MtrNode *treeZ; /* Variable group tree (ZDD) */ + int realign; /* realign ZDD order after BDD reordering */ + int realignZ; /* realign BDD order after ZDD reordering */ + unsigned int nextDyn; /* reorder if this size is reached */ + unsigned int countDead; /* if 0, count deads to trigger reordering */ + MtrNode *tree; /* Variable group tree (BDD) */ + MtrNode *treeZ; /* Variable group tree (ZDD) */ Cudd_AggregationType groupcheck; /* Used during group sifting */ - int recomb; /* Used during group sifting */ - int symmviolation; /* Used during group sifting */ - int arcviolation; /* Used during group sifting */ - int populationSize; /* population size for GA */ - int numberXovers; /* number of crossovers for GA */ - DdLocalCache *localCaches; /* local caches currently in existence */ + int recomb; /* Used during group sifting */ + int symmviolation; /* Used during group sifting */ + int arcviolation; /* Used during group sifting */ + int populationSize; /* population size for GA */ + int numberXovers; /* number of crossovers for GA */ + DdLocalCache *localCaches; /* local caches currently in existence */ #ifdef __osf__ #pragma pointer_size restore #endif - char *hooks; /* application-specific field (used by vis) */ - DdHook *preGCHook; /* hooks to be called before GC */ - DdHook *postGCHook; /* hooks to be called after GC */ - DdHook *preReorderingHook; /* hooks to be called before reordering */ - DdHook *postReorderingHook; /* hooks to be called after reordering */ - FILE *out; /* stdout for this manager */ - FILE *err; /* stderr for this manager */ + char *hooks; /* application-specific field (used by vis) */ + DdHook *preGCHook; /* hooks to be called before GC */ + DdHook *postGCHook; /* hooks to be called after GC */ + DdHook *preReorderingHook; /* hooks to be called before reordering */ + DdHook *postReorderingHook; /* hooks to be called after reordering */ + FILE *out; /* stdout for this manager */ + FILE *err; /* stderr for this manager */ #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short #endif - Cudd_ErrorType errorCode; /* info on last error */ + Cudd_ErrorType errorCode; /* info on last error */ /* Statistical counters. */ - long memused; /* total memory allocated for the manager */ - long maxmem; /* target maximum memory */ - long maxmemhard; /* hard limit for maximum memory */ - int garbageCollections; /* number of garbage collections */ - long GCTime; /* total time spent in garbage collection */ - long reordTime; /* total time spent in reordering */ - double totCachehits; /* total number of cache hits */ - double totCacheMisses; /* total number of cache misses */ - double cachecollisions; /* number of cache collisions */ - double cacheinserts; /* number of cache insertions */ + unsigned long memused; /* total memory allocated for the manager */ + unsigned long maxmem; /* target maximum memory */ + unsigned long maxmemhard; /* hard limit for maximum memory */ + int garbageCollections; /* number of garbage collections */ + long GCTime; /* total time spent in garbage collection */ + long reordTime; /* total time spent in reordering */ + double totCachehits; /* total number of cache hits */ + double totCacheMisses; /* total number of cache misses */ + double cachecollisions; /* number of cache collisions */ + double cacheinserts; /* number of cache insertions */ double cacheLastInserts; /* insertions at the last cache resizing */ - double cachedeletions; /* number of deletions during garbage coll. */ + double cachedeletions; /* number of deletions during garbage coll. */ #ifdef DD_STATS - double nodesFreed; /* number of nodes returned to the free list */ - double nodesDropped; /* number of nodes killed by dereferencing */ + double nodesFreed; /* number of nodes returned to the free list */ + double nodesDropped; /* number of nodes killed by dereferencing */ #endif - unsigned int peakLiveNodes; /* maximum number of live nodes */ + unsigned int peakLiveNodes; /* maximum number of live nodes */ #ifdef DD_UNIQUE_PROFILE - double uniqueLookUps; /* number of unique table lookups */ - double uniqueLinks; /* total distance traveled in coll. chains */ + double uniqueLookUps; /* number of unique table lookups */ + double uniqueLinks; /* total distance traveled in coll. chains */ #endif #ifdef DD_COUNT - double recursiveCalls; /* number of recursive calls */ + double recursiveCalls; /* number of recursive calls */ #ifdef DD_STATS - double nextSample; /* when to write next line of stats */ + double nextSample; /* when to write next line of stats */ #endif - double swapSteps; /* number of elementary reordering steps */ + double swapSteps; /* number of elementary reordering steps */ #endif #ifdef DD_MIS /* mis/verif compatibility fields */ - array_t *iton; /* maps ids in ddNode to node_t */ + array_t *iton; /* maps ids in ddNode to node_t */ array_t *order; /* copy of order_list */ - lsHandle handle; /* where it is in network BDD list */ + lsHandle handle; /* where it is in network BDD list */ network_t *network; - st_table *local_order; /* for local BDDs */ - int nvars; /* variables used so far */ - int threshold; /* for pseudo var threshold value*/ + st_table *local_order; /* for local BDDs */ + int nvars; /* variables used so far */ + int threshold; /* for pseudo var threshold value*/ #endif DdNode * bFunc; DdNode * bFunc2; @@ -496,13 +534,31 @@ typedef struct DdLevelQueue { SideEffects [None] - SeeAlso [cuddAllocNode cuddDynamicAllocNode] + SeeAlso [cuddAllocNode cuddDynamicAllocNode cuddDeallocMove] ******************************************************************************/ #define cuddDeallocNode(unique,node) \ (node)->next = (unique)->nextFree; \ (unique)->nextFree = node; +/**Macro*********************************************************************** + + Synopsis [Adds node to the head of the free list.] + + Description [Adds node to the head of the free list. Does not + deallocate memory chunks that become free. This function is also + used by the dynamic reordering functions.] + + SideEffects [None] + + SeeAlso [cuddDeallocNode cuddDynamicAllocNode] + +******************************************************************************/ +#define cuddDeallocMove(unique,node) \ + ((DdNode *)(node))->ref = 0; \ + ((DdNode *)(node))->next = (unique)->nextFree; \ + (unique)->nextFree = (DdNode *)(node); + /**Macro*********************************************************************** @@ -620,7 +676,7 @@ typedef struct DdLevelQueue { SeeAlso [Cudd_ReadPerm] ******************************************************************************/ -#define cuddI(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->perm[(index)]) +#define cuddI(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->perm[(index)]) /**Macro*********************************************************************** @@ -638,7 +694,7 @@ typedef struct DdLevelQueue { SeeAlso [Cudd_ReadPermZdd] ******************************************************************************/ -#define cuddIZ(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->permZ[(index)]) +#define cuddIZ(dd,index) (((index)==CUDD_CONST_INDEX)?(int)(index):(dd)->permZ[(index)]) /**Macro*********************************************************************** @@ -654,8 +710,8 @@ typedef struct DdLevelQueue { ******************************************************************************/ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 #define ddHash(f,g,s) \ -((((unsigned)(unsigned long)(f) * DD_P1 + \ - (unsigned)(unsigned long)(g)) * DD_P2) >> (s)) +((((unsigned)(ptruint)(f) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (s)) #else #define ddHash(f,g,s) \ ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s)) @@ -675,9 +731,9 @@ typedef struct DdLevelQueue { ******************************************************************************/ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 #define ddCHash(o,f,g,h,s) \ -((((((unsigned)(unsigned long)(f) + (unsigned)(unsigned long)(o)) * DD_P1 + \ - (unsigned)(unsigned long)(g)) * DD_P2 + \ - (unsigned)(unsigned long)(h)) * DD_P3) >> (s)) +((((((unsigned)(ptruint)(f) + (unsigned)(ptruint)(o)) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2 + \ + (unsigned)(ptruint)(h)) * DD_P3) >> (s)) #else #define ddCHash(o,f,g,h,s) \ ((((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2 + \ @@ -699,8 +755,8 @@ typedef struct DdLevelQueue { ******************************************************************************/ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 #define ddCHash2(o,f,g,s) \ -(((((unsigned)(unsigned long)(f) + (unsigned)(unsigned long)(o)) * DD_P1 + \ - (unsigned)(unsigned long)(g)) * DD_P2) >> (s)) +(((((unsigned)(ptruint)(f) + (unsigned)(ptruint)(o)) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (s)) #else #define ddCHash2(o,f,g,s) \ (((((unsigned)(f) + (unsigned)(o)) * DD_P1 + (unsigned)(g)) * DD_P2) >> (s)) @@ -825,7 +881,7 @@ typedef struct DdLevelQueue { SeeAlso [DD_ZERO DD_PLUS_INFINITY DD_MINUS_INFINITY] ******************************************************************************/ -#define DD_ONE(dd) ((dd)->one) +#define DD_ONE(dd) ((dd)->one) /**Macro*********************************************************************** @@ -893,7 +949,7 @@ typedef struct DdLevelQueue { #ifdef HAVE_IEEE_754 #define cuddAdjust(x) #else -#define cuddAdjust(x) ((x) = ((x) >= DD_CRI_HI_MARK) ? DD_PLUS_INF_VAL : (((x) <= DD_CRI_LO_MARK) ? DD_MINUS_INF_VAL : (x))) +#define cuddAdjust(x) ((x) = ((x) >= DD_CRI_HI_MARK) ? DD_PLUS_INF_VAL : (((x) <= DD_CRI_LO_MARK) ? DD_MINUS_INF_VAL : (x))) #endif @@ -909,7 +965,7 @@ typedef struct DdLevelQueue { SeeAlso [DD_MSDIGIT] ******************************************************************************/ -#define DD_LSDIGIT(x) ((x) & DD_APA_MASK) +#define DD_LSDIGIT(x) ((x) & DD_APA_MASK) /**Macro*********************************************************************** @@ -924,7 +980,7 @@ typedef struct DdLevelQueue { SeeAlso [DD_LSDIGIT] ******************************************************************************/ -#define DD_MSDIGIT(x) ((x) >> DD_APA_BITS) +#define DD_MSDIGIT(x) ((x) >> DD_APA_BITS) /**Macro*********************************************************************** @@ -961,181 +1017,184 @@ dd->nextSample += 250000;} /* Function prototypes */ /*---------------------------------------------------------------------------*/ -EXTERN DdNode * cuddAddExistAbstractRecur ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * cuddAddUnivAbstractRecur ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * cuddAddOrAbstractRecur ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * cuddAddApplyRecur ARGS((DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g)); -EXTERN DdNode * cuddAddMonadicApplyRecur ARGS((DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f)); -EXTERN DdNode * cuddAddScalarInverseRecur ARGS((DdManager *dd, DdNode *f, DdNode *epsilon)); -EXTERN DdNode * cuddAddIteRecur ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * cuddAddCmplRecur ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * cuddAddNegateRecur ARGS((DdManager *dd, DdNode *f)); -EXTERN DdNode * cuddAddRoundOffRecur ARGS((DdManager *dd, DdNode *f, double trunc)); -EXTERN DdNode * cuddUnderApprox ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, int safe, double quality)); -EXTERN DdNode * cuddRemapUnderApprox ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, double quality)); -EXTERN DdNode * cuddBiasedUnderApprox ARGS((DdManager *dd, DdNode *f, DdNode *b, int numVars, int threshold, double quality1, double quality0)); -EXTERN DdNode * cuddBddAndAbstractRecur ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)); -EXTERN int cuddAnnealing ARGS((DdManager *table, int lower, int upper)); -EXTERN DdNode * cuddBddExistAbstractRecur ARGS((DdManager *manager, DdNode *f, DdNode *cube)); -EXTERN DdNode * cuddBddXorExistAbstractRecur ARGS((DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)); -EXTERN DdNode * cuddBddBooleanDiffRecur ARGS((DdManager *manager, DdNode *f, DdNode *var)); -EXTERN DdNode * cuddBddIteRecur ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * cuddBddIntersectRecur ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddBddAndRecur ARGS((DdManager *manager, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddBddXorRecur ARGS((DdManager *manager, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddBddTransfer ARGS((DdManager *ddS, DdManager *ddD, DdNode *f)); -EXTERN DdNode * cuddAddBddDoPattern ARGS((DdManager *dd, DdNode *f)); -EXTERN int cuddInitCache ARGS((DdManager *unique, unsigned int cacheSize, unsigned int maxCacheSize)); -EXTERN void cuddCacheInsert ARGS((DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)); -EXTERN void cuddCacheInsert2 ARGS((DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g, DdNode *data)); -EXTERN void cuddCacheInsert1 ARGS((DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f, DdNode *data)); -EXTERN DdNode * cuddCacheLookup ARGS((DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * cuddCacheLookupZdd ARGS((DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * cuddCacheLookup2 ARGS((DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)); -EXTERN DdNode * cuddCacheLookup1 ARGS((DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f)); -EXTERN DdNode * cuddCacheLookup2Zdd ARGS((DdManager *table, DdNode * (*)(DdManager *, DdNode *, DdNode *), DdNode *f, DdNode *g)); -EXTERN DdNode * cuddCacheLookup1Zdd ARGS((DdManager *table, DdNode * (*)(DdManager *, DdNode *), DdNode *f)); -EXTERN DdNode * cuddConstantLookup ARGS((DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)); -EXTERN int cuddCacheProfile ARGS((DdManager *table, FILE *fp)); -EXTERN void cuddCacheResize ARGS((DdManager *table)); -EXTERN void cuddCacheFlush ARGS((DdManager *table)); -EXTERN int cuddComputeFloorLog2 ARGS((unsigned int value)); -EXTERN int cuddHeapProfile ARGS((DdManager *dd)); -EXTERN void cuddPrintNode ARGS((DdNode *f, FILE *fp)); -EXTERN void cuddPrintVarGroups ARGS((DdManager * dd, MtrNode * root, int zdd, int silent)); -EXTERN DdNode * cuddBddClippingAnd ARGS((DdManager *dd, DdNode *f, DdNode *g, int maxDepth, int direction)); -EXTERN DdNode * cuddBddClippingAndAbstract ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *cube, int maxDepth, int direction)); -EXTERN void cuddGetBranches ARGS((DdNode *g, DdNode **g1, DdNode **g0)); -EXTERN int cuddCheckCube ARGS((DdManager *dd, DdNode *g)); -EXTERN DdNode * cuddCofactorRecur ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddBddComposeRecur ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *proj)); -EXTERN DdNode * cuddAddComposeRecur ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *proj)); -EXTERN int cuddExact ARGS((DdManager *table, int lower, int upper)); -EXTERN DdNode * cuddBddConstrainRecur ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * cuddBddRestrictRecur ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * cuddAddConstrainRecur ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * cuddAddRestrictRecur ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN DdNode * cuddBddLICompaction ARGS((DdManager *dd, DdNode *f, DdNode *c)); -EXTERN int cuddGa ARGS((DdManager *table, int lower, int upper)); -EXTERN int cuddTreeSifting ARGS((DdManager *table, Cudd_ReorderingType method, int TimeStop)); -EXTERN int cuddZddInitUniv ARGS((DdManager *zdd)); -EXTERN void cuddZddFreeUniv ARGS((DdManager *zdd)); -EXTERN void cuddSetInteract ARGS((DdManager *table, int x, int y)); -EXTERN int cuddTestInteract ARGS((DdManager *table, int x, int y)); -EXTERN int cuddInitInteract ARGS((DdManager *table)); -EXTERN DdLocalCache * cuddLocalCacheInit ARGS((DdManager *manager, unsigned int keySize, unsigned int cacheSize, unsigned int maxCacheSize)); -EXTERN void cuddLocalCacheQuit ARGS((DdLocalCache *cache)); -EXTERN void cuddLocalCacheInsert ARGS((DdLocalCache *cache, DdNodePtr *key, DdNode *value)); -EXTERN DdNode * cuddLocalCacheLookup ARGS((DdLocalCache *cache, DdNodePtr *key)); -EXTERN void cuddLocalCacheClearDead ARGS((DdManager *manager)); -EXTERN int cuddIsInDeathRow ARGS((DdManager *dd, DdNode *f)); -EXTERN int cuddTimesInDeathRow ARGS((DdManager *dd, DdNode *f)); -EXTERN void cuddLocalCacheClearAll ARGS((DdManager *manager)); +extern DdNode * cuddAddExistAbstractRecur( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * cuddAddUnivAbstractRecur( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * cuddAddOrAbstractRecur( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * cuddAddApplyRecur( DdManager * dd, DdNode * (*)(DdManager * , DdNode ** , DdNode **), DdNode * f, DdNode * g ); +extern DdNode * cuddAddMonadicApplyRecur( DdManager * dd, DdNode * (*)(DdManager * , DdNode *), DdNode * f ); +extern DdNode * cuddAddScalarInverseRecur( DdManager * dd, DdNode * f, DdNode * epsilon ); +extern DdNode * cuddAddIteRecur( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * cuddAddCmplRecur( DdManager * dd, DdNode * f ); +extern DdNode * cuddAddNegateRecur( DdManager * dd, DdNode * f ); +extern DdNode * cuddAddRoundOffRecur( DdManager * dd, DdNode * f, double trunc ); +extern DdNode * cuddUnderApprox( DdManager * dd, DdNode * f, int numVars, int threshold, int safe, double quality ); +extern DdNode * cuddRemapUnderApprox( DdManager * dd, DdNode * f, int numVars, int threshold, double quality ); +extern DdNode * cuddBiasedUnderApprox( DdManager * dd, DdNode * f, DdNode * b, int numVars, int threshold, double quality1, double quality0 ); +extern DdNode * cuddBddAndAbstractRecur( DdManager * manager, DdNode * f, DdNode * g, DdNode * cube ); +extern int cuddAnnealing( DdManager * table, int lower, int upper ); +extern DdNode * cuddBddExistAbstractRecur( DdManager * manager, DdNode * f, DdNode * cube ); +extern DdNode * cuddBddXorExistAbstractRecur( DdManager * manager, DdNode * f, DdNode * g, DdNode * cube ); +extern DdNode * cuddBddBooleanDiffRecur( DdManager * manager, DdNode * f, DdNode * var ); +extern DdNode * cuddBddIteRecur( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * cuddBddIntersectRecur( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddBddAndRecur( DdManager * manager, DdNode * f, DdNode * g ); +extern DdNode * cuddBddXorRecur( DdManager * manager, DdNode * f, DdNode * g ); +extern DdNode * cuddBddTransfer( DdManager * ddS, DdManager * ddD, DdNode * f ); +extern DdNode * cuddAddBddDoPattern( DdManager * dd, DdNode * f ); +extern int cuddInitCache( DdManager * unique, unsigned int cacheSize, unsigned int maxCacheSize ); +extern void cuddCacheInsert( DdManager * table, ptruint op, DdNode * f, DdNode * g, DdNode * h, DdNode * data ); +extern void cuddCacheInsert2( DdManager * table, DdNode * (*)(DdManager * , DdNode * , DdNode *), DdNode * f, DdNode * g, DdNode * data ); +extern void cuddCacheInsert1( DdManager * table, DdNode * (*)(DdManager * , DdNode *), DdNode * f, DdNode * data ); +extern DdNode * cuddCacheLookup( DdManager * table, ptruint op, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * cuddCacheLookupZdd( DdManager * table, ptruint op, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * cuddCacheLookup2( DdManager * table, DdNode * (*)(DdManager * , DdNode * , DdNode *), DdNode * f, DdNode * g ); +extern DdNode * cuddCacheLookup1( DdManager * table, DdNode * (*)(DdManager * , DdNode *), DdNode * f ); +extern DdNode * cuddCacheLookup2Zdd( DdManager * table, DdNode * (*)(DdManager * , DdNode * , DdNode *), DdNode * f, DdNode * g ); +extern DdNode * cuddCacheLookup1Zdd( DdManager * table, DdNode * (*)(DdManager * , DdNode *), DdNode * f ); +extern DdNode * cuddConstantLookup( DdManager * table, ptruint op, DdNode * f, DdNode * g, DdNode * h ); +extern int cuddCacheProfile( DdManager * table, FILE * fp ); +extern void cuddCacheResize( DdManager * table ); +extern void cuddCacheFlush( DdManager * table ); +extern int cuddComputeFloorLog2( unsigned int value ); +extern int cuddHeapProfile( DdManager * dd ); +extern void cuddPrintNode( DdNode * f, FILE * fp ); +extern void cuddPrintVarGroups( DdManager * dd, MtrNode * root, int zdd, int silent ); +extern DdNode * cuddBddClippingAnd( DdManager * dd, DdNode * f, DdNode * g, int maxDepth, int direction ); +extern DdNode * cuddBddClippingAndAbstract( DdManager * dd, DdNode * f, DdNode * g, DdNode * cube, int maxDepth, int direction ); +extern void cuddGetBranches( DdNode * g, DdNode ** g1, DdNode ** g0 ); +extern int cuddCheckCube( DdManager * dd, DdNode * g ); +extern DdNode * cuddCofactorRecur( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddBddComposeRecur( DdManager * dd, DdNode * f, DdNode * g, DdNode * proj ); +extern DdNode * cuddAddComposeRecur( DdManager * dd, DdNode * f, DdNode * g, DdNode * proj ); +extern int cuddExact( DdManager * table, int lower, int upper ); +extern DdNode * cuddBddConstrainRecur( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * cuddBddRestrictRecur( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * cuddBddNPAndRecur( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * cuddAddConstrainRecur( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * cuddAddRestrictRecur( DdManager * dd, DdNode * f, DdNode * c ); +extern DdNode * cuddBddLICompaction( DdManager * dd, DdNode * f, DdNode * c ); +extern int cuddGa( DdManager * table, int lower, int upper ); +extern int cuddTreeSifting( DdManager * table, Cudd_ReorderingType method ); +extern int cuddZddInitUniv( DdManager * zdd ); +extern void cuddZddFreeUniv( DdManager * zdd ); +extern void cuddSetInteract( DdManager * table, int x, int y ); +extern int cuddTestInteract( DdManager * table, int x, int y ); +extern int cuddInitInteract( DdManager * table ); +extern DdLocalCache * cuddLocalCacheInit( DdManager * manager, unsigned int keySize, unsigned int cacheSize, unsigned int maxCacheSize ); +extern void cuddLocalCacheQuit( DdLocalCache * cache ); +extern void cuddLocalCacheInsert( DdLocalCache * cache, DdNodePtr * key, DdNode * value ); +extern DdNode * cuddLocalCacheLookup( DdLocalCache * cache, DdNodePtr * key ); +extern void cuddLocalCacheClearDead( DdManager * manager ); +extern int cuddIsInDeathRow( DdManager * dd, DdNode * f ); +extern int cuddTimesInDeathRow( DdManager * dd, DdNode * f ); +extern void cuddLocalCacheClearAll( DdManager * manager ); #ifdef DD_CACHE_PROFILE -EXTERN int cuddLocalCacheProfile ARGS((DdLocalCache *cache)); +extern int cuddLocalCacheProfile( DdLocalCache * cache ); #endif -EXTERN DdHashTable * cuddHashTableInit ARGS((DdManager *manager, unsigned int keySize, unsigned int initSize)); -EXTERN void cuddHashTableQuit ARGS((DdHashTable *hash)); -EXTERN int cuddHashTableInsert ARGS((DdHashTable *hash, DdNodePtr *key, DdNode *value, ptrint count)); -EXTERN DdNode * cuddHashTableLookup ARGS((DdHashTable *hash, DdNodePtr *key)); -EXTERN int cuddHashTableInsert1 ARGS((DdHashTable *hash, DdNode *f, DdNode *value, ptrint count)); -EXTERN DdNode * cuddHashTableLookup1 ARGS((DdHashTable *hash, DdNode *f)); -EXTERN int cuddHashTableInsert2 ARGS((DdHashTable *hash, DdNode *f, DdNode *g, DdNode *value, ptrint count)); -EXTERN DdNode * cuddHashTableLookup2 ARGS((DdHashTable *hash, DdNode *f, DdNode *g)); -EXTERN int cuddHashTableInsert3 ARGS((DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h, DdNode *value, ptrint count)); -EXTERN DdNode * cuddHashTableLookup3 ARGS((DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdLevelQueue * cuddLevelQueueInit ARGS((int levels, int itemSize, int numBuckets)); -EXTERN void cuddLevelQueueQuit ARGS((DdLevelQueue *queue)); -EXTERN void * cuddLevelQueueEnqueue ARGS((DdLevelQueue *queue, void *key, int level)); -EXTERN void cuddLevelQueueDequeue ARGS((DdLevelQueue *queue, int level)); -EXTERN int cuddLinearAndSifting ARGS((DdManager *table, int lower, int upper)); -EXTERN DdNode * cuddBddLiteralSetIntersectionRecur ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddCProjectionRecur ARGS((DdManager *dd, DdNode *R, DdNode *Y, DdNode *Ysupp)); -EXTERN DdNode * cuddBddClosestCube ARGS((DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE bound)); -EXTERN void cuddReclaim ARGS((DdManager *table, DdNode *n)); -EXTERN void cuddReclaimZdd ARGS((DdManager *table, DdNode *n)); -EXTERN void cuddClearDeathRow ARGS((DdManager *table)); -EXTERN void cuddShrinkDeathRow ARGS((DdManager *table)); -EXTERN DdNode * cuddDynamicAllocNode ARGS((DdManager *table)); -EXTERN int cuddSifting ARGS((DdManager *table, int lower, int upper)); -EXTERN int cuddSwapping ARGS((DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)); -EXTERN int cuddNextHigh ARGS((DdManager *table, int x)); -EXTERN int cuddNextLow ARGS((DdManager *table, int x)); -EXTERN int cuddSwapInPlace ARGS((DdManager *table, int x, int y)); -EXTERN int cuddBddAlignToZdd ARGS((DdManager *table)); -EXTERN DdNode * cuddBddMakePrime ARGS((DdManager *dd, DdNode *cube, DdNode *f)); -EXTERN DdNode * cuddSolveEqnRecur ARGS((DdManager *bdd, DdNode *F, DdNode *Y, DdNode **G, int n, int *yIndex, int i)); -EXTERN DdNode * cuddVerifySol ARGS((DdManager *bdd, DdNode *F, DdNode **G, int *yIndex, int n)); +extern DdHashTable * cuddHashTableInit( DdManager * manager, unsigned int keySize, unsigned int initSize ); +extern void cuddHashTableQuit( DdHashTable * hash ); +extern int cuddHashTableInsert( DdHashTable * hash, DdNodePtr * key, DdNode * value, ptrint count ); +extern DdNode * cuddHashTableLookup( DdHashTable * hash, DdNodePtr * key ); +extern int cuddHashTableInsert1( DdHashTable * hash, DdNode * f, DdNode * value, ptrint count ); +extern DdNode * cuddHashTableLookup1( DdHashTable * hash, DdNode * f ); +extern int cuddHashTableInsert2( DdHashTable * hash, DdNode * f, DdNode * g, DdNode * value, ptrint count ); +extern DdNode * cuddHashTableLookup2( DdHashTable * hash, DdNode * f, DdNode * g ); +extern int cuddHashTableInsert3( DdHashTable * hash, DdNode * f, DdNode * g, DdNode * h, DdNode * value, ptrint count ); +extern DdNode * cuddHashTableLookup3( DdHashTable * hash, DdNode * f, DdNode * g, DdNode * h ); +extern DdLevelQueue * cuddLevelQueueInit( int levels, int itemSize, int numBuckets ); +extern void cuddLevelQueueQuit( DdLevelQueue * queue ); +extern void * cuddLevelQueueEnqueue( DdLevelQueue * queue, void * key, int level ); +extern void cuddLevelQueueDequeue( DdLevelQueue * queue, int level ); +extern int cuddLinearAndSifting( DdManager * table, int lower, int upper ); +extern int cuddLinearInPlace( DdManager * table, int x, int y ); +extern void cuddUpdateInteractionMatrix( DdManager * table, int xindex, int yindex ); +extern int cuddInitLinear( DdManager * table ); +extern int cuddResizeLinear( DdManager * table ); +extern DdNode * cuddBddLiteralSetIntersectionRecur( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddCProjectionRecur( DdManager * dd, DdNode * R, DdNode * Y, DdNode * Ysupp ); +extern DdNode * cuddBddClosestCube( DdManager * dd, DdNode * f, DdNode * g, CUDD_VALUE_TYPE bound ); +extern void cuddReclaim( DdManager * table, DdNode * n ); +extern void cuddReclaimZdd( DdManager * table, DdNode * n ); +extern void cuddClearDeathRow( DdManager * table ); +extern void cuddShrinkDeathRow( DdManager * table ); +extern DdNode * cuddDynamicAllocNode( DdManager * table ); +extern int cuddSifting( DdManager * table, int lower, int upper ); +extern int cuddSwapping( DdManager * table, int lower, int upper, Cudd_ReorderingType heuristic ); +extern int cuddNextHigh( DdManager * table, int x ); +extern int cuddNextLow( DdManager * table, int x ); +extern int cuddSwapInPlace( DdManager * table, int x, int y ); +extern int cuddBddAlignToZdd( DdManager * table ); +extern DdNode * cuddBddMakePrime( DdManager * dd, DdNode * cube, DdNode * f ); +extern DdNode * cuddSolveEqnRecur( DdManager * bdd, DdNode * F, DdNode * Y, DdNode ** G, int n, int * yIndex, int i ); +extern DdNode * cuddVerifySol( DdManager * bdd, DdNode * F, DdNode ** G, int * yIndex, int n ); #ifdef ST_INCLUDED -EXTERN DdNode* cuddSplitSetRecur ARGS((DdManager *manager, st_table *mtable, int *varSeen, DdNode *p, double n, double max, int index)); +extern DdNode * cuddSplitSetRecur( DdManager * manager, st_table * mtable, int * varSeen, DdNode * p, double n, double max, int index ); #endif -EXTERN DdNode * cuddSubsetHeavyBranch ARGS((DdManager *dd, DdNode *f, int numVars, int threshold)); -EXTERN DdNode * cuddSubsetShortPaths ARGS((DdManager *dd, DdNode *f, int numVars, int threshold, int hardlimit)); -EXTERN int cuddSymmCheck ARGS((DdManager *table, int x, int y)); -EXTERN int cuddSymmSifting ARGS((DdManager *table, int lower, int upper, int TimeStop)); -EXTERN int cuddSymmSiftingConv ARGS((DdManager *table, int lower, int upper)); -EXTERN DdNode * cuddAllocNode ARGS((DdManager *unique)); -EXTERN DdManager * cuddInitTable ARGS((unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int looseUpTo)); -EXTERN void cuddFreeTable ARGS((DdManager *unique)); -EXTERN int cuddGarbageCollect ARGS((DdManager *unique, int clearCache)); -EXTERN int cuddGarbageCollectZdd ARGS((DdManager *unique, int clearCache)); -EXTERN DdNode * cuddZddGetNode ARGS((DdManager *zdd, int id, DdNode *T, DdNode *E)); -EXTERN DdNode * cuddZddGetNodeIVO ARGS((DdManager *dd, int index, DdNode *g, DdNode *h)); -EXTERN DdNode * cuddUniqueInter ARGS((DdManager *unique, int index, DdNode *T, DdNode *E)); -EXTERN DdNode * cuddUniqueInterIVO ARGS((DdManager *unique, int index, DdNode *T, DdNode *E)); -EXTERN DdNode * cuddUniqueInterZdd ARGS((DdManager *unique, int index, DdNode *T, DdNode *E)); -EXTERN DdNode * cuddUniqueConst ARGS((DdManager *unique, CUDD_VALUE_TYPE value)); -EXTERN void cuddRehash ARGS((DdManager *unique, int i)); -EXTERN void cuddShrinkSubtable ARGS((DdManager *unique, int i)); -EXTERN int cuddInsertSubtables ARGS((DdManager *unique, int n, int level)); -EXTERN int cuddDestroySubtables ARGS((DdManager *unique, int n)); -EXTERN int cuddResizeTableZdd ARGS((DdManager *unique, int index)); -EXTERN void cuddSlowTableGrowth ARGS((DdManager *unique)); -EXTERN int cuddP ARGS((DdManager *dd, DdNode *f)); +extern DdNode * cuddSubsetHeavyBranch( DdManager * dd, DdNode * f, int numVars, int threshold ); +extern DdNode * cuddSubsetShortPaths( DdManager * dd, DdNode * f, int numVars, int threshold, int hardlimit ); +extern int cuddSymmCheck( DdManager * table, int x, int y ); +extern int cuddSymmSifting( DdManager * table, int lower, int upper ); +extern int cuddSymmSiftingConv( DdManager * table, int lower, int upper ); +extern DdNode * cuddAllocNode( DdManager * unique ); +extern DdManager * cuddInitTable( unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int looseUpTo ); +extern void cuddFreeTable( DdManager * unique ); +extern int cuddGarbageCollect( DdManager * unique, int clearCache ); +extern DdNode * cuddZddGetNode( DdManager * zdd, int id, DdNode * T, DdNode * E ); +extern DdNode * cuddZddGetNodeIVO( DdManager * dd, int index, DdNode * g, DdNode * h ); +extern DdNode * cuddUniqueInter( DdManager * unique, int index, DdNode * T, DdNode * E ); +extern DdNode * cuddUniqueInterIVO( DdManager * unique, int index, DdNode * T, DdNode * E ); +extern DdNode * cuddUniqueInterZdd( DdManager * unique, int index, DdNode * T, DdNode * E ); +extern DdNode * cuddUniqueConst( DdManager * unique, CUDD_VALUE_TYPE value ); +extern void cuddRehash( DdManager * unique, int i ); +extern void cuddShrinkSubtable( DdManager * unique, int i ); +extern int cuddInsertSubtables( DdManager * unique, int n, int level ); +extern int cuddDestroySubtables( DdManager * unique, int n ); +extern int cuddResizeTableZdd( DdManager * unique, int index ); +extern void cuddSlowTableGrowth( DdManager * unique ); +extern int cuddP( DdManager * dd, DdNode * f ); #ifdef ST_INCLUDED -EXTERN enum st_retval cuddStCountfree ARGS((char *key, char *value, char *arg)); -EXTERN int cuddCollectNodes ARGS((DdNode *f, st_table *visited)); +extern enum st_retval cuddStCountfree( char * key, char * value, char * arg ); +extern int cuddCollectNodes( DdNode * f, st_table * visited ); #endif -EXTERN int cuddWindowReorder ARGS((DdManager *table, int low, int high, Cudd_ReorderingType submethod)); -EXTERN DdNode * cuddZddProduct ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddZddUnateProduct ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddZddWeakDiv ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddZddWeakDivF ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddZddDivide ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN DdNode * cuddZddDivideF ARGS((DdManager *dd, DdNode *f, DdNode *g)); -EXTERN int cuddZddGetCofactors3 ARGS((DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)); -EXTERN int cuddZddGetCofactors2 ARGS((DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0)); -EXTERN DdNode * cuddZddComplement ARGS((DdManager *dd, DdNode *node)); -EXTERN int cuddZddGetPosVarIndex(DdManager * dd, int index); -EXTERN int cuddZddGetNegVarIndex(DdManager * dd, int index); -EXTERN int cuddZddGetPosVarLevel(DdManager * dd, int index); -EXTERN int cuddZddGetNegVarLevel(DdManager * dd, int index); -EXTERN int cuddZddTreeSifting ARGS((DdManager *table, Cudd_ReorderingType method)); -EXTERN DdNode * cuddZddIsop ARGS((DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)); -EXTERN DdNode * cuddBddIsop ARGS((DdManager *dd, DdNode *L, DdNode *U)); -EXTERN DdNode * cuddMakeBddFromZddCover ARGS((DdManager *dd, DdNode *node)); -EXTERN int cuddZddLinearSifting ARGS((DdManager *table, int lower, int upper)); -EXTERN int cuddZddAlignToBdd ARGS((DdManager *table)); -EXTERN int cuddZddNextHigh ARGS((DdManager *table, int x)); -EXTERN int cuddZddNextLow ARGS((DdManager *table, int x)); -EXTERN int cuddZddUniqueCompare ARGS((int *ptr_x, int *ptr_y)); -EXTERN int cuddZddSwapInPlace ARGS((DdManager *table, int x, int y)); -EXTERN int cuddZddSwapping ARGS((DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)); -EXTERN int cuddZddSifting ARGS((DdManager *table, int lower, int upper)); -EXTERN DdNode * cuddZddIte ARGS((DdManager *dd, DdNode *f, DdNode *g, DdNode *h)); -EXTERN DdNode * cuddZddUnion ARGS((DdManager *zdd, DdNode *P, DdNode *Q)); -EXTERN DdNode * cuddZddIntersect ARGS((DdManager *zdd, DdNode *P, DdNode *Q)); -EXTERN DdNode * cuddZddDiff ARGS((DdManager *zdd, DdNode *P, DdNode *Q)); -EXTERN DdNode * cuddZddChangeAux ARGS((DdManager *zdd, DdNode *P, DdNode *zvar)); -EXTERN DdNode * cuddZddSubset1 ARGS((DdManager *dd, DdNode *P, int var)); -EXTERN DdNode * cuddZddSubset0 ARGS((DdManager *dd, DdNode *P, int var)); -EXTERN DdNode * cuddZddChange ARGS((DdManager *dd, DdNode *P, int var)); -EXTERN int cuddZddSymmCheck ARGS((DdManager *table, int x, int y)); -EXTERN int cuddZddSymmSifting ARGS((DdManager *table, int lower, int upper)); -EXTERN int cuddZddSymmSiftingConv ARGS((DdManager *table, int lower, int upper)); -EXTERN int cuddZddP ARGS((DdManager *zdd, DdNode *f)); - -EXTERN void (*MMoutOfMemory)(long); +extern DdNodePtr * cuddNodeArray( DdNode * f, int * n ); +extern int cuddWindowReorder( DdManager * table, int low, int high, Cudd_ReorderingType submethod ); +extern DdNode * cuddZddProduct( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddZddUnateProduct( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddZddWeakDiv( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddZddWeakDivF( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddZddDivide( DdManager * dd, DdNode * f, DdNode * g ); +extern DdNode * cuddZddDivideF( DdManager * dd, DdNode * f, DdNode * g ); +extern int cuddZddGetCofactors3( DdManager * dd, DdNode * f, int v, DdNode ** f1, DdNode ** f0, DdNode ** fd ); +extern int cuddZddGetCofactors2( DdManager * dd, DdNode * f, int v, DdNode ** f1, DdNode ** f0 ); +extern DdNode * cuddZddComplement( DdManager * dd, DdNode * node ); +extern int cuddZddGetPosVarIndex(DdManager * dd, int index ); +extern int cuddZddGetNegVarIndex(DdManager * dd, int index ); +extern int cuddZddGetPosVarLevel(DdManager * dd, int index ); +extern int cuddZddGetNegVarLevel(DdManager * dd, int index ); +extern int cuddZddTreeSifting( DdManager * table, Cudd_ReorderingType method ); +extern DdNode * cuddZddIsop( DdManager * dd, DdNode * L, DdNode * U, DdNode ** zdd_I ); +extern DdNode * cuddBddIsop( DdManager * dd, DdNode * L, DdNode * U ); +extern DdNode * cuddMakeBddFromZddCover( DdManager * dd, DdNode * node ); +extern int cuddZddLinearSifting( DdManager * table, int lower, int upper ); +extern int cuddZddAlignToBdd( DdManager * table ); +extern int cuddZddNextHigh( DdManager * table, int x ); +extern int cuddZddNextLow( DdManager * table, int x ); +extern int cuddZddUniqueCompare( int * ptr_x, int * ptr_y ); +extern int cuddZddSwapInPlace( DdManager * table, int x, int y ); +extern int cuddZddSwapping( DdManager * table, int lower, int upper, Cudd_ReorderingType heuristic ); +extern int cuddZddSifting( DdManager * table, int lower, int upper ); +extern DdNode * cuddZddIte( DdManager * dd, DdNode * f, DdNode * g, DdNode * h ); +extern DdNode * cuddZddUnion( DdManager * zdd, DdNode * P, DdNode * Q ); +extern DdNode * cuddZddIntersect( DdManager * zdd, DdNode * P, DdNode * Q ); +extern DdNode * cuddZddDiff( DdManager * zdd, DdNode * P, DdNode * Q ); +extern DdNode * cuddZddChangeAux( DdManager * zdd, DdNode * P, DdNode * zvar ); +extern DdNode * cuddZddSubset1( DdManager * dd, DdNode * P, int var ); +extern DdNode * cuddZddSubset0( DdManager * dd, DdNode * P, int var ); +extern DdNode * cuddZddChange( DdManager * dd, DdNode * P, int var ); +extern int cuddZddSymmCheck( DdManager * table, int x, int y ); +extern int cuddZddSymmSifting( DdManager * table, int lower, int upper ); +extern int cuddZddSymmSiftingConv( DdManager * table, int lower, int upper ); +extern int cuddZddP( DdManager * zdd, DdNode * f ); /**AutomaticEnd***************************************************************/ diff --git a/src/bdd/cudd/cuddInteract.c b/src/bdd/cudd/cuddInteract.c index 3891e9d0..1d335c2a 100644 --- a/src/bdd/cudd/cuddInteract.c +++ b/src/bdd/cudd/cuddInteract.c @@ -7,18 +7,18 @@ Synopsis [Functions to manipulate the variable interaction matrix.] Description [Internal procedures included in this file: - <ul> - <li> cuddSetInteract() - <li> cuddTestInteract() - <li> cuddInitInteract() - </ul> + <ul> + <li> cuddSetInteract() + <li> cuddTestInteract() + <li> cuddInitInteract() + </ul> Static procedures included in this file: - <ul> - <li> ddSuppInteract() - <li> ddClearLocal() - <li> ddUpdateInteract() - <li> ddClearGlobal() - </ul> + <ul> + <li> ddSuppInteract() + <li> ddClearLocal() + <li> ddUpdateInteract() + <li> ddClearGlobal() + </ul> The interaction matrix tells whether two variables are both in the support of some function of the DD. The main use of the interaction matrix is in the in-place swapping. Indeed, if two @@ -40,10 +40,37 @@ Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -53,6 +80,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -80,7 +108,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddInteract.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddInteract.c,v 1.12 2004/08/13 18:04:49 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -94,10 +122,10 @@ static char rcsid[] DD_UNUSED = "$Id: cuddInteract.c,v 1.1.1.1 2003/02/24 22:23: /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void ddSuppInteract ARGS((DdNode *f, int *support)); -static void ddClearLocal ARGS((DdNode *f)); -static void ddUpdateInteract ARGS((DdManager *table, int *support)); -static void ddClearGlobal ARGS((DdManager *table)); +static void ddSuppInteract (DdNode *f, int *support); +static void ddClearLocal (DdNode *f); +static void ddUpdateInteract (DdManager *table, int *support); +static void ddClearGlobal (DdManager *table); /**AutomaticEnd***************************************************************/ @@ -168,9 +196,9 @@ cuddTestInteract( int posn, word, bit, result; if (x > y) { - int tmp = x; - x = y; - y = tmp; + int tmp = x; + x = y; + y = tmp; } #ifdef DD_DEBUG assert(x < y); @@ -222,43 +250,43 @@ cuddInitInteract( words = ((n * (n-1)) >> (1 + LOGBPL)) + 1; table->interact = interact = ABC_ALLOC(long,words); if (interact == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < words; i++) { - interact[i] = 0; + interact[i] = 0; } support = ABC_ALLOC(int,n); if (support == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(interact); - return(0); + table->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(interact); + return(0); } for (i = 0; i < n; i++) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; - for (j = 0; j < slots; j++) { - f = nodelist[j]; - while (f != sentinel) { - /* A node is a root of the DAG if it cannot be - ** reached by nodes above it. If a node was never - ** reached during the previous depth-first searches, - ** then it is a root, and we start a new depth-first - ** search from it. - */ - if (!Cudd_IsComplement(f->next)) { - for (k = 0; k < n; k++) { - support[k] = 0; + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + /* A node is a root of the DAG if it cannot be + ** reached by nodes above it. If a node was never + ** reached during the previous depth-first searches, + ** then it is a root, and we start a new depth-first + ** search from it. + */ + if (!Cudd_IsComplement(f->next)) { + for (k = 0; k < n; k++) { + support[k] = 0; + } + ddSuppInteract(f,support); + ddClearLocal(f); + ddUpdateInteract(table,support); + } + f = Cudd_Regular(f->next); } - ddSuppInteract(f,support); - ddClearLocal(f); - ddUpdateInteract(table,support); } - f = Cudd_Regular(f->next); - } - } } ddClearGlobal(table); @@ -291,7 +319,7 @@ ddSuppInteract( int * support) { if (cuddIsConstant(f) || Cudd_IsComplement(cuddT(f))) { - return; + return; } support[f->index] = 1; @@ -321,7 +349,7 @@ ddClearLocal( DdNode * f) { if (cuddIsConstant(f) || !Cudd_IsComplement(cuddT(f))) { - return; + return; } /* clear visited flag */ cuddT(f) = Cudd_Regular(cuddT(f)); @@ -354,14 +382,14 @@ ddUpdateInteract( int n = table->size; for (i = 0; i < n-1; i++) { - if (support[i] == 1) { - for (j = i+1; j < n; j++) { - if (support[j] == 1) { - cuddSetInteract(table,i,j); - } + if (support[i] == 1) { + for (j = i+1; j < n; j++) { + if (support[j] == 1) { + cuddSetInteract(table,i,j); + } + } } } - } } /* end of ddUpdateInteract */ @@ -390,18 +418,20 @@ ddClearGlobal( int slots; for (i = 0; i < table->size; i++) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; - for (j = 0; j < slots; j++) { - f = nodelist[j]; - while (f != sentinel) { - f->next = Cudd_Regular(f->next); - f = f->next; + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (f != sentinel) { + f->next = Cudd_Regular(f->next); + f = f->next; + } } } - } } /* end of ddClearGlobal */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddLCache.c b/src/bdd/cudd/cuddLCache.c index bf6af8bd..45d71a8d 100644 --- a/src/bdd/cudd/cuddLCache.c +++ b/src/bdd/cudd/cuddLCache.c @@ -7,55 +7,83 @@ Synopsis [Functions for local caches.] Description [Internal procedures included in this module: - <ul> - <li> cuddLocalCacheInit() - <li> cuddLocalCacheQuit() - <li> cuddLocalCacheInsert() - <li> cuddLocalCacheLookup() - <li> cuddLocalCacheClearDead() - <li> cuddLocalCacheClearAll() - <li> cuddLocalCacheProfile() - <li> cuddHashTableInit() - <li> cuddHashTableQuit() - <li> cuddHashTableInsert() - <li> cuddHashTableLookup() - <li> cuddHashTableInsert2() - <li> cuddHashTableLookup2() - <li> cuddHashTableInsert3() - <li> cuddHashTableLookup3() - </ul> - Static procedures included in this module: - <ul> - <li> cuddLocalCacheResize() - <li> ddLCHash() - <li> cuddLocalCacheAddToList() - <li> cuddLocalCacheRemoveFromList() - <li> cuddHashTableResize() - <li> cuddHashTableAlloc() - </ul> ] + <ul> + <li> cuddLocalCacheInit() + <li> cuddLocalCacheQuit() + <li> cuddLocalCacheInsert() + <li> cuddLocalCacheLookup() + <li> cuddLocalCacheClearDead() + <li> cuddLocalCacheClearAll() + <li> cuddLocalCacheProfile() + <li> cuddHashTableInit() + <li> cuddHashTableQuit() + <li> cuddHashTableInsert() + <li> cuddHashTableLookup() + <li> cuddHashTableInsert2() + <li> cuddHashTableLookup2() + <li> cuddHashTableInsert3() + <li> cuddHashTableLookup3() + </ul> + Static procedures included in this module: + <ul> + <li> cuddLocalCacheResize() + <li> ddLCHash() + <li> cuddLocalCacheAddToList() + <li> cuddLocalCacheRemoveFromList() + <li> cuddHashTableResize() + <li> cuddHashTableAlloc() + </ul> ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define DD_MAX_HASHTABLE_DENSITY 2 /* tells when to resize a table */ +#define DD_MAX_HASHTABLE_DENSITY 2 /* tells when to resize a table */ /*---------------------------------------------------------------------------*/ /* Stucture declarations */ @@ -72,7 +100,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.24 2009/03/08 02:49:02 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -92,8 +120,8 @@ static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.1.1.1 2003/02/24 22:23:52 ******************************************************************************/ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 #define ddLCHash2(f,g,shift) \ -((((unsigned)(unsigned long)(f) * DD_P1 + \ - (unsigned)(unsigned long)(g)) * DD_P2) >> (shift)) +((((unsigned)(ptruint)(f) * DD_P1 + \ + (unsigned)(ptruint)(g)) * DD_P2) >> (shift)) #else #define ddLCHash2(f,g,shift) \ ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift)) @@ -120,12 +148,12 @@ static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.1.1.1 2003/02/24 22:23:52 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void cuddLocalCacheResize ARGS((DdLocalCache *cache)); -DD_INLINE static unsigned int ddLCHash ARGS((DdNodePtr *key, unsigned int keysize, int shift)); -static void cuddLocalCacheAddToList ARGS((DdLocalCache *cache)); -static void cuddLocalCacheRemoveFromList ARGS((DdLocalCache *cache)); -static int cuddHashTableResize ARGS((DdHashTable *hash)); -DD_INLINE static DdHashItem * cuddHashTableAlloc ARGS((DdHashTable *hash)); +static void cuddLocalCacheResize (DdLocalCache *cache); +DD_INLINE static unsigned int ddLCHash (DdNodePtr *key, unsigned int keysize, int shift); +static void cuddLocalCacheAddToList (DdLocalCache *cache); +static void cuddLocalCacheRemoveFromList (DdLocalCache *cache); +static int cuddHashTableResize (DdHashTable *hash); +DD_INLINE static DdHashItem * cuddHashTableAlloc (DdHashTable *hash); /**AutomaticEnd***************************************************************/ @@ -163,8 +191,8 @@ cuddLocalCacheInit( cache = ABC_ALLOC(DdLocalCache,1); if (cache == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); } cache->manager = manager; cache->keysize = keySize; @@ -175,11 +203,11 @@ cuddLocalCacheInit( logSize = cuddComputeFloorLog2(ddMax(cacheSize,manager->slots/2)); cacheSize = 1 << logSize; cache->item = (DdLocalCacheItem *) - ABC_ALLOC(char, cacheSize * cache->itemsize); + ABC_ALLOC(char, cacheSize * cache->itemsize); if (cache->item == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(cache); - return(NULL); + manager->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(cache); + return(NULL); } cache->slots = cacheSize; cache->shift = sizeof(int) * 8 - logSize; @@ -219,7 +247,7 @@ cuddLocalCacheQuit( DdLocalCache * cache /* cache to be shut down */) { cache->manager->memused -= - cache->slots * cache->itemsize + sizeof(DdLocalCache); + cache->slots * cache->itemsize + sizeof(DdLocalCache); cuddLocalCacheRemoveFromList(cache); ABC_FREE(cache->item); ABC_FREE(cache); @@ -251,7 +279,7 @@ cuddLocalCacheInsert( posn = ddLCHash(key,cache->keysize,cache->shift); entry = (DdLocalCacheItem *) ((char *) cache->item + - posn * cache->itemsize); + posn * cache->itemsize); memcpy(entry->key,key,cache->keysize * sizeof(DdNode *)); entry->value = value; #ifdef DD_CACHE_PROFILE @@ -285,22 +313,22 @@ cuddLocalCacheLookup( cache->lookUps++; posn = ddLCHash(key,cache->keysize,cache->shift); entry = (DdLocalCacheItem *) ((char *) cache->item + - posn * cache->itemsize); + posn * cache->itemsize); if (entry->value != NULL && - memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) { - cache->hits++; - value = Cudd_Regular(entry->value); - if (value->ref == 0) { - cuddReclaim(cache->manager,value); - } - return(entry->value); + memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) { + cache->hits++; + value = Cudd_Regular(entry->value); + if (value->ref == 0) { + cuddReclaim(cache->manager,value); + } + return(entry->value); } /* Cache miss: decide whether to resize */ if (cache->slots < cache->maxslots && - cache->hits > cache->lookUps * cache->minHit) { - cuddLocalCacheResize(cache); + cache->hits > cache->lookUps * cache->minHit) { + cuddLocalCacheResize(cache); } return(NULL); @@ -333,25 +361,27 @@ cuddLocalCacheClearDead( unsigned int i, j; while (cache != NULL) { - keysize = cache->keysize; - itemsize = cache->itemsize; - slots = cache->slots; - item = cache->item; - for (i = 0; i < slots; i++) { - if (item->value != NULL && Cudd_Regular(item->value)->ref == 0) { - item->value = NULL; - } else { - key = item->key; - for (j = 0; j < keysize; j++) { - if (Cudd_Regular(key[j])->ref == 0) { - item->value = NULL; - break; + keysize = cache->keysize; + itemsize = cache->itemsize; + slots = cache->slots; + item = cache->item; + for (i = 0; i < slots; i++) { + if (item->value != NULL) { + if (Cudd_Regular(item->value)->ref == 0) { + item->value = NULL; + } else { + key = item->key; + for (j = 0; j < keysize; j++) { + if (Cudd_Regular(key[j])->ref == 0) { + item->value = NULL; + break; + } + } + } } + item = (DdLocalCacheItem *) ((char *) item + itemsize); } - } - item = (DdLocalCacheItem *) ((char *) item + itemsize); - } - cache = cache->next; + cache = cache->next; } return; @@ -377,8 +407,8 @@ cuddLocalCacheClearAll( DdLocalCache *cache = manager->localCaches; while (cache != NULL) { - memset(cache->item, 0, cache->slots * cache->itemsize); - cache = cache->next; + memset(cache->item, 0, cache->slots * cache->itemsize); + cache = cache->next; } return; @@ -427,34 +457,34 @@ cuddLocalCacheProfile( hystogram = ABC_ALLOC(long, nbins); if (hystogram == NULL) { - return(0); + return(0); } for (i = 0; i < nbins; i++) { - hystogram[i] = 0; + hystogram[i] = 0; } for (i = 0; i < slots; i++) { - entry = (DdLocalCacheItem *) ((char *) cache->item + - i * cache->itemsize); - thiscount = (long) entry->count; - if (thiscount > max) { - max = thiscount; - imax = i; - } - if (thiscount < min) { - min = thiscount; - imin = i; - } - if (thiscount == 0) { - nzeroes++; - } - count = (double) thiscount; - mean += count; - meansq += count * count; - totalcount += count; - expected += count * (double) i; - bin = (i * nbins) / slots; - hystogram[bin] += thiscount; + entry = (DdLocalCacheItem *) ((char *) cache->item + + i * cache->itemsize); + thiscount = (long) entry->count; + if (thiscount > max) { + max = thiscount; + imax = i; + } + if (thiscount < min) { + min = thiscount; + imin = i; + } + if (thiscount == 0) { + nzeroes++; + } + count = (double) thiscount; + mean += count; + meansq += count * count; + totalcount += count; + expected += count * (double) i; + bin = (i * nbins) / slots; + hystogram[bin] += thiscount; } mean /= (double) slots; meansq /= (double) slots; @@ -472,17 +502,17 @@ cuddLocalCacheProfile( if (retval == EOF) return(0); if (totalcount) { - expected /= totalcount; - retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); - if (retval == EOF) return(0); - retval = fprintf(fp," (expected bin value = %g)\n# ", expected); - if (retval == EOF) return(0); - for (i = nbins - 1; i>=0; i--) { - retval = fprintf(fp,"%ld ", hystogram[i]); + expected /= totalcount; + retval = fprintf(fp,"Cache access hystogram for %d bins", nbins); + if (retval == EOF) return(0); + retval = fprintf(fp," (expected bin value = %g)\n# ", expected); + if (retval == EOF) return(0); + for (i = nbins - 1; i>=0; i--) { + retval = fprintf(fp,"%ld ", hystogram[i]); + if (retval == EOF) return(0); + } + retval = fprintf(fp,"\n"); if (retval == EOF) return(0); - } - retval = fprintf(fp,"\n"); - if (retval == EOF) return(0); } ABC_FREE(hystogram); @@ -519,15 +549,15 @@ cuddHashTableInit( #endif hash = ABC_ALLOC(DdHashTable, 1); if (hash == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); } hash->keysize = keySize; hash->manager = manager; hash->memoryList = NULL; hash->nextFree = NULL; hash->itemsize = (keySize + 1) * sizeof(DdNode *) + - sizeof(ptrint) + sizeof(DdHashItem *); + sizeof(ptrint) + sizeof(DdHashItem *); /* We have to guarantee that the shift be < 32. */ if (initSize < 2) initSize = 2; logSize = cuddComputeFloorLog2(initSize); @@ -535,9 +565,9 @@ cuddHashTableInit( hash->shift = sizeof(int) * 8 - logSize; hash->bucket = ABC_ALLOC(DdHashItem *, hash->numBuckets); if (hash->bucket == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(hash); - return(NULL); + manager->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(hash); + return(NULL); } memset(hash->bucket, 0, hash->numBuckets * sizeof(DdHashItem *)); hash->size = 0; @@ -576,18 +606,18 @@ cuddHashTableQuit( unsigned int numBuckets = hash->numBuckets; for (i = 0; i < numBuckets; i++) { - bucket = hash->bucket[i]; - while (bucket != NULL) { - Cudd_RecursiveDeref(dd, bucket->value); - bucket = bucket->next; - } + bucket = hash->bucket[i]; + while (bucket != NULL) { + Cudd_RecursiveDeref(dd, bucket->value); + bucket = bucket->next; + } } memlist = hash->memoryList; while (memlist != NULL) { - nextmem = (DdHashItem **) memlist[0]; - ABC_FREE(memlist); - memlist = nextmem; + nextmem = (DdHashItem **) memlist[0]; + ABC_FREE(memlist); + memlist = nextmem; } ABC_FREE(hash->bucket); @@ -631,8 +661,8 @@ cuddHashTableInsert( #endif if (hash->size > hash->maxsize) { - result = cuddHashTableResize(hash); - if (result == 0) return(0); + result = cuddHashTableResize(hash); + if (result == 0) return(0); } item = cuddHashTableAlloc(hash); if (item == NULL) return(0); @@ -641,7 +671,7 @@ cuddHashTableInsert( cuddRef(value); item->count = count; for (i = 0; i < hash->keysize; i++) { - item->key[i] = key[i]; + item->key[i] = key[i]; } posn = ddLCHash(key,hash->keysize,hash->shift); item->next = hash->bucket[posn]; @@ -688,32 +718,32 @@ cuddHashTableLookup( keysize = hash->keysize; while (item != NULL) { - DdNodePtr *key2 = item->key; - int equal = 1; - for (i = 0; i < keysize; i++) { - if (key[i] != key2[i]) { - equal = 0; - break; - } - } - if (equal) { - DdNode *value = item->value; - cuddSatDec(item->count); - if (item->count == 0) { - cuddDeref(value); - if (prev == NULL) { - hash->bucket[posn] = item->next; - } else { - prev->next = item->next; + DdNodePtr *key2 = item->key; + int equal = 1; + for (i = 0; i < keysize; i++) { + if (key[i] != key2[i]) { + equal = 0; + break; + } } - item->next = hash->nextFree; - hash->nextFree = item; - hash->size--; + if (equal) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); } - return(value); - } - prev = item; - item = item->next; + prev = item; + item = item->next; } return(NULL); @@ -749,8 +779,8 @@ cuddHashTableInsert1( #endif if (hash->size > hash->maxsize) { - result = cuddHashTableResize(hash); - if (result == 0) return(0); + result = cuddHashTableResize(hash); + if (result == 0) return(0); } item = cuddHashTableAlloc(hash); if (item == NULL) return(0); @@ -776,7 +806,7 @@ cuddHashTableInsert1( Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the - value of the entry is dereferenced, and the entry is returned to the ABC_FREE + value of the entry is dereferenced, and the entry is returned to the free list.] SideEffects [None] @@ -802,25 +832,25 @@ cuddHashTableLookup1( prev = NULL; while (item != NULL) { - DdNodePtr *key = item->key; - if (f == key[0]) { - DdNode *value = item->value; - cuddSatDec(item->count); - if (item->count == 0) { - cuddDeref(value); - if (prev == NULL) { - hash->bucket[posn] = item->next; - } else { - prev->next = item->next; - } - item->next = hash->nextFree; - hash->nextFree = item; - hash->size--; + DdNodePtr *key = item->key; + if (f == key[0]) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); } - return(value); - } - prev = item; - item = item->next; + prev = item; + item = item->next; } return(NULL); @@ -857,8 +887,8 @@ cuddHashTableInsert2( #endif if (hash->size > hash->maxsize) { - result = cuddHashTableResize(hash); - if (result == 0) return(0); + result = cuddHashTableResize(hash); + if (result == 0) return(0); } item = cuddHashTableAlloc(hash); if (item == NULL) return(0); @@ -885,7 +915,7 @@ cuddHashTableInsert2( Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the - value of the entry is dereferenced, and the entry is returned to the ABC_FREE + value of the entry is dereferenced, and the entry is returned to the free list.] SideEffects [None] @@ -912,25 +942,25 @@ cuddHashTableLookup2( prev = NULL; while (item != NULL) { - DdNodePtr *key = item->key; - if ((f == key[0]) && (g == key[1])) { - DdNode *value = item->value; - cuddSatDec(item->count); - if (item->count == 0) { - cuddDeref(value); - if (prev == NULL) { - hash->bucket[posn] = item->next; - } else { - prev->next = item->next; - } - item->next = hash->nextFree; - hash->nextFree = item; - hash->size--; + DdNodePtr *key = item->key; + if ((f == key[0]) && (g == key[1])) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); } - return(value); - } - prev = item; - item = item->next; + prev = item; + item = item->next; } return(NULL); @@ -968,8 +998,8 @@ cuddHashTableInsert3( #endif if (hash->size > hash->maxsize) { - result = cuddHashTableResize(hash); - if (result == 0) return(0); + result = cuddHashTableResize(hash); + if (result == 0) return(0); } item = cuddHashTableAlloc(hash); if (item == NULL) return(0); @@ -997,7 +1027,7 @@ cuddHashTableInsert3( Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the - value of the entry is dereferenced, and the entry is returned to the ABC_FREE + value of the entry is dereferenced, and the entry is returned to the free list.] SideEffects [None] @@ -1025,25 +1055,25 @@ cuddHashTableLookup3( prev = NULL; while (item != NULL) { - DdNodePtr *key = item->key; - if ((f == key[0]) && (g == key[1]) && (h == key[2])) { - DdNode *value = item->value; - cuddSatDec(item->count); - if (item->count == 0) { - cuddDeref(value); - if (prev == NULL) { - hash->bucket[posn] = item->next; - } else { - prev->next = item->next; - } - item->next = hash->nextFree; - hash->nextFree = item; - hash->size--; + DdNodePtr *key = item->key; + if ((f == key[0]) && (g == key[1]) && (h == key[2])) { + DdNode *value = item->value; + cuddSatDec(item->count); + if (item->count == 0) { + cuddDeref(value); + if (prev == NULL) { + hash->bucket[posn] = item->next; + } else { + prev->next = item->next; + } + item->next = hash->nextFree; + hash->nextFree = item; + hash->size--; + } + return(value); } - return(value); - } - prev = item; - item = item->next; + prev = item; + item = item->next; } return(NULL); @@ -1074,8 +1104,8 @@ cuddLocalCacheResize( int i, shift; unsigned int posn; unsigned int slots, oldslots; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; olditem = cache->item; oldslots = cache->slots; @@ -1083,28 +1113,28 @@ cuddLocalCacheResize( #ifdef DD_VERBOSE (void) fprintf(cache->manager->err, - "Resizing local cache from %d to %d entries\n", - oldslots, slots); + "Resizing local cache from %d to %d entries\n", + oldslots, slots); (void) fprintf(cache->manager->err, - "\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n", - cache->hits, cache->lookUps, cache->hits / cache->lookUps); + "\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n", + cache->hits, cache->lookUps, cache->hits / cache->lookUps); #endif saveHandler = MMoutOfMemory; MMoutOfMemory = Cudd_OutOfMem; cache->item = item = - (DdLocalCacheItem *) ABC_ALLOC(char, slots * cache->itemsize); + (DdLocalCacheItem *) ABC_ALLOC(char, slots * cache->itemsize); MMoutOfMemory = saveHandler; /* If we fail to allocate the new table we just give up. */ if (item == NULL) { #ifdef DD_VERBOSE - (void) fprintf(cache->manager->err,"Resizing failed. Giving up.\n"); + (void) fprintf(cache->manager->err,"Resizing failed. Giving up.\n"); #endif - cache->slots = oldslots; - cache->item = olditem; - /* Do not try to resize again. */ - cache->maxslots = oldslots - 1; - return; + cache->slots = oldslots; + cache->item = olditem; + /* Do not try to resize again. */ + cache->maxslots = oldslots - 1; + return; } shift = --(cache->shift); cache->manager->memused += (slots - oldslots) * cache->itemsize; @@ -1114,14 +1144,14 @@ cuddLocalCacheResize( /* Copy from old cache to new one. */ for (i = 0; (unsigned) i < oldslots; i++) { - old = (DdLocalCacheItem *) ((char *) olditem + i * cache->itemsize); - if (old->value != NULL) { - posn = ddLCHash(old->key,cache->keysize,slots); - entry = (DdLocalCacheItem *) ((char *) item + - posn * cache->itemsize); - memcpy(entry->key,old->key,cache->keysize*sizeof(DdNode *)); - entry->value = old->value; - } + old = (DdLocalCacheItem *) ((char *) olditem + i * cache->itemsize); + if (old->value != NULL) { + posn = ddLCHash(old->key,cache->keysize,shift); + entry = (DdLocalCacheItem *) ((char *) item + + posn * cache->itemsize); + memcpy(entry->key,old->key,cache->keysize*sizeof(DdNode *)); + entry->value = old->value; + } } ABC_FREE(olditem); @@ -1154,11 +1184,11 @@ ddLCHash( unsigned int keysize, int shift) { - unsigned int val = (unsigned int) (ptrint) key[0]; + unsigned int val = (unsigned int) (ptrint) key[0] * DD_P2; unsigned int i; for (i = 1; i < keysize; i++) { - val = val * DD_P1 + (int) (ptrint) key[i]; + val = val * DD_P1 + (int) (ptrint) key[i]; } return(val >> shift); @@ -1219,14 +1249,14 @@ cuddLocalCacheRemoveFromList( nextCache = manager->localCaches; while (nextCache != NULL) { - if (nextCache == cache) { - *prevCache = nextCache->next; - return; - } - prevCache = &(nextCache->next); - nextCache = nextCache->next; + if (nextCache == cache) { + *prevCache = nextCache->next; + return; + } + prevCache = &(nextCache->next); + nextCache = nextCache->next; } - return; /* should never get here */ + return; /* should never get here */ } /* end of cuddLocalCacheRemoveFromList */ @@ -1264,8 +1294,8 @@ cuddHashTableResize( #endif int shift; int oldNumBuckets = hash->numBuckets; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; /* Compute the new size of the table. */ numBuckets = oldNumBuckets << 1; @@ -1278,8 +1308,8 @@ cuddHashTableResize( buckets = ABC_ALLOC(DdHashItem *, numBuckets); MMoutOfMemory = saveHandler; if (buckets == NULL) { - hash->maxsize <<= 1; - return(1); + hash->maxsize <<= 1; + return(1); } hash->bucket = buckets; @@ -1291,53 +1321,53 @@ cuddHashTableResize( #pragma pointer_size restore #endif if (hash->keysize == 1) { - for (j = 0; j < oldNumBuckets; j++) { - item = oldBuckets[j]; - while (item != NULL) { - next = item->next; - key = item->key; - posn = ddLCHash2(key[0], key[0], shift); - item->next = buckets[posn]; - buckets[posn] = item; - item = next; + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash2(key[0], key[0], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } } - } } else if (hash->keysize == 2) { - for (j = 0; j < oldNumBuckets; j++) { - item = oldBuckets[j]; - while (item != NULL) { - next = item->next; - key = item->key; - posn = ddLCHash2(key[0], key[1], shift); - item->next = buckets[posn]; - buckets[posn] = item; - item = next; + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash2(key[0], key[1], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } } - } } else if (hash->keysize == 3) { - for (j = 0; j < oldNumBuckets; j++) { - item = oldBuckets[j]; - while (item != NULL) { - next = item->next; - key = item->key; - posn = ddLCHash3(key[0], key[1], key[2], shift); - item->next = buckets[posn]; - buckets[posn] = item; - item = next; + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + key = item->key; + posn = ddLCHash3(key[0], key[1], key[2], shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } } - } } else { - for (j = 0; j < oldNumBuckets; j++) { - item = oldBuckets[j]; - while (item != NULL) { - next = item->next; - posn = ddLCHash(item->key, hash->keysize, shift); - item->next = buckets[posn]; - buckets[posn] = item; - item = next; + for (j = 0; j < oldNumBuckets; j++) { + item = oldBuckets[j]; + while (item != NULL) { + next = item->next; + posn = ddLCHash(item->key, hash->keysize, shift); + item->next = buckets[posn]; + buckets[posn] = item; + item = next; + } } } - } ABC_FREE(oldBuckets); return(1); @@ -1365,8 +1395,8 @@ cuddHashTableAlloc( { int i; unsigned int itemsize = hash->itemsize; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short @@ -1374,54 +1404,54 @@ cuddHashTableAlloc( DdHashItem **mem, *thisOne, *next, *item; if (hash->nextFree == NULL) { - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - mem = (DdHashItem **) ABC_ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); - MMoutOfMemory = saveHandler; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdHashItem **) ABC_ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); + MMoutOfMemory = saveHandler; #ifdef __osf__ #pragma pointer_size restore #endif - if (mem == NULL) { - if (hash->manager->stash != NULL) { - ABC_FREE(hash->manager->stash); - hash->manager->stash = NULL; - /* Inhibit resizing of tables. */ - hash->manager->maxCacheHard = hash->manager->cacheSlots - 1; - hash->manager->cacheSlack = -(int)(hash->manager->cacheSlots + 1); - for (i = 0; i < hash->manager->size; i++) { - hash->manager->subtables[i].maxKeys <<= 2; - } - hash->manager->gcFrac = 0.2; - hash->manager->minDead = - (unsigned) (0.2 * (double) hash->manager->slots); + if (mem == NULL) { + if (hash->manager->stash != NULL) { + ABC_FREE(hash->manager->stash); + hash->manager->stash = NULL; + /* Inhibit resizing of tables. */ + hash->manager->maxCacheHard = hash->manager->cacheSlots - 1; + hash->manager->cacheSlack = - (int) (hash->manager->cacheSlots + 1); + for (i = 0; i < hash->manager->size; i++) { + hash->manager->subtables[i].maxKeys <<= 2; + } + hash->manager->gcFrac = 0.2; + hash->manager->minDead = + (unsigned) (0.2 * (double) hash->manager->slots); #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short #endif - mem = (DdHashItem **) ABC_ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); + mem = (DdHashItem **) ABC_ALLOC(char,(DD_MEM_CHUNK+1) * itemsize); #ifdef __osf__ #pragma pointer_size restore #endif + } + if (mem == NULL) { + (*MMoutOfMemory)((long)((DD_MEM_CHUNK + 1) * itemsize)); + hash->manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } } - if (mem == NULL) { - (*MMoutOfMemory)((DD_MEM_CHUNK + 1) * itemsize); - hash->manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - } - mem[0] = (DdHashItem *) hash->memoryList; - hash->memoryList = mem; + mem[0] = (DdHashItem *) hash->memoryList; + hash->memoryList = mem; - thisOne = (DdHashItem *) ((char *) mem + itemsize); - hash->nextFree = thisOne; - for (i = 1; i < DD_MEM_CHUNK; i++) { - next = (DdHashItem *) ((char *) thisOne + itemsize); - thisOne->next = next; - thisOne = next; - } + thisOne = (DdHashItem *) ((char *) mem + itemsize); + hash->nextFree = thisOne; + for (i = 1; i < DD_MEM_CHUNK; i++) { + next = (DdHashItem *) ((char *) thisOne + itemsize); + thisOne->next = next; + thisOne = next; + } - thisOne->next = NULL; + thisOne->next = NULL; } item = hash->nextFree; @@ -1429,5 +1459,7 @@ cuddHashTableAlloc( return(item); } /* end of cuddHashTableAlloc */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddLevelQ.c b/src/bdd/cudd/cuddLevelQ.c index 1a09820a..43e730d6 100644 --- a/src/bdd/cudd/cuddLevelQ.c +++ b/src/bdd/cudd/cuddLevelQ.c @@ -25,28 +25,55 @@ Internal procedures provided by this module: <ul> - <li> cuddLevelQueueInit() - <li> cuddLevelQueueQuit() - <li> cuddLevelQueueEnqueue() - <li> cuddLevelQueueDequeue() - </ul> + <li> cuddLevelQueueInit() + <li> cuddLevelQueueQuit() + <li> cuddLevelQueueEnqueue() + <li> cuddLevelQueueDequeue() + </ul> Static procedures included in this module: - <ul> - <li> hashLookup() - <li> hashInsert() - <li> hashDelete() - <li> hashResize() - </ul> - ] + <ul> + <li> hashLookup() + <li> hashInsert() + <li> hashDelete() + <li> hashResize() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no - warranty about the suitability of this software for any - purpose. It is presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -56,6 +83,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -74,7 +102,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.13 2009/03/08 02:49:02 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -95,7 +123,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52 ******************************************************************************/ #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 #define lqHash(key,shift) \ -(((unsigned)(unsigned long)(key) * DD_P1) >> (shift)) +(((unsigned)(ptruint)(key) * DD_P1) >> (shift)) #else #define lqHash(key,shift) \ (((unsigned)(key) * DD_P1) >> (shift)) @@ -108,10 +136,10 @@ static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdQueueItem * hashLookup ARGS((DdLevelQueue *queue, void *key)); -static int hashInsert ARGS((DdLevelQueue *queue, DdQueueItem *item)); -static void hashDelete ARGS((DdLevelQueue *queue, DdQueueItem *item)); -static int hashResize ARGS((DdLevelQueue *queue)); +static DdQueueItem * hashLookup (DdLevelQueue *queue, void *key); +static int hashInsert (DdLevelQueue *queue, DdQueueItem *item); +static void hashDelete (DdLevelQueue *queue, DdQueueItem *item); +static int hashResize (DdLevelQueue *queue); /**AutomaticEnd***************************************************************/ @@ -148,7 +176,7 @@ cuddLevelQueueInit( queue = ABC_ALLOC(DdLevelQueue,1); if (queue == NULL) - return(NULL); + return(NULL); #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short @@ -159,8 +187,8 @@ cuddLevelQueueInit( #pragma pointer_size restore #endif if (queue->last == NULL) { - ABC_FREE(queue); - return(NULL); + ABC_FREE(queue); + return(NULL); } /* Use a hash table to test for uniqueness. */ if (numBuckets < 2) numBuckets = 2; @@ -176,9 +204,9 @@ cuddLevelQueueInit( #pragma pointer_size restore #endif if (queue->buckets == NULL) { - ABC_FREE(queue->last); - ABC_FREE(queue); - return(NULL); + ABC_FREE(queue->last); + ABC_FREE(queue); + return(NULL); } #ifdef __osf__ #pragma pointer_size save @@ -219,14 +247,14 @@ cuddLevelQueueQuit( DdQueueItem *item; while (queue->freelist != NULL) { - item = queue->freelist; - queue->freelist = item->next; - ABC_FREE(item); + item = queue->freelist; + queue->freelist = item->next; + ABC_FREE(item); } while (queue->first != NULL) { - item = (DdQueueItem *) queue->first; - queue->first = item->next; - ABC_FREE(item); + item = (DdQueueItem *) queue->first; + queue->first = item->next; + ABC_FREE(item); } ABC_FREE(queue->buckets); ABC_FREE(queue->last); @@ -268,12 +296,12 @@ cuddLevelQueueEnqueue( /* Get a free item from either the free list or the memory manager. */ if (queue->freelist == NULL) { - item = (DdQueueItem *) ABC_ALLOC(char, queue->itemsize); - if (item == NULL) - return(NULL); + item = (DdQueueItem *) ABC_ALLOC(char, queue->itemsize); + if (item == NULL) + return(NULL); } else { - item = queue->freelist; - queue->freelist = item->next; + item = queue->freelist; + queue->freelist = item->next; } /* Initialize. */ memset(item, 0, queue->itemsize); @@ -282,29 +310,29 @@ cuddLevelQueueEnqueue( queue->size++; if (queue->last[level]) { - /* There are already items for this level in the queue. */ - item->next = queue->last[level]->next; - queue->last[level]->next = item; - } else { - /* There are no items at the current level. Look for the first - ** non-empty level preceeding this one. */ - plevel = level; - while (plevel != 0 && queue->last[plevel] == NULL) - plevel--; - if (queue->last[plevel] == NULL) { - /* No element precedes this one in the queue. */ - item->next = (DdQueueItem *) queue->first; - queue->first = item; + /* There are already items for this level in the queue. */ + item->next = queue->last[level]->next; + queue->last[level]->next = item; } else { - item->next = queue->last[plevel]->next; - queue->last[plevel]->next = item; - } + /* There are no items at the current level. Look for the first + ** non-empty level preceeding this one. */ + plevel = level; + while (plevel != 0 && queue->last[plevel] == NULL) + plevel--; + if (queue->last[plevel] == NULL) { + /* No element precedes this one in the queue. */ + item->next = (DdQueueItem *) queue->first; + queue->first = item; + } else { + item->next = queue->last[plevel]->next; + queue->last[plevel]->next = item; + } } queue->last[level] = item; /* Insert entry for the key in the hash table. */ if (hashInsert(queue,item) == 0) { - return(NULL); + return(NULL); } return(item); @@ -335,7 +363,7 @@ cuddLevelQueueDequeue( /* Since we delete from the front, if this is the last item for ** its level, there are no other items for the same level. */ if (queue->last[level] == item) - queue->last[level] = NULL; + queue->last[level] = NULL; queue->first = item->next; /* Put item on the free list. */ @@ -378,10 +406,10 @@ hashLookup( item = queue->buckets[posn]; while (item != NULL) { - if (item->key == key) { - return(item); - } - item = item->cnext; + if (item->key == key) { + return(item); + } + item = item->cnext; } return(NULL); @@ -410,8 +438,8 @@ hashInsert( int posn; if (queue->size > queue->maxsize) { - result = hashResize(queue); - if (result == 0) return(0); + result = hashResize(queue); + if (result == 0) return(0); } posn = lqHash(item->key,queue->shift); @@ -448,16 +476,16 @@ hashDelete( if (prevItem == NULL) return; if (prevItem == item) { - queue->buckets[posn] = prevItem->cnext; - return; + queue->buckets[posn] = prevItem->cnext; + return; } while (prevItem->cnext != NULL) { - if (prevItem->cnext == item) { - prevItem->cnext = item->cnext; - return; - } - prevItem = prevItem->cnext; + if (prevItem->cnext == item) { + prevItem->cnext = item->cnext; + return; + } + prevItem = prevItem->cnext; } return; @@ -496,8 +524,8 @@ hashResize( #endif int shift; int oldNumBuckets = queue->numBuckets; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; /* Compute the new size of the subtable. */ numBuckets = oldNumBuckets << 1; @@ -508,9 +536,10 @@ hashResize( #pragma pointer_size short #endif buckets = queue->buckets = ABC_ALLOC(DdQueueItem *, numBuckets); + MMoutOfMemory = saveHandler; if (buckets == NULL) { - queue->maxsize <<= 1; - return(1); + queue->maxsize <<= 1; + return(1); } queue->numBuckets = numBuckets; @@ -521,18 +550,20 @@ hashResize( #pragma pointer_size restore #endif for (j = 0; j < oldNumBuckets; j++) { - item = oldBuckets[j]; - while (item != NULL) { - next = item->cnext; - posn = lqHash(item->key, shift); - item->cnext = buckets[posn]; - buckets[posn] = item; - item = next; - } + item = oldBuckets[j]; + while (item != NULL) { + next = item->cnext; + posn = lqHash(item->key, shift); + item->cnext = buckets[posn]; + buckets[posn] = item; + item = next; + } } ABC_FREE(oldBuckets); return(1); } /* end of hashResize */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddLinear.c b/src/bdd/cudd/cuddLinear.c index 9cb19e95..19de9820 100644 --- a/src/bdd/cudd/cuddLinear.c +++ b/src/bdd/cudd/cuddLinear.c @@ -7,30 +7,57 @@ Synopsis [Functions for DD reduction by linear transformations.] Description [ Internal procedures included in this module: - <ul> - <li> cuddLinearAndSifting() - </ul> - Static procedures included in this module: - <ul> - <li> ddLinearUniqueCompare() - <li> ddLinearAndSiftingAux() - <li> ddLinearAndSiftingUp() - <li> ddLinearAndSiftingDown() - <li> ddLinearAndSiftingBackward() - <li> ddUndoMoves() - <li> ddUpdateInteractionMatrix() - <li> cuddLinearInPlace() - <li> cuddInitLinear() - <li> cuddResizeLinear() - <li> cuddXorLinear() - </ul>] + <ul> + <li> cuddLinearAndSifting() + <li> cuddLinearInPlace() + <li> cuddUpdateInteractionMatrix() + <li> cuddInitLinear() + <li> cuddResizeLinear() + </ul> + Static procedures included in this module: + <ul> + <li> ddLinearUniqueCompare() + <li> ddLinearAndSiftingAux() + <li> ddLinearAndSiftingUp() + <li> ddLinearAndSiftingDown() + <li> ddLinearAndSiftingBackward() + <li> ddUndoMoves() + <li> cuddXorLinear() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -40,6 +67,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -68,19 +96,19 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddLinear.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddLinear.c,v 1.28 2009/02/19 16:21:03 fabio Exp $"; #endif -static int *entry; +static int *entry; #ifdef DD_STATS -extern int ddTotalNumberSwapping; -extern int ddTotalNISwaps; -static int ddTotalNumberLinearTr; +extern int ddTotalNumberSwapping; +extern int ddTotalNISwaps; +static int ddTotalNumberLinearTr; #endif #ifdef DD_DEBUG -static int zero = 0; +static int zero = 0; #endif /*---------------------------------------------------------------------------*/ @@ -93,17 +121,13 @@ static int zero = 0; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int ddLinearUniqueCompare ARGS((int *ptrX, int *ptrY)); -static int ddLinearAndSiftingAux ARGS((DdManager *table, int x, int xLow, int xHigh)); -static Move * ddLinearAndSiftingUp ARGS((DdManager *table, int y, int xLow, Move *prevMoves)); -static Move * ddLinearAndSiftingDown ARGS((DdManager *table, int x, int xHigh, Move *prevMoves)); -static int ddLinearAndSiftingBackward ARGS((DdManager *table, int size, Move *moves)); -static Move* ddUndoMoves ARGS((DdManager *table, Move *moves)); -static int cuddLinearInPlace ARGS((DdManager *table, int x, int y)); -static void ddUpdateInteractionMatrix ARGS((DdManager *table, int xindex, int yindex)); -static int cuddInitLinear ARGS((DdManager *table)); -static int cuddResizeLinear ARGS((DdManager *table)); -static void cuddXorLinear ARGS((DdManager *table, int x, int y)); +static int ddLinearUniqueCompare (int *ptrX, int *ptrY); +static int ddLinearAndSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddLinearAndSiftingUp (DdManager *table, int y, int xLow, Move *prevMoves); +static Move * ddLinearAndSiftingDown (DdManager *table, int x, int xHigh, Move *prevMoves); +static int ddLinearAndSiftingBackward (DdManager *table, int size, Move *moves); +static Move* ddUndoMoves (DdManager *table, Move *moves); +static void cuddXorLinear (DdManager *table, int x, int y); /**AutomaticEnd***************************************************************/ @@ -114,7 +138,7 @@ static void cuddXorLinear ARGS((DdManager *table, int x, int y)); /**Function******************************************************************** - + Synopsis [Prints the linear transform matrix.] Description [Prints the linear transform matrix. Returns 1 in case of @@ -136,16 +160,16 @@ Cudd_PrintLinear( long word; for (i = 0; i < nvars; i++) { - for (j = 0; j < wordsPerRow; j++) { - word = table->linear[i*wordsPerRow + j]; - for (k = 0; k < BPL; k++) { - retval = fprintf(table->out,"%ld",word & 1); - if (retval == 0) return(0); - word >>= 1; + for (j = 0; j < wordsPerRow; j++) { + word = table->linear[i*wordsPerRow + j]; + for (k = 0; k < BPL; k++) { + retval = fprintf(table->out,"%ld",word & 1); + if (retval == 0) return(0); + word >>= 1; + } } - } - retval = fprintf(table->out,"\n"); - if (retval == 0) return(0); + retval = fprintf(table->out,"\n"); + if (retval == 0) return(0); } return(1); @@ -153,7 +177,7 @@ Cudd_PrintLinear( /**Function******************************************************************** - + Synopsis [Reads an entry of the linear transform matrix.] Description [Reads an entry of the linear transform matrix.] @@ -218,13 +242,13 @@ cuddLinearAndSifting( int lower, int upper) { - int i; - int *var; - int size; - int x; - int result; + int i; + int *var; + int size; + int x; + int result; #ifdef DD_STATS - int previousSize; + int previousSize; #endif #ifdef DD_STATS @@ -236,65 +260,65 @@ cuddLinearAndSifting( var = NULL; entry = NULL; if (table->linear == NULL) { - result = cuddInitLinear(table); - if (result == 0) goto cuddLinearAndSiftingOutOfMem; + result = cuddInitLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; #if 0 - (void) fprintf(table->out,"\n"); - result = Cudd_PrintLinear(table); - if (result == 0) goto cuddLinearAndSiftingOutOfMem; + (void) fprintf(table->out,"\n"); + result = Cudd_PrintLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; #endif } else if (table->size != table->linearSize) { - result = cuddResizeLinear(table); - if (result == 0) goto cuddLinearAndSiftingOutOfMem; + result = cuddResizeLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; #if 0 - (void) fprintf(table->out,"\n"); - result = Cudd_PrintLinear(table); - if (result == 0) goto cuddLinearAndSiftingOutOfMem; + (void) fprintf(table->out,"\n"); + result = Cudd_PrintLinear(table); + if (result == 0) goto cuddLinearAndSiftingOutOfMem; #endif } /* Find order in which to sift variables. */ entry = ABC_ALLOC(int,size); if (entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddLinearAndSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddLinearAndSiftingOutOfMem; } var = ABC_ALLOC(int,size); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddLinearAndSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddLinearAndSiftingOutOfMem; } for (i = 0; i < size; i++) { - x = table->perm[i]; - entry[i] = table->subtables[x].keys; - var[i] = i; + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; } - qsort((void *)var,size,sizeof(int),(int (*)(const void *, const void *))ddLinearUniqueCompare); + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddLinearUniqueCompare); /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { - x = table->perm[var[i]]; - if (x < lower || x > upper) continue; + x = table->perm[var[i]]; + if (x < lower || x > upper) continue; #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - result = ddLinearAndSiftingAux(table,x,lower,upper); - if (!result) goto cuddLinearAndSiftingOutOfMem; + result = ddLinearAndSiftingAux(table,x,lower,upper); + if (!result) goto cuddLinearAndSiftingOutOfMem; #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"+"); /* should never happen */ - (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif #ifdef DD_DEBUG - (void) Cudd_DebugCheck(table); + (void) Cudd_DebugCheck(table); #endif } @@ -303,7 +327,7 @@ cuddLinearAndSifting( #ifdef DD_STATS (void) fprintf(table->out,"\n#:L_LINSIFT %8d: linear trans.", - ddTotalNumberLinearTr); + ddTotalNumberLinearTr); #endif return(1); @@ -313,11 +337,520 @@ cuddLinearAndSiftingOutOfMem: if (entry != NULL) ABC_FREE(entry); if (var != NULL) ABC_FREE(var); - return(0); + return(0); } /* end of cuddLinearAndSifting */ +/**Function******************************************************************** + + Synopsis [Linearly combines two adjacent variables.] + + Description [Linearly combines two adjacent variables. Specifically, + replaces the top variable with the exclusive nor of the two variables. + It assumes that no dead nodes are present on entry to this + procedure. The procedure then guarantees that no dead nodes will be + present when it terminates. cuddLinearInPlace assumes that x < + y. Returns the number of keys in the table if successful; 0 + otherwise.] + + SideEffects [The two subtables corrresponding to variables x and y are + modified. The global counters of the unique table are also affected.] + + SeeAlso [cuddSwapInPlace] + +******************************************************************************/ +int +cuddLinearInPlace( + DdManager * table, + int x, + int y) +{ + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; + int oldxkeys, oldykeys; + int newxkeys, newykeys; + int comple, newcomplement; + int i; + int posn; + int isolated; + DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0; + DdNode *g,*next,*last; + DdNodePtr *previousP; + DdNode *tmp; + DdNode *sentinel = &(table->sentinel); +#ifdef DD_DEBUG + int count, idcheck; +#endif + +#ifdef DD_DEBUG + assert(x < y); + assert(cuddNextHigh(table,x) == y); + assert(table->subtables[x].keys != 0); + assert(table->subtables[y].keys != 0); + assert(table->subtables[x].dead == 0); + assert(table->subtables[y].dead == 0); +#endif + + xindex = table->invperm[x]; + yindex = table->invperm[y]; + + if (cuddTestInteract(table,xindex,yindex)) { +#ifdef DD_STATS + ddTotalNumberLinearTr++; +#endif + /* Get parameters of x subtable. */ + xlist = table->subtables[x].nodelist; + oldxkeys = table->subtables[x].keys; + xslots = table->subtables[x].slots; + xshift = table->subtables[x].shift; + + /* Get parameters of y subtable. */ + ylist = table->subtables[y].nodelist; + oldykeys = table->subtables[y].keys; + yslots = table->subtables[y].slots; + yshift = table->subtables[y].shift; + + newxkeys = 0; + newykeys = oldykeys; + + /* Check whether the two projection functions involved in this + ** swap are isolated. At the end, we'll be able to tell how many + ** isolated projection functions are there by checking only these + ** two functions again. This is done to eliminate the isolated + ** projection functions from the node count. + */ + isolated = - ((table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1)); + + /* The nodes in the x layer are put in a chain. + ** The chain is handled as a FIFO; g points to the beginning and + ** last points to the end. + */ + g = NULL; +#ifdef DD_DEBUG + last = NULL; +#endif + for (i = 0; i < xslots; i++) { + f = xlist[i]; + if (f == sentinel) continue; + xlist[i] = sentinel; + if (g == NULL) { + g = f; + } else { + last->next = f; + } + while ((next = f->next) != sentinel) { + f = next; + } /* while there are elements in the collision chain */ + last = f; + } /* for each slot of the x subtable */ +#ifdef DD_DEBUG + /* last is always assigned in the for loop because there is at + ** least one key */ + assert(last != NULL); +#endif + last->next = NULL; + +#ifdef DD_COUNT + table->swapSteps += oldxkeys; +#endif + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f1))); +#endif + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = f10 = f1; + } +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(f11))); +#endif + f0 = cuddE(f); + comple = Cudd_IsComplement(f0); + f0 = Cudd_Regular(f0); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == f00) { + newf1 = f11; + cuddSatInc(newf1->ref); + } else { + /* Check ylist for triple (yindex,f11,f00). */ + posn = ddHash(f11, f00, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + previousP = &(ylist[posn]); + newf1 = *previousP; + while (f11 < cuddT(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + while (f11 == cuddT(newf1) && f00 < cuddE(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + if (cuddT(newf1) == f11 && cuddE(newf1) == f00) { + cuddSatInc(newf1->ref); + } else { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto cuddLinearOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f00; + /* Insert newf1 in the collision list ylist[posn]; + ** increase the ref counts of f11 and f00. + */ + newykeys++; + newf1->next = *previousP; + *previousP = newf1; + cuddSatInc(f11->ref); + tmp = Cudd_Regular(f00); + cuddSatInc(tmp->ref); + } + } + cuddT(f) = newf1; +#ifdef DD_DEBUG + assert(!(Cudd_IsComplement(newf1))); +#endif + + /* Do the same for f0, keeping complement dots into account. */ + /* decrease ref count of f0 */ + tmp = Cudd_Regular(f0); + cuddSatDec(tmp->ref); + /* create the new E child */ + if (f01 == f10) { + newf0 = f01; + tmp = Cudd_Regular(newf0); + cuddSatInc(tmp->ref); + } else { + /* make sure f01 is regular */ + newcomplement = Cudd_IsComplement(f01); + if (newcomplement) { + f01 = Cudd_Not(f01); + f10 = Cudd_Not(f10); + } + /* Check ylist for triple (yindex,f01,f10). */ + posn = ddHash(f01, f10, yshift); + /* For each element newf0 in collision list ylist[posn]. */ + previousP = &(ylist[posn]); + newf0 = *previousP; + while (f01 < cuddT(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + while (f01 == cuddT(newf0) && f10 < cuddE(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + if (cuddT(newf0) == f01 && cuddE(newf0) == f10) { + cuddSatInc(newf0->ref); + } else { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto cuddLinearOutOfMem; + newf0->index = yindex; newf0->ref = 1; + cuddT(newf0) = f01; + cuddE(newf0) = f10; + /* Insert newf0 in the collision list ylist[posn]; + ** increase the ref counts of f01 and f10. + */ + newykeys++; + newf0->next = *previousP; + *previousP = newf0; + cuddSatInc(f01->ref); + tmp = Cudd_Regular(f10); + cuddSatInc(tmp->ref); + } + if (newcomplement) { + newf0 = Cudd_Not(newf0); + } + } + cuddE(f) = newf0; + + /* Re-insert the modified f in xlist. + ** The modified f does not already exists in xlist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, xshift); + newxkeys++; + previousP = &(xlist[posn]); + tmp = *previousP; + while (newf1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + if (f->ref == 0) { + tmp = cuddT(f); + cuddSatDec(tmp->ref); + tmp = Cudd_Regular(cuddE(f)); + cuddSatDec(tmp->ref); + cuddDeallocNode(table,f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = sentinel; + } /* for every collision list */ + +#ifdef DD_DEBUG +#if 0 + (void) fprintf(table->out,"Linearly combining %d and %d\n",x,y); +#endif + count = 0; + idcheck = 0; + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) yindex) + idcheck++; + f = f->next; + } + } + if (count != newykeys) { + fprintf(table->err,"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count); + } + if (idcheck != 0) + fprintf(table->err,"Error in id's of ylist\twrong id's = %d\n",idcheck); + count = 0; + idcheck = 0; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) xindex) + idcheck++; + f = f->next; + } + } + if (count != newxkeys || newxkeys != oldxkeys) { + fprintf(table->err,"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count); + } + if (idcheck != 0) + fprintf(table->err,"Error in id's of xlist\twrong id's = %d\n",idcheck); +#endif + + isolated += (table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1); + table->isolated += isolated; + + /* Set the appropriate fields in table. */ + table->subtables[y].keys = newykeys; + + /* Here we should update the linear combination table + ** to record that x <- x EXNOR y. This is done by complementing + ** the (x,y) entry of the table. + */ + + table->keys += newykeys - oldykeys; + + cuddXorLinear(table,xindex,yindex); + } + +#ifdef DD_DEBUG + if (zero) { + (void) Cudd_DebugCheck(table); + } +#endif + + return(table->keys - table->isolated); + +cuddLinearOutOfMem: + (void) fprintf(table->err,"Error: cuddLinearInPlace out of memory\n"); + + return (0); + +} /* end of cuddLinearInPlace */ + + +/**Function******************************************************************** + + Synopsis [Updates the interaction matrix.] + + Description [] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +void +cuddUpdateInteractionMatrix( + DdManager * table, + int xindex, + int yindex) +{ + int i; + for (i = 0; i < yindex; i++) { + if (i != xindex && cuddTestInteract(table,i,yindex)) { + if (i < xindex) { + cuddSetInteract(table,i,xindex); + } else { + cuddSetInteract(table,xindex,i); + } + } + } + for (i = yindex+1; i < table->size; i++) { + if (i != xindex && cuddTestInteract(table,yindex,i)) { + if (i < xindex) { + cuddSetInteract(table,i,xindex); + } else { + cuddSetInteract(table,xindex,i); + } + } + } + +} /* end of cuddUpdateInteractionMatrix */ + + +/**Function******************************************************************** + + Synopsis [Initializes the linear transform matrix.] + + Description [Initializes the linear transform matrix. Returns 1 if + successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +cuddInitLinear( + DdManager * table) +{ + int words; + int wordsPerRow; + int nvars; + int word; + int bit; + int i; + long *linear; + + nvars = table->size; + wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + words = wordsPerRow * nvars; + table->linear = linear = ABC_ALLOC(long,words); + if (linear == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + table->memused += words * sizeof(long); + table->linearSize = nvars; + for (i = 0; i < words; i++) linear[i] = 0; + for (i = 0; i < nvars; i++) { + word = wordsPerRow * i + (i >> LOGBPL); + bit = i & (BPL-1); + linear[word] = 1 << bit; + } + return(1); + +} /* end of cuddInitLinear */ + + +/**Function******************************************************************** + + Synopsis [Resizes the linear transform matrix.] + + Description [Resizes the linear transform matrix. Returns 1 if + successful; 0 otherwise.] + + SideEffects [none] + + SeeAlso [] + +******************************************************************************/ +int +cuddResizeLinear( + DdManager * table) +{ + int words,oldWords; + int wordsPerRow,oldWordsPerRow; + int nvars,oldNvars; + int word,oldWord; + int bit; + int i,j; + long *linear,*oldLinear; + + oldNvars = table->linearSize; + oldWordsPerRow = ((oldNvars - 1) >> LOGBPL) + 1; + oldWords = oldWordsPerRow * oldNvars; + oldLinear = table->linear; + + nvars = table->size; + wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; + words = wordsPerRow * nvars; + table->linear = linear = ABC_ALLOC(long,words); + if (linear == NULL) { + table->errorCode = CUDD_MEMORY_OUT; + return(0); + } + table->memused += (words - oldWords) * sizeof(long); + for (i = 0; i < words; i++) linear[i] = 0; + + /* Copy old matrix. */ + for (i = 0; i < oldNvars; i++) { + for (j = 0; j < oldWordsPerRow; j++) { + oldWord = oldWordsPerRow * i + j; + word = wordsPerRow * i + j; + linear[word] = oldLinear[oldWord]; + } + } + ABC_FREE(oldLinear); + + /* Add elements to the diagonal. */ + for (i = oldNvars; i < nvars; i++) { + word = wordsPerRow * i + (i >> LOGBPL); + bit = i & (BPL-1); + linear[word] = 1 << bit; + } + table->linearSize = nvars; + + return(1); + +} /* end of cuddResizeLinear */ + + /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ @@ -342,7 +875,7 @@ ddLinearUniqueCompare( { #if 0 if (entry[*ptrY] == entry[*ptrX]) { - return((*ptrX) - (*ptrY)); + return((*ptrX) - (*ptrY)); } #endif return(entry[*ptrY] - entry[*ptrX]); @@ -371,11 +904,11 @@ ddLinearAndSiftingAux( int xHigh) { - Move *move; - Move *moveUp; /* list of up moves */ - Move *moveDown; /* list of down moves */ - int initialSize; - int result; + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; initialSize = table->keys - table->isolated; @@ -383,73 +916,73 @@ ddLinearAndSiftingAux( moveUp = NULL; if (x == xLow) { - moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); - /* At this point x --> xHigh unless bounding occurred. */ - if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddLinearAndSiftingBackward(table,initialSize,moveDown); - if (!result) goto ddLinearAndSiftingAuxOutOfMem; + moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; } else if (x == xHigh) { - moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); - /* At this point x --> xLow unless bounding occurred. */ - if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddLinearAndSiftingBackward(table,initialSize,moveUp); - if (!result) goto ddLinearAndSiftingAuxOutOfMem; + moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ - moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); - /* At this point x --> xHigh unless bounding occurred. */ - if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; - moveUp = ddUndoMoves(table,moveDown); + moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + moveUp = ddUndoMoves(table,moveDown); #ifdef DD_DEBUG - assert(moveUp == NULL || moveUp->x == x); + assert(moveUp == NULL || moveUp->x == x); #endif - moveUp = ddLinearAndSiftingUp(table,x,xLow,moveUp); - if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddLinearAndSiftingBackward(table,initialSize,moveUp); - if (!result) goto ddLinearAndSiftingAuxOutOfMem; + moveUp = ddLinearAndSiftingUp(table,x,xLow,moveUp); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; } else { /* must go up first: shorter */ - moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); - /* At this point x --> xLow unless bounding occurred. */ - if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; - moveDown = ddUndoMoves(table,moveUp); + moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + moveDown = ddUndoMoves(table,moveUp); #ifdef DD_DEBUG - assert(moveDown == NULL || moveDown->y == x); + assert(moveDown == NULL || moveDown->y == x); #endif - moveDown = ddLinearAndSiftingDown(table,x,xHigh,moveDown); - if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddLinearAndSiftingBackward(table,initialSize,moveDown); - if (!result) goto ddLinearAndSiftingAuxOutOfMem; + moveDown = ddLinearAndSiftingDown(table,x,xHigh,moveDown); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddLinearAndSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddLinearAndSiftingAuxOutOfMem; } while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(1); ddLinearAndSiftingAuxOutOfMem: while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(0); @@ -476,14 +1009,14 @@ ddLinearAndSiftingUp( int xLow, Move * prevMoves) { - Move *moves; - Move *move; - int x; - int size, newsize; - int limitSize; - int xindex, yindex; - int isolated; - int L; /* lower bound on DD size */ + Move *moves; + Move *move; + int x; + int size, newsize; + int limitSize; + int xindex, yindex; + int isolated; + int L; /* lower bound on DD size */ #ifdef DD_DEBUG int checkL; int z; @@ -501,84 +1034,84 @@ ddLinearAndSiftingUp( */ limitSize = L = table->keys - table->isolated; for (x = xLow + 1; x < y; x++) { - xindex = table->invperm[x]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[xindex]->ref == 1; - L -= table->subtables[x].keys - isolated; - } + xindex = table->invperm[x]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L -= table->subtables[x].keys - isolated; + } } isolated = table->vars[yindex]->ref == 1; L -= table->subtables[y].keys - isolated; x = cuddNextLow(table,y); while (x >= xLow && L <= limitSize) { - xindex = table->invperm[x]; + xindex = table->invperm[x]; #ifdef DD_DEBUG - checkL = table->keys - table->isolated; - for (z = xLow + 1; z < y; z++) { - zindex = table->invperm[z]; - if (cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - checkL -= table->subtables[z].keys - isolated; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z < y; z++) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } + } + isolated = table->vars[yindex]->ref == 1; + checkL -= table->subtables[y].keys - isolated; + if (L != checkL) { + (void) fprintf(table->out, "checkL(%d) != L(%d)\n",checkL,L); } - } - isolated = table->vars[yindex]->ref == 1; - checkL -= table->subtables[y].keys - isolated; - if (L != checkL) { - (void) fprintf(table->out, "checkL(%d) != L(%d)\n",checkL,L); - } #endif - size = cuddSwapInPlace(table,x,y); - if (size == 0) goto ddLinearAndSiftingUpOutOfMem; - newsize = cuddLinearInPlace(table,x,y); - if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddLinearAndSiftingUpOutOfMem; - move->x = x; - move->y = y; - move->next = moves; - moves = move; - move->flags = CUDD_SWAP_MOVE; - if (newsize >= size) { - /* Undo transformation. The transformation we apply is - ** its own inverse. Hence, we just apply the transformation - ** again. - */ + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddLinearAndSiftingUpOutOfMem; newsize = cuddLinearInPlace(table,x,y); if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddLinearAndSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize >= size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem; #ifdef DD_DEBUG - if (newsize != size) { - (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); - } + if (newsize != size) { + (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } #endif - } else if (cuddTestInteract(table,xindex,yindex)) { - size = newsize; - move->flags = CUDD_LINEAR_TRANSFORM_MOVE; - ddUpdateInteractionMatrix(table,xindex,yindex); - } - move->size = size; - /* Update the lower bound. */ - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[xindex]->ref == 1; - L += table->subtables[y].keys - isolated; - } - if ((double) size > (double) limitSize * table->maxGrowth) break; - if (size < limitSize) limitSize = size; - y = x; - x = cuddNextLow(table,y); + } else if (cuddTestInteract(table,xindex,yindex)) { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + cuddUpdateInteractionMatrix(table,xindex,yindex); + } + move->size = size; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + y = x; + x = cuddNextLow(table,y); } return(moves); ddLinearAndSiftingUpOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return((Move *) CUDD_OUT_OF_MEM); } /* end of ddLinearAndSiftingUp */ - + /**Function******************************************************************** @@ -599,18 +1132,18 @@ ddLinearAndSiftingDown( int xHigh, Move * prevMoves) { - Move *moves; - Move *move; - int y; - int size, newsize; - int R; /* upper bound on node decrease */ - int limitSize; - int xindex, yindex; - int isolated; + Move *moves; + Move *move; + int y; + int size, newsize; + int R; /* upper bound on node decrease */ + int limitSize; + int xindex, yindex; + int isolated; #ifdef DD_DEBUG - int checkR; - int z; - int zindex; + int checkR; + int z; + int zindex; #endif moves = prevMoves; @@ -619,73 +1152,73 @@ ddLinearAndSiftingDown( limitSize = size = table->keys - table->isolated; R = 0; for (y = xHigh; y > x; y--) { - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[yindex]->ref == 1; - R += table->subtables[y].keys - isolated; - } + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R += table->subtables[y].keys - isolated; + } } y = cuddNextHigh(table,x); while (y <= xHigh && size - R < limitSize) { #ifdef DD_DEBUG - checkR = 0; - for (z = xHigh; z > x; z--) { - zindex = table->invperm[z]; - if (cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - checkR += table->subtables[z].keys - isolated; + checkR = 0; + for (z = xHigh; z > x; z--) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } + } + if (R != checkR) { + (void) fprintf(table->out, "checkR(%d) != R(%d)\n",checkR,R); } - } - if (R != checkR) { - (void) fprintf(table->out, "checkR(%d) != R(%d)\n",checkR,R); - } #endif - /* Update upper bound on node decrease. */ - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[yindex]->ref == 1; - R -= table->subtables[y].keys - isolated; - } - size = cuddSwapInPlace(table,x,y); - if (size == 0) goto ddLinearAndSiftingDownOutOfMem; - newsize = cuddLinearInPlace(table,x,y); - if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddLinearAndSiftingDownOutOfMem; - move->x = x; - move->y = y; - move->next = moves; - moves = move; - move->flags = CUDD_SWAP_MOVE; - if (newsize >= size) { - /* Undo transformation. The transformation we apply is - ** its own inverse. Hence, we just apply the transformation - ** again. - */ + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddLinearAndSiftingDownOutOfMem; newsize = cuddLinearInPlace(table,x,y); if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem; - if (newsize != size) { - (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddLinearAndSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize >= size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddLinearInPlace(table,x,y); + if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem; + if (newsize != size) { + (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } + } else if (cuddTestInteract(table,xindex,yindex)) { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + cuddUpdateInteractionMatrix(table,xindex,yindex); } - } else if (cuddTestInteract(table,xindex,yindex)) { - size = newsize; - move->flags = CUDD_LINEAR_TRANSFORM_MOVE; - ddUpdateInteractionMatrix(table,xindex,yindex); - } - move->size = size; - if ((double) size > (double) limitSize * table->maxGrowth) break; - if (size < limitSize) limitSize = size; - x = y; - y = cuddNextHigh(table,x); + move->size = size; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + x = y; + y = cuddNextHigh(table,x); } return(moves); ddLinearAndSiftingDownOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return((Move *) CUDD_OUT_OF_MEM); @@ -712,26 +1245,26 @@ ddLinearAndSiftingBackward( Move * moves) { Move *move; - int res; + int res; for (move = moves; move != NULL; move = move->next) { - if (move->size < size) { - size = move->size; - } + if (move->size < size) { + size = move->size; + } } for (move = moves; move != NULL; move = move->next) { - if (move->size == size) return(1); - if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { - res = cuddLinearInPlace(table,(int)move->x,(int)move->y); - if (!res) return(0); - } - res = cuddSwapInPlace(table,(int)move->x,(int)move->y); - if (!res) return(0); - if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { - res = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (move->size == size) return(1); + if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + res = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); if (!res) return(0); - } + if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { + res = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } } return(1); @@ -759,45 +1292,45 @@ ddUndoMoves( Move *invmoves = NULL; Move *move; Move *invmove; - int size; + int size; for (move = moves; move != NULL; move = move->next) { - invmove = (Move *) cuddDynamicAllocNode(table); - if (invmove == NULL) goto ddUndoMovesOutOfMem; - invmove->x = move->x; - invmove->y = move->y; - invmove->next = invmoves; - invmoves = invmove; - if (move->flags == CUDD_SWAP_MOVE) { - invmove->flags = CUDD_SWAP_MOVE; - size = cuddSwapInPlace(table,(int)move->x,(int)move->y); - if (!size) goto ddUndoMovesOutOfMem; - } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { - invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; - size = cuddLinearInPlace(table,(int)move->x,(int)move->y); - if (!size) goto ddUndoMovesOutOfMem; - size = cuddSwapInPlace(table,(int)move->x,(int)move->y); - if (!size) goto ddUndoMovesOutOfMem; - } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ + invmove = (Move *) cuddDynamicAllocNode(table); + if (invmove == NULL) goto ddUndoMovesOutOfMem; + invmove->x = move->x; + invmove->y = move->y; + invmove->next = invmoves; + invmoves = invmove; + if (move->flags == CUDD_SWAP_MOVE) { + invmove->flags = CUDD_SWAP_MOVE; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; + size = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ #ifdef DD_DEBUG - (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); + (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); #endif - invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; - size = cuddSwapInPlace(table,(int)move->x,(int)move->y); - if (!size) goto ddUndoMovesOutOfMem; - size = cuddLinearInPlace(table,(int)move->x,(int)move->y); - if (!size) goto ddUndoMovesOutOfMem; - } - invmove->size = size; + invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; + size = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + size = cuddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto ddUndoMovesOutOfMem; + } + invmove->size = size; } return(invmoves); ddUndoMovesOutOfMem: while (invmoves != NULL) { - move = invmoves->next; - cuddDeallocNode(table, (DdNode *) invmoves); - invmoves = move; + move = invmoves->next; + cuddDeallocMove(table, invmoves); + invmoves = move; } return((Move *) CUDD_OUT_OF_MEM); @@ -805,506 +1338,7 @@ ddUndoMovesOutOfMem: /**Function******************************************************************** - - Synopsis [Linearly combines two adjacent variables.] - - Description [Linearly combines two adjacent variables. Specifically, - replaces the top variable with the exclusive nor of the two variables. - It assumes that no dead nodes are present on entry to this - procedure. The procedure then guarantees that no dead nodes will be - present when it terminates. cuddLinearInPlace assumes that x < - y. Returns the number of keys in the table if successful; 0 - otherwise.] - - SideEffects [The two subtables corrresponding to variables x and y are - modified. The global counters of the unique table are also affected.] - - SeeAlso [cuddSwapInPlace] - -******************************************************************************/ -static int -cuddLinearInPlace( - DdManager * table, - int x, - int y) -{ - DdNodePtr *xlist, *ylist; - int xindex, yindex; - int xslots, yslots; - int xshift, yshift; - int oldxkeys, oldykeys; - int newxkeys, newykeys; - int comple, newcomplement; - int i; - int posn; - int isolated; - DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0; - DdNode *g,*next,*last = NULL; // Suppress "might be used uninitialized" - DdNodePtr *previousP; - DdNode *tmp; - DdNode *sentinel = &(table->sentinel); -#if DD_DEBUG - int count, idcheck; -#endif - -#ifdef DD_DEBUG - assert(x < y); - assert(cuddNextHigh(table,x) == y); - assert(table->subtables[x].keys != 0); - assert(table->subtables[y].keys != 0); - assert(table->subtables[x].dead == 0); - assert(table->subtables[y].dead == 0); -#endif - - xindex = table->invperm[x]; - yindex = table->invperm[y]; - - if (cuddTestInteract(table,xindex,yindex)) { -#ifdef DD_STATS - ddTotalNumberLinearTr++; -#endif - /* Get parameters of x subtable. */ - xlist = table->subtables[x].nodelist; - oldxkeys = table->subtables[x].keys; - xslots = table->subtables[x].slots; - xshift = table->subtables[x].shift; - - /* Get parameters of y subtable. */ - ylist = table->subtables[y].nodelist; - oldykeys = table->subtables[y].keys; - yslots = table->subtables[y].slots; - yshift = table->subtables[y].shift; - - newxkeys = 0; - newykeys = oldykeys; - - /* Check whether the two projection functions involved in this - ** swap are isolated. At the end, we'll be able to tell how many - ** isolated projection functions are there by checking only these - ** two functions again. This is done to eliminate the isolated - ** projection functions from the node count. - */ - isolated = - ((table->vars[xindex]->ref == 1) + - (table->vars[yindex]->ref == 1)); - - /* The nodes in the x layer are put in a chain. - ** The chain is handled as a FIFO; g points to the beginning and - ** last points to the end. - */ - g = NULL; - for (i = 0; i < xslots; i++) { - f = xlist[i]; - if (f == sentinel) continue; - xlist[i] = sentinel; - if (g == NULL) { - g = f; - } else { - last->next = f; - } - while ((next = f->next) != sentinel) { - f = next; - } /* while there are elements in the collision chain */ - last = f; - } /* for each slot of the x subtable */ - last->next = NULL; - -#ifdef DD_COUNT - table->swapSteps += oldxkeys; -#endif - /* Take care of the x nodes that must be re-expressed. - ** They form a linked list pointed by g. - */ - f = g; - while (f != NULL) { - next = f->next; - /* Find f1, f0, f11, f10, f01, f00. */ - f1 = cuddT(f); -#ifdef DD_DEBUG - assert(!(Cudd_IsComplement(f1))); -#endif - if ((int) f1->index == yindex) { - f11 = cuddT(f1); f10 = cuddE(f1); - } else { - f11 = f10 = f1; - } -#ifdef DD_DEBUG - assert(!(Cudd_IsComplement(f11))); -#endif - f0 = cuddE(f); - comple = Cudd_IsComplement(f0); - f0 = Cudd_Regular(f0); - if ((int) f0->index == yindex) { - f01 = cuddT(f0); f00 = cuddE(f0); - } else { - f01 = f00 = f0; - } - if (comple) { - f01 = Cudd_Not(f01); - f00 = Cudd_Not(f00); - } - /* Decrease ref count of f1. */ - cuddSatDec(f1->ref); - /* Create the new T child. */ - if (f11 == f00) { - newf1 = f11; - cuddSatInc(newf1->ref); - } else { - /* Check ylist for triple (yindex,f11,f00). */ - posn = ddHash(f11, f00, yshift); - /* For each element newf1 in collision list ylist[posn]. */ - previousP = &(ylist[posn]); - newf1 = *previousP; - while (f11 < cuddT(newf1)) { - previousP = &(newf1->next); - newf1 = *previousP; - } - while (f11 == cuddT(newf1) && f00 < cuddE(newf1)) { - previousP = &(newf1->next); - newf1 = *previousP; - } - if (cuddT(newf1) == f11 && cuddE(newf1) == f00) { - cuddSatInc(newf1->ref); - } else { /* no match */ - newf1 = cuddDynamicAllocNode(table); - if (newf1 == NULL) - goto cuddLinearOutOfMem; - newf1->index = yindex; newf1->ref = 1; - cuddT(newf1) = f11; - cuddE(newf1) = f00; - /* Insert newf1 in the collision list ylist[posn]; - ** increase the ref counts of f11 and f00. - */ - newykeys++; - newf1->next = *previousP; - *previousP = newf1; - cuddSatInc(f11->ref); - tmp = Cudd_Regular(f00); - cuddSatInc(tmp->ref); - } - } - cuddT(f) = newf1; -#ifdef DD_DEBUG - assert(!(Cudd_IsComplement(newf1))); -#endif - - /* Do the same for f0, keeping complement dots into account. */ - /* decrease ref count of f0 */ - tmp = Cudd_Regular(f0); - cuddSatDec(tmp->ref); - /* create the new E child */ - if (f01 == f10) { - newf0 = f01; - tmp = Cudd_Regular(newf0); - cuddSatInc(tmp->ref); - } else { - /* make sure f01 is regular */ - newcomplement = Cudd_IsComplement(f01); - if (newcomplement) { - f01 = Cudd_Not(f01); - f10 = Cudd_Not(f10); - } - /* Check ylist for triple (yindex,f01,f10). */ - posn = ddHash(f01, f10, yshift); - /* For each element newf0 in collision list ylist[posn]. */ - previousP = &(ylist[posn]); - newf0 = *previousP; - while (f01 < cuddT(newf0)) { - previousP = &(newf0->next); - newf0 = *previousP; - } - while (f01 == cuddT(newf0) && f10 < cuddE(newf0)) { - previousP = &(newf0->next); - newf0 = *previousP; - } - if (cuddT(newf0) == f01 && cuddE(newf0) == f10) { - cuddSatInc(newf0->ref); - } else { /* no match */ - newf0 = cuddDynamicAllocNode(table); - if (newf0 == NULL) - goto cuddLinearOutOfMem; - newf0->index = yindex; newf0->ref = 1; - cuddT(newf0) = f01; - cuddE(newf0) = f10; - /* Insert newf0 in the collision list ylist[posn]; - ** increase the ref counts of f01 and f10. - */ - newykeys++; - newf0->next = *previousP; - *previousP = newf0; - cuddSatInc(f01->ref); - tmp = Cudd_Regular(f10); - cuddSatInc(tmp->ref); - } - if (newcomplement) { - newf0 = Cudd_Not(newf0); - } - } - cuddE(f) = newf0; - - /* Re-insert the modified f in xlist. - ** The modified f does not already exists in xlist. - ** (Because of the uniqueness of the cofactors.) - */ - posn = ddHash(newf1, newf0, xshift); - newxkeys++; - previousP = &(xlist[posn]); - tmp = *previousP; - while (newf1 < cuddT(tmp)) { - previousP = &(tmp->next); - tmp = *previousP; - } - while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { - previousP = &(tmp->next); - tmp = *previousP; - } - f->next = *previousP; - *previousP = f; - f = next; - } /* while f != NULL */ - - /* GC the y layer. */ - - /* For each node f in ylist. */ - for (i = 0; i < yslots; i++) { - previousP = &(ylist[i]); - f = *previousP; - while (f != sentinel) { - next = f->next; - if (f->ref == 0) { - tmp = cuddT(f); - cuddSatDec(tmp->ref); - tmp = Cudd_Regular(cuddE(f)); - cuddSatDec(tmp->ref); - cuddDeallocNode(table,f); - newykeys--; - } else { - *previousP = f; - previousP = &(f->next); - } - f = next; - } /* while f */ - *previousP = sentinel; - } /* for every collision list */ - -#if DD_DEBUG -#if 0 - (void) fprintf(table->out,"Linearly combining %d and %d\n",x,y); -#endif - count = 0; - idcheck = 0; - for (i = 0; i < yslots; i++) { - f = ylist[i]; - while (f != sentinel) { - count++; - if (f->index != (DdHalfWord) yindex) - idcheck++; - f = f->next; - } - } - if (count != newykeys) { - fprintf(table->err,"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count); - } - if (idcheck != 0) - fprintf(table->err,"Error in id's of ylist\twrong id's = %d\n",idcheck); - count = 0; - idcheck = 0; - for (i = 0; i < xslots; i++) { - f = xlist[i]; - while (f != sentinel) { - count++; - if (f->index != (DdHalfWord) xindex) - idcheck++; - f = f->next; - } - } - if (count != newxkeys || newxkeys != oldxkeys) { - fprintf(table->err,"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count); - } - if (idcheck != 0) - fprintf(table->err,"Error in id's of xlist\twrong id's = %d\n",idcheck); -#endif - - isolated += (table->vars[xindex]->ref == 1) + - (table->vars[yindex]->ref == 1); - table->isolated += isolated; - - /* Set the appropriate fields in table. */ - table->subtables[y].keys = newykeys; - - /* Here we should update the linear combination table - ** to record that x <- x EXNOR y. This is done by complementing - ** the (x,y) entry of the table. - */ - - table->keys += newykeys - oldykeys; - - cuddXorLinear(table,xindex,yindex); - } - -#ifdef DD_DEBUG - if (zero) { - (void) Cudd_DebugCheck(table); - } -#endif - - return(table->keys - table->isolated); - -cuddLinearOutOfMem: - (void) fprintf(table->err,"Error: cuddLinearInPlace out of memory\n"); - - return (0); - -} /* end of cuddLinearInPlace */ - - -/**Function******************************************************************** - - Synopsis [Updates the interaction matrix.] - - Description [] - - SideEffects [none] - - SeeAlso [] - -******************************************************************************/ -static void -ddUpdateInteractionMatrix( - DdManager * table, - int xindex, - int yindex) -{ - int i; - for (i = 0; i < yindex; i++) { - if (i != xindex && cuddTestInteract(table,i,yindex)) { - if (i < xindex) { - cuddSetInteract(table,i,xindex); - } else { - cuddSetInteract(table,xindex,i); - } - } - } - for (i = yindex+1; i < table->size; i++) { - if (i != xindex && cuddTestInteract(table,yindex,i)) { - if (i < xindex) { - cuddSetInteract(table,i,xindex); - } else { - cuddSetInteract(table,xindex,i); - } - } - } - -} /* end of ddUpdateInteractionMatrix */ - - -/**Function******************************************************************** - - Synopsis [Initializes the linear transform matrix.] - - Description [] - - SideEffects [none] - - SeeAlso [] - -******************************************************************************/ -static int -cuddInitLinear( - DdManager * table) -{ - int words; - int wordsPerRow; - int nvars; - int word; - int bit; - int i; - long *linear; - nvars = table->size; - wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; - words = wordsPerRow * nvars; - table->linear = linear = ABC_ALLOC(long,words); - if (linear == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); - } - table->memused += words * sizeof(long); - table->linearSize = nvars; - for (i = 0; i < words; i++) linear[i] = 0; - for (i = 0; i < nvars; i++) { - word = wordsPerRow * i + (i >> LOGBPL); - bit = i & (BPL-1); - linear[word] = 1 << bit; - } - return(1); - -} /* end of cuddInitLinear */ - - -/**Function******************************************************************** - - Synopsis [Resizes the linear transform matrix.] - - Description [] - - SideEffects [none] - - SeeAlso [] - -******************************************************************************/ -static int -cuddResizeLinear( - DdManager * table) -{ - int words,oldWords; - int wordsPerRow,oldWordsPerRow; - int nvars,oldNvars; - int word,oldWord; - int bit; - int i,j; - long *linear,*oldLinear; - - oldNvars = table->linearSize; - oldWordsPerRow = ((oldNvars - 1) >> LOGBPL) + 1; - oldWords = oldWordsPerRow * oldNvars; - oldLinear = table->linear; - - nvars = table->size; - wordsPerRow = ((nvars - 1) >> LOGBPL) + 1; - words = wordsPerRow * nvars; - table->linear = linear = ABC_ALLOC(long,words); - if (linear == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); - } - table->memused += (words - oldWords) * sizeof(long); - for (i = 0; i < words; i++) linear[i] = 0; - - /* Copy old matrix. */ - for (i = 0; i < oldNvars; i++) { - for (j = 0; j < oldWordsPerRow; j++) { - oldWord = oldWordsPerRow * i + j; - word = wordsPerRow * i + j; - linear[word] = oldLinear[oldWord]; - } - } - ABC_FREE(oldLinear); - - /* Add elements to the diagonal. */ - for (i = oldNvars; i < nvars; i++) { - word = wordsPerRow * i + (i >> LOGBPL); - bit = i & (BPL-1); - linear[word] = 1 << bit; - } - table->linearSize = nvars; - - return(1); - -} /* end of cuddResizeLinear */ - - -/**Function******************************************************************** - Synopsis [XORs two rows of the linear transform matrix.] Description [XORs two rows of the linear transform matrix and replaces @@ -1329,10 +1363,11 @@ cuddXorLinear( long *linear = table->linear; for (i = 0; i < wordsPerRow; i++) { - linear[xstart+i] ^= linear[ystart+i]; + linear[xstart+i] ^= linear[ystart+i]; } } /* end of cuddXorLinear */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddLiteral.c b/src/bdd/cudd/cuddLiteral.c index c5684e9b..b5895fcf 100644 --- a/src/bdd/cudd/cuddLiteral.c +++ b/src/bdd/cudd/cuddLiteral.c @@ -8,20 +8,47 @@ BDDs.] Description [External procedures included in this file: - <ul> - <li> Cudd_bddLiteralSetIntersection() - </ul> - Internal procedures included in this file: - <ul> - <li> cuddBddLiteralSetIntersectionRecur() - </ul>] + <ul> + <li> Cudd_bddLiteralSetIntersection() + </ul> + Internal procedures included in this file: + <ul> + <li> cuddBddLiteralSetIntersectionRecur() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -32,6 +59,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -49,7 +77,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddLiteral.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddLiteral.c,v 1.8 2004/08/13 18:04:50 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -95,8 +123,8 @@ Cudd_bddLiteralSetIntersection( DdNode *res; do { - dd->reordered = 0; - res = cuddBddLiteralSetIntersectionRecur(dd,f,g); + dd->reordered = 0; + res = cuddBddLiteralSetIntersectionRecur(dd,f,g); } while (dd->reordered == 1); return(res); @@ -155,27 +183,27 @@ cuddBddLiteralSetIntersectionRecur( ** loop will stop when the constant node is reached in both cubes. */ while (topf != topg) { - if (topf < topg) { /* move down on f */ - comple = f != F; - f = cuddT(F); - if (comple) f = Cudd_Not(f); - if (f == zero) { - f = cuddE(F); - if (comple) f = Cudd_Not(f); - } - F = Cudd_Regular(f); - topf = cuddI(dd,F->index); - } else if (topg < topf) { - comple = g != G; - g = cuddT(G); - if (comple) g = Cudd_Not(g); - if (g == zero) { - g = cuddE(G); - if (comple) g = Cudd_Not(g); + if (topf < topg) { /* move down on f */ + comple = f != F; + f = cuddT(F); + if (comple) f = Cudd_Not(f); + if (f == zero) { + f = cuddE(F); + if (comple) f = Cudd_Not(f); + } + F = Cudd_Regular(f); + topf = cuddI(dd,F->index); + } else if (topg < topf) { + comple = g != G; + g = cuddT(G); + if (comple) g = Cudd_Not(g); + if (g == zero) { + g = cuddE(G); + if (comple) g = Cudd_Not(g); + } + G = Cudd_Regular(g); + topg = cuddI(dd,G->index); } - G = Cudd_Regular(g); - topg = cuddI(dd,G->index); - } } /* At this point, f == one <=> g == 1. It suffices to test one of them. */ @@ -183,7 +211,7 @@ cuddBddLiteralSetIntersectionRecur( res = cuddCacheLookup2(dd,Cudd_bddLiteralSetIntersection,f,g); if (res != NULL) { - return(res); + return(res); } /* Here f and g are both non constant and have the same top variable. */ @@ -192,39 +220,39 @@ cuddBddLiteralSetIntersectionRecur( phasef = 1; if (comple) fc = Cudd_Not(fc); if (fc == zero) { - fc = cuddE(F); - phasef = 0; - if (comple) fc = Cudd_Not(fc); + fc = cuddE(F); + phasef = 0; + if (comple) fc = Cudd_Not(fc); } comple = g != G; gc = cuddT(G); phaseg = 1; if (comple) gc = Cudd_Not(gc); if (gc == zero) { - gc = cuddE(G); - phaseg = 0; - if (comple) gc = Cudd_Not(gc); + gc = cuddE(G); + phaseg = 0; + if (comple) gc = Cudd_Not(gc); } tmp = cuddBddLiteralSetIntersectionRecur(dd,fc,gc); if (tmp == NULL) { - return(NULL); + return(NULL); } if (phasef != phaseg) { - res = tmp; - } else { - cuddRef(tmp); - if (phasef == 0) { - res = cuddBddAndRecur(dd,Cudd_Not(dd->vars[F->index]),tmp); + res = tmp; } else { - res = cuddBddAndRecur(dd,dd->vars[F->index],tmp); - } - if (res == NULL) { - Cudd_RecursiveDeref(dd,tmp); - return(NULL); - } - cuddDeref(tmp); /* Just cuddDeref, because it is included in result */ + cuddRef(tmp); + if (phasef == 0) { + res = cuddBddAndRecur(dd,Cudd_Not(dd->vars[F->index]),tmp); + } else { + res = cuddBddAndRecur(dd,dd->vars[F->index],tmp); + } + if (res == NULL) { + Cudd_RecursiveDeref(dd,tmp); + return(NULL); + } + cuddDeref(tmp); /* Just cuddDeref, because it is included in result */ } cuddCacheInsert2(dd,Cudd_bddLiteralSetIntersection,f,g,res); @@ -238,5 +266,7 @@ cuddBddLiteralSetIntersectionRecur( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddMatMult.c b/src/bdd/cudd/cuddMatMult.c index b4ec5c6a..f78d037d 100644 --- a/src/bdd/cudd/cuddMatMult.c +++ b/src/bdd/cudd/cuddMatMult.c @@ -7,25 +7,52 @@ Synopsis [Matrix multiplication functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_addMatrixMultiply() - <li> Cudd_addTimesPlus() - <li> Cudd_addTriangle() - <li> Cudd_addOuterSum() - </ul> - Static procedures included in this module: - <ul> - <li> addMMRecur() - <li> addTriangleRecur() - <li> cuddAddOuterSumRecur() - </ul>] + <ul> + <li> Cudd_addMatrixMultiply() + <li> Cudd_addTimesPlus() + <li> Cudd_addTriangle() + <li> Cudd_addOuterSum() + </ul> + Static procedures included in this module: + <ul> + <li> addMMRecur() + <li> addTriangleRecur() + <li> cuddAddOuterSumRecur() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -36,6 +63,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -56,7 +84,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.17 2004/08/13 18:04:50 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -70,9 +98,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddMatMult.c,v 1.1.1.1 2003/02/24 22:23:5 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * addMMRecur ARGS((DdManager *dd, DdNode *A, DdNode *B, int topP, int *vars)); -static DdNode * addTriangleRecur ARGS((DdManager *dd, DdNode *f, DdNode *g, int *vars, DdNode *cube)); -static DdNode * cuddAddOuterSumRecur ARGS((DdManager *dd, DdNode *M, DdNode *r, DdNode *c)); +static DdNode * addMMRecur (DdManager *dd, DdNode *A, DdNode *B, int topP, int *vars); +static DdNode * addTriangleRecur (DdManager *dd, DdNode *f, DdNode *g, int *vars, DdNode *cube); +static DdNode * cuddAddOuterSumRecur (DdManager *dd, DdNode *M, DdNode *r, DdNode *c); /**AutomaticEnd***************************************************************/ @@ -115,8 +143,8 @@ Cudd_addMatrixMultiply( nvars = dd->size; vars = ABC_ALLOC(int,nvars); if (vars == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < nvars; i++) { vars[i] = 0; @@ -126,8 +154,8 @@ Cudd_addMatrixMultiply( } do { - dd->reordered = 0; - res = addMMRecur(dd,A,B,-1,vars); + dd->reordered = 0; + res = addMMRecur(dd,A,B,-1,vars); } while (dd->reordered == 1); ABC_FREE(vars); return(res); @@ -168,20 +196,20 @@ Cudd_addTimesPlus( Cudd_Ref(tmp); Cudd_Ref(cube = DD_ONE(dd)); for (i = nz-1; i >= 0; i--) { - w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd)); - if (w == NULL) { - Cudd_RecursiveDeref(dd,tmp); - return(NULL); - } - Cudd_Ref(w); - Cudd_RecursiveDeref(dd,cube); - cube = w; + w = Cudd_addIte(dd,z[i],cube,DD_ZERO(dd)); + if (w == NULL) { + Cudd_RecursiveDeref(dd,tmp); + return(NULL); + } + Cudd_Ref(w); + Cudd_RecursiveDeref(dd,cube); + cube = w; } res = Cudd_addExistAbstract(dd,tmp,cube); if (res == NULL) { - Cudd_RecursiveDeref(dd,tmp); - Cudd_RecursiveDeref(dd,cube); - return(NULL); + Cudd_RecursiveDeref(dd,tmp); + Cudd_RecursiveDeref(dd,cube); + return(NULL); } Cudd_Ref(res); Cudd_RecursiveDeref(dd,cube); @@ -225,21 +253,21 @@ Cudd_addTriangle( nvars = dd->size; vars = ABC_ALLOC(int, nvars); if (vars == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < nvars; i++) vars[i] = -1; for (i = 0; i < nz; i++) vars[z[i]->index] = i; cube = Cudd_addComputeCube(dd, z, NULL, nz); if (cube == NULL) { - ABC_FREE(vars); - return(NULL); + ABC_FREE(vars); + return(NULL); } cuddRef(cube); do { - dd->reordered = 0; - res = addTriangleRecur(dd, f, g, vars, cube); + dd->reordered = 0; + res = addTriangleRecur(dd, f, g, vars, cube); } while (dd->reordered == 1); if (res != NULL) cuddRef(res); Cudd_RecursiveDeref(dd,cube); @@ -274,8 +302,8 @@ Cudd_addOuterSum( DdNode *res; do { - dd->reordered = 0; - res = cuddAddOuterSumRecur(dd, M, r, c); + dd->reordered = 0; + res = cuddAddOuterSumRecur(dd, M, r, c); } while (dd->reordered == 1); return(res); @@ -310,21 +338,21 @@ addMMRecur( int * vars) { DdNode *zero, - *At, /* positive cofactor of first operand */ - *Ae, /* negative cofactor of first operand */ - *Bt, /* positive cofactor of second operand */ - *Be, /* negative cofactor of second operand */ - *t, /* positive cofactor of result */ - *e, /* negative cofactor of result */ - *scaled, /* scaled result */ - *add_scale, /* ADD representing the scaling factor */ - *res; - int i; /* loop index */ - double scale; /* scaling factor */ - int index; /* index of the top variable */ + *At, /* positive cofactor of first operand */ + *Ae, /* negative cofactor of first operand */ + *Bt, /* positive cofactor of second operand */ + *Be, /* negative cofactor of second operand */ + *t, /* positive cofactor of result */ + *e, /* negative cofactor of result */ + *scaled, /* scaled result */ + *add_scale, /* ADD representing the scaling factor */ + *res; + int i; /* loop index */ + double scale; /* scaling factor */ + int index; /* index of the top variable */ CUDD_VALUE_TYPE value; unsigned int topA, topB, topV; - DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *); + DD_CTFP cacheOp; statLine(dd); zero = DD_ZERO(dd); @@ -334,21 +362,21 @@ addMMRecur( } if (cuddIsConstant(A) && cuddIsConstant(B)) { - /* Compute the scaling factor. It is 2^k, where k is the - ** number of summation variables below the current variable. - ** Indeed, these constants represent blocks of 2^k identical - ** constant values in both A and B. - */ - value = cuddV(A) * cuddV(B); - for (i = 0; i < dd->size; i++) { - if (vars[i]) { - if (dd->perm[i] > topP) { - value *= (CUDD_VALUE_TYPE) 2; + /* Compute the scaling factor. It is 2^k, where k is the + ** number of summation variables below the current variable. + ** Indeed, these constants represent blocks of 2^k identical + ** constant values in both A and B. + */ + value = cuddV(A) * cuddV(B); + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP) { + value *= (CUDD_VALUE_TYPE) 2; + } + } } - } - } - res = cuddUniqueConst(dd, value); - return(res); + res = cuddUniqueConst(dd, value); + return(res); } /* Standardize to increase cache efficiency. Clearly, A*B != B*A @@ -357,67 +385,67 @@ addMMRecur( ** which one is passed as first argument. */ if (A > B) { - DdNode *tmp = A; - A = B; - B = tmp; + DdNode *tmp = A; + A = B; + B = tmp; } topA = cuddI(dd,A->index); topB = cuddI(dd,B->index); topV = ddMin(topA,topB); - cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) addMMRecur; + cacheOp = (DD_CTFP) addMMRecur; res = cuddCacheLookup2(dd,cacheOp,A,B); if (res != NULL) { - /* If the result is 0, there is no need to normalize. - ** Otherwise we count the number of z variables between - ** the current depth and the top of the ADDs. These are - ** the missing variables that determine the size of the - ** constant blocks. - */ - if (res == zero) return(res); - scale = 1.0; - for (i = 0; i < dd->size; i++) { - if (vars[i]) { - if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { - scale *= 2; - } - } - } - if (scale > 1.0) { - cuddRef(res); - add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); - if (add_scale == NULL) { - Cudd_RecursiveDeref(dd, res); - return(NULL); + /* If the result is 0, there is no need to normalize. + ** Otherwise we count the number of z variables between + ** the current depth and the top of the ADDs. These are + ** the missing variables that determine the size of the + ** constant blocks. + */ + if (res == zero) return(res); + scale = 1.0; + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { + scale *= 2; + } + } } - cuddRef(add_scale); - scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); - if (scaled == NULL) { - Cudd_RecursiveDeref(dd, add_scale); - Cudd_RecursiveDeref(dd, res); - return(NULL); + if (scale > 1.0) { + cuddRef(res); + add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); + if (add_scale == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(add_scale); + scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); + if (scaled == NULL) { + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(scaled); + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + res = scaled; + cuddDeref(res); } - cuddRef(scaled); - Cudd_RecursiveDeref(dd, add_scale); - Cudd_RecursiveDeref(dd, res); - res = scaled; - cuddDeref(res); - } return(res); } /* compute the cofactors */ if (topV == topA) { - At = cuddT(A); - Ae = cuddE(A); + At = cuddT(A); + Ae = cuddE(A); } else { - At = Ae = A; + At = Ae = A; } if (topV == topB) { - Bt = cuddT(B); - Be = cuddE(B); + Bt = cuddT(B); + Be = cuddE(B); } else { - Bt = Be = B; + Bt = Be = B; } t = addMMRecur(dd, At, Bt, (int)topV, vars); @@ -425,39 +453,39 @@ addMMRecur( cuddRef(t); e = addMMRecur(dd, Ae, Be, (int)topV, vars); if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); + Cudd_RecursiveDeref(dd, t); + return(NULL); } cuddRef(e); index = dd->invperm[topV]; if (vars[index] == 0) { - /* We have split on either the rows of A or the columns - ** of B. We just need to connect the two subresults, - ** which correspond to two submatrices of the result. - */ - res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); - if (res == NULL) { - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - return(NULL); - } - cuddRef(res); - cuddDeref(t); - cuddDeref(e); + /* We have split on either the rows of A or the columns + ** of B. We just need to connect the two subresults, + ** which correspond to two submatrices of the result. + */ + res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); + cuddDeref(t); + cuddDeref(e); } else { - /* we have simultaneously split on the columns of A and - ** the rows of B. The two subresults must be added. - */ - res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e); - if (res == NULL) { + /* we have simultaneously split on the columns of A and + ** the rows of B. The two subresults must be added. + */ + res = cuddAddApplyRecur(dd,Cudd_addPlus,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(dd, t); Cudd_RecursiveDeref(dd, e); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); } cuddCacheInsert2(dd,cacheOp,A,B,res); @@ -469,32 +497,32 @@ addMMRecur( ** scaling the result. */ if (res != zero) { - scale = 1.0; - for (i = 0; i < dd->size; i++) { - if (vars[i]) { - if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { - scale *= 2; - } - } - } - if (scale > 1.0) { - add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); - if (add_scale == NULL) { - Cudd_RecursiveDeref(dd, res); - return(NULL); + scale = 1.0; + for (i = 0; i < dd->size; i++) { + if (vars[i]) { + if (dd->perm[i] > topP && (unsigned) dd->perm[i] < topV) { + scale *= 2; + } + } } - cuddRef(add_scale); - scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); - if (scaled == NULL) { - Cudd_RecursiveDeref(dd, res); - Cudd_RecursiveDeref(dd, add_scale); - return(NULL); + if (scale > 1.0) { + add_scale = cuddUniqueConst(dd,(CUDD_VALUE_TYPE)scale); + if (add_scale == NULL) { + Cudd_RecursiveDeref(dd, res); + return(NULL); + } + cuddRef(add_scale); + scaled = cuddAddApplyRecur(dd,Cudd_addTimes,res,add_scale); + if (scaled == NULL) { + Cudd_RecursiveDeref(dd, res); + Cudd_RecursiveDeref(dd, add_scale); + return(NULL); + } + cuddRef(scaled); + Cudd_RecursiveDeref(dd, add_scale); + Cudd_RecursiveDeref(dd, res); + res = scaled; } - cuddRef(scaled); - Cudd_RecursiveDeref(dd, add_scale); - Cudd_RecursiveDeref(dd, res); - res = scaled; - } } cuddDeref(res); return(res); @@ -526,25 +554,25 @@ addTriangleRecur( statLine(dd); if (f == DD_PLUS_INFINITY(dd) || g == DD_PLUS_INFINITY(dd)) { - return(DD_PLUS_INFINITY(dd)); + return(DD_PLUS_INFINITY(dd)); } if (cuddIsConstant(f) && cuddIsConstant(g)) { - value = cuddV(f) + cuddV(g); - res = cuddUniqueConst(dd, value); - return(res); + value = cuddV(f) + cuddV(g); + res = cuddUniqueConst(dd, value); + return(res); } if (f < g) { - DdNode *tmp = f; - f = g; - g = tmp; + DdNode *tmp = f; + f = g; + g = tmp; } if (f->ref != 1 || g->ref != 1) { - res = cuddCacheLookup(dd, DD_ADD_TRIANGLE_TAG, f, g, cube); - if (res != NULL) { - return(res); - } + res = cuddCacheLookup(dd, DD_ADD_TRIANGLE_TAG, f, g, cube); + if (res != NULL) { + return(res); + } } topf = cuddI(dd,f->index); topg = cuddI(dd,g->index); @@ -558,36 +586,36 @@ addTriangleRecur( cuddRef(t); e = addTriangleRecur(dd, fvn, gvn, vars, cube); if (e == NULL) { - Cudd_RecursiveDeref(dd, t); - return(NULL); + Cudd_RecursiveDeref(dd, t); + return(NULL); } cuddRef(e); index = dd->invperm[top]; if (vars[index] < 0) { - res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); - if (res == NULL) { - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + res = (t == e) ? t : cuddUniqueInter(dd,index,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } else { - res = cuddAddApplyRecur(dd,Cudd_addMinimum,t,e); - if (res == NULL) { + res = cuddAddApplyRecur(dd,Cudd_addMinimum,t,e); + if (res == NULL) { + Cudd_RecursiveDeref(dd, t); + Cudd_RecursiveDeref(dd, e); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(dd, t); Cudd_RecursiveDeref(dd, e); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(dd, t); - Cudd_RecursiveDeref(dd, e); - cuddDeref(res); + cuddDeref(res); } if (f->ref != 1 || g->ref != 1) { - cuddCacheInsert(dd, DD_ADD_TRIANGLE_TAG, f, g, cube, res); + cuddCacheInsert(dd, DD_ADD_TRIANGLE_TAG, f, g, cube, res); } return(res); @@ -623,23 +651,23 @@ cuddAddOuterSumRecur( if (r == DD_PLUS_INFINITY(dd) || c == DD_PLUS_INFINITY(dd)) return(M); if (cuddIsConstant(c) && cuddIsConstant(r)) { - R = cuddUniqueConst(dd,Cudd_V(c)+Cudd_V(r)); - cuddRef(R); - if (cuddIsConstant(M)) { - if (cuddV(R) <= cuddV(M)) { - cuddDeref(R); - return(R); + R = cuddUniqueConst(dd,Cudd_V(c)+Cudd_V(r)); + cuddRef(R); + if (cuddIsConstant(M)) { + if (cuddV(R) <= cuddV(M)) { + cuddDeref(R); + return(R); + } else { + Cudd_RecursiveDeref(dd,R); + return(M); + } } else { - Cudd_RecursiveDeref(dd,R); - return(M); + P = Cudd_addApply(dd,Cudd_addMinimum,R,M); + cuddRef(P); + Cudd_RecursiveDeref(dd,R); + cuddDeref(P); + return(P); } - } else { - P = Cudd_addApply(dd,Cudd_addMinimum,R,M); - cuddRef(P); - Cudd_RecursiveDeref(dd,R); - cuddDeref(P); - return(P); - } } /* Check the cache. */ @@ -661,16 +689,16 @@ cuddAddOuterSumRecur( cuddRef(Rt); Re = cuddAddOuterSumRecur(dd,Me,re,ce); if (Re == NULL) { - Cudd_RecursiveDeref(dd, Rt); - return(NULL); + Cudd_RecursiveDeref(dd, Rt); + return(NULL); } cuddRef(Re); index = dd->invperm[v]; R = (Rt == Re) ? Rt : cuddUniqueInter(dd,index,Rt,Re); if (R == NULL) { - Cudd_RecursiveDeref(dd, Rt); - Cudd_RecursiveDeref(dd, Re); - return(NULL); + Cudd_RecursiveDeref(dd, Rt); + Cudd_RecursiveDeref(dd, Re); + return(NULL); } cuddDeref(Rt); cuddDeref(Re); @@ -681,5 +709,7 @@ cuddAddOuterSumRecur( return(R); } /* end of cuddAddOuterSumRecur */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddPriority.c b/src/bdd/cudd/cuddPriority.c index f67fb88a..188d2c9e 100644 --- a/src/bdd/cudd/cuddPriority.c +++ b/src/bdd/cudd/cuddPriority.c @@ -7,39 +7,69 @@ Synopsis [Priority functions.] Description [External procedures included in this file: - <ul> - <li> Cudd_PrioritySelect() - <li> Cudd_Xgty() - <li> Cudd_Xeqy() - <li> Cudd_addXeqy() - <li> Cudd_Dxygtdxz() - <li> Cudd_Dxygtdyz() - <li> Cudd_CProjection() - <li> Cudd_addHamming() - <li> Cudd_MinHammingDist() - <li> Cudd_bddClosestCube() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddCProjectionRecur() - <li> cuddBddClosestCube() - </ul> - Static procedures included in this module: - <ul> - <li> cuddMinHammingDistRecur() - <li> separateCube() - <li> createResult() - </ul> - ] + <ul> + <li> Cudd_PrioritySelect() + <li> Cudd_Xgty() + <li> Cudd_Xeqy() + <li> Cudd_addXeqy() + <li> Cudd_Dxygtdxz() + <li> Cudd_Dxygtdyz() + <li> Cudd_Inequality() + <li> Cudd_Disequality() + <li> Cudd_bddInterval() + <li> Cudd_CProjection() + <li> Cudd_addHamming() + <li> Cudd_MinHammingDist() + <li> Cudd_bddClosestCube() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddCProjectionRecur() + <li> cuddBddClosestCube() + </ul> + Static procedures included in this module: + <ul> + <li> cuddMinHammingDistRecur() + <li> separateCube() + <li> createResult() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -50,10 +80,12 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ +#define DD_DEBUG 1 /*---------------------------------------------------------------------------*/ /* Stucture declarations */ @@ -70,7 +102,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddPriority.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddPriority.c,v 1.33 2009/02/20 02:14:58 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -83,9 +115,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddPriority.c,v 1.1.1.1 2003/02/24 22:23: /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int cuddMinHammingDistRecur ARGS((DdNode * f, int *minterm, DdHashTable * table, int upperBound)); -static DdNode * separateCube ARGS((DdManager *dd, DdNode *f, CUDD_VALUE_TYPE *distance)); -static DdNode * createResult ARGS((DdManager *dd, unsigned int index, unsigned int phase, DdNode *cube, CUDD_VALUE_TYPE distance)); +static int cuddMinHammingDistRecur (DdNode * f, int *minterm, DdHashTable * table, int upperBound); +static DdNode * separateCube (DdManager *dd, DdNode *f, CUDD_VALUE_TYPE *distance); +static DdNode * createResult (DdManager *dd, unsigned int index, unsigned int phase, DdNode *cube, CUDD_VALUE_TYPE distance); /**AutomaticEnd***************************************************************/ @@ -148,7 +180,7 @@ Cudd_PrioritySelect( DdNode ** z /* array of z variables (optional: may be NULL) */, DdNode * Pi /* BDD of the priority function (optional: may be NULL) */, int n /* size of x, y, and z */, - DdNode * (*Pifunc)(DdManager *, int, DdNode **, DdNode **, DdNode **) /* function used to build Pi if it is NULL */) + DD_PRFP Pifunc /* function used to build Pi if it is NULL */) { DdNode *res = NULL; DdNode *zcube = NULL; @@ -159,38 +191,38 @@ Cudd_PrioritySelect( /* Create z variables if needed. */ if (z == NULL) { - if (Pi != NULL) return(NULL); - z = ABC_ALLOC(DdNode *,n); - if (z == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - createdZ = 1; - for (i = 0; i < n; i++) { - if (dd->size >= (int) CUDD_MAXINDEX - 1) goto endgame; - z[i] = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); - if (z[i] == NULL) goto endgame; - } + if (Pi != NULL) return(NULL); + z = ABC_ALLOC(DdNode *,n); + if (z == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + createdZ = 1; + for (i = 0; i < n; i++) { + if (dd->size >= (int) CUDD_MAXINDEX - 1) goto endgame; + z[i] = cuddUniqueInter(dd,dd->size,dd->one,Cudd_Not(dd->one)); + if (z[i] == NULL) goto endgame; + } } /* Create priority function BDD if needed. */ if (Pi == NULL) { - Pi = Pifunc(dd,n,x,y,z); - if (Pi == NULL) goto endgame; - createdPi = 1; - cuddRef(Pi); + Pi = Pifunc(dd,n,x,y,z); + if (Pi == NULL) goto endgame; + createdPi = 1; + cuddRef(Pi); } /* Initialize abstraction cube. */ zcube = DD_ONE(dd); cuddRef(zcube); for (i = n - 1; i >= 0; i--) { - DdNode *tmpp; - tmpp = Cudd_bddAnd(dd,z[i],zcube); - if (tmpp == NULL) goto endgame; - cuddRef(tmpp); - Cudd_RecursiveDeref(dd,zcube); - zcube = tmpp; + DdNode *tmpp; + tmpp = Cudd_bddAnd(dd,z[i],zcube); + if (tmpp == NULL) goto endgame; + cuddRef(tmpp); + Cudd_RecursiveDeref(dd,zcube); + zcube = tmpp; } /* Compute subset of (x,y) pairs. */ @@ -199,15 +231,15 @@ Cudd_PrioritySelect( cuddRef(Rxz); Q = Cudd_bddAndAbstract(dd,Rxz,Pi,zcube); if (Q == NULL) { - Cudd_RecursiveDeref(dd,Rxz); - goto endgame; + Cudd_RecursiveDeref(dd,Rxz); + goto endgame; } cuddRef(Q); Cudd_RecursiveDeref(dd,Rxz); res = Cudd_bddAnd(dd,R,Cudd_Not(Q)); if (res == NULL) { - Cudd_RecursiveDeref(dd,Q); - goto endgame; + Cudd_RecursiveDeref(dd,Q); + goto endgame; } cuddRef(res); Cudd_RecursiveDeref(dd,Q); @@ -215,10 +247,10 @@ Cudd_PrioritySelect( endgame: if (zcube != NULL) Cudd_RecursiveDeref(dd,zcube); if (createdZ) { - ABC_FREE(z); + ABC_FREE(z); } if (createdPi) { - Cudd_RecursiveDeref(dd,Pi); + Cudd_RecursiveDeref(dd,Pi); } if (res != NULL) cuddDeref(res); return(res); @@ -234,7 +266,7 @@ endgame: 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: + 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.] @@ -262,29 +294,29 @@ Cudd_Xgty( /* Loop to build the rest of the BDD. */ for (i = N-2; i >= 0; i--) { - v = Cudd_bddAnd(dd, y[i], Cudd_Not(u)); - if (v == NULL) { - Cudd_RecursiveDeref(dd, u); - return(NULL); - } - cuddRef(v); - w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); - if (w == NULL) { + v = Cudd_bddAnd(dd, y[i], Cudd_Not(u)); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); Cudd_RecursiveDeref(dd, u); - Cudd_RecursiveDeref(dd, v); - return(NULL); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, u); - u = Cudd_bddIte(dd, x[i], Cudd_Not(v), w); - if (u == NULL) { + u = Cudd_bddIte(dd, x[i], Cudd_Not(v), w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); Cudd_RecursiveDeref(dd, v); Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(u); - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); } cuddDeref(u); @@ -301,7 +333,7 @@ Cudd_Xgty( 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: + 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] @@ -326,29 +358,29 @@ Cudd_Xeqy( /* Loop to build the rest of the BDD. */ for (i = N-2; i >= 0; i--) { - v = Cudd_bddAnd(dd, y[i], u); - if (v == NULL) { - Cudd_RecursiveDeref(dd, u); - return(NULL); - } - cuddRef(v); - w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); - if (w == NULL) { + v = Cudd_bddAnd(dd, y[i], u); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_bddAnd(dd, Cudd_Not(y[i]), u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); Cudd_RecursiveDeref(dd, u); - Cudd_RecursiveDeref(dd, v); - return(NULL); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, u); - u = Cudd_bddIte(dd, x[i], v, w); - if (u == NULL) { + u = Cudd_bddIte(dd, x[i], v, w); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); Cudd_RecursiveDeref(dd, v); Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(u); - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); } cuddDeref(u); return(u); @@ -364,7 +396,7 @@ Cudd_Xeqy( 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: + 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] @@ -392,15 +424,15 @@ Cudd_addXeqy( cuddRef(v); w = Cudd_addIte(dd, y[N-1], zero, one); if (w == NULL) { - Cudd_RecursiveDeref(dd, v); - return(NULL); + Cudd_RecursiveDeref(dd, v); + return(NULL); } cuddRef(w); u = Cudd_addIte(dd, x[N-1], v, w); - if (w == NULL) { - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); - return(NULL); + if (u == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); } cuddRef(u); Cudd_RecursiveDeref(dd, v); @@ -408,29 +440,29 @@ Cudd_addXeqy( /* Loop to build the rest of the ADD. */ for (i = N-2; i >= 0; i--) { - v = Cudd_addIte(dd, y[i], u, zero); - if (v == NULL) { - Cudd_RecursiveDeref(dd, u); - return(NULL); - } - cuddRef(v); - w = Cudd_addIte(dd, y[i], zero, u); - if (w == NULL) { + v = Cudd_addIte(dd, y[i], u, zero); + if (v == NULL) { + Cudd_RecursiveDeref(dd, u); + return(NULL); + } + cuddRef(v); + w = Cudd_addIte(dd, y[i], zero, u); + if (w == NULL) { + Cudd_RecursiveDeref(dd, u); + Cudd_RecursiveDeref(dd, v); + return(NULL); + } + cuddRef(w); Cudd_RecursiveDeref(dd, u); - Cudd_RecursiveDeref(dd, v); - return(NULL); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, u); - u = Cudd_addIte(dd, x[i], v, w); - if (w == NULL) { + u = Cudd_addIte(dd, x[i], v, w); + if (w == NULL) { + Cudd_RecursiveDeref(dd, v); + Cudd_RecursiveDeref(dd, w); + return(NULL); + } + cuddRef(u); Cudd_RecursiveDeref(dd, v); Cudd_RecursiveDeref(dd, w); - return(NULL); - } - cuddRef(u); - Cudd_RecursiveDeref(dd, v); - Cudd_RecursiveDeref(dd, w); } cuddDeref(u); return(u); @@ -448,9 +480,9 @@ Cudd_addXeqy( 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: - \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). + \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). The BDD is built bottom-up. - It has 7*N-3 internal nodes, if the variables are ordered as follows: + 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] @@ -479,15 +511,15 @@ Cudd_Dxygtdxz( cuddRef(y1_); y2 = Cudd_bddIte(dd, y[N-1], z[N-1], one); if (y2 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - return(NULL); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); } cuddRef(y2); x1 = Cudd_bddIte(dd, x[N-1], y1_, y2); if (x1 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); - return(NULL); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); } cuddRef(x1); Cudd_RecursiveDeref(dd, y1_); @@ -495,69 +527,69 @@ Cudd_Dxygtdxz( /* Loop to build the rest of the BDD. */ for (i = N-2; i >= 0; i--) { - z1 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); - if (z1 == NULL) { - Cudd_RecursiveDeref(dd, x1); - return(NULL); - } - cuddRef(z1); - z2 = Cudd_bddIte(dd, z[i], x1, one); - if (z2 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - return(NULL); - } - cuddRef(z2); - z3 = Cudd_bddIte(dd, z[i], one, x1); - if (z3 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - return(NULL); - } - cuddRef(z3); - z4 = Cudd_bddIte(dd, z[i], x1, zero); - if (z4 == NULL) { + z1 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); + if (z1 == NULL) { + Cudd_RecursiveDeref(dd, x1); + return(NULL); + } + cuddRef(z1); + z2 = Cudd_bddIte(dd, z[i], x1, one); + if (z2 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + return(NULL); + } + cuddRef(z2); + z3 = Cudd_bddIte(dd, z[i], one, x1); + if (z3 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + return(NULL); + } + cuddRef(z3); + z4 = Cudd_bddIte(dd, z[i], x1, zero); + if (z4 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + return(NULL); + } + cuddRef(z4); Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - return(NULL); - } - cuddRef(z4); - Cudd_RecursiveDeref(dd, x1); - y1_ = Cudd_bddIte(dd, y[i], z2, Cudd_Not(z1)); - if (y1_ == NULL) { - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - return(NULL); - } - cuddRef(y1_); - y2 = Cudd_bddIte(dd, y[i], z4, z3); - if (y2 == NULL) { + y1_ = Cudd_bddIte(dd, y[i], z2, Cudd_Not(z1)); + if (y1_ == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + return(NULL); + } + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[i], z4, z3); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); Cudd_RecursiveDeref(dd, z1); Cudd_RecursiveDeref(dd, z2); Cudd_RecursiveDeref(dd, z3); Cudd_RecursiveDeref(dd, z4); - Cudd_RecursiveDeref(dd, y1_); - return(NULL); - } - cuddRef(y2); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - x1 = Cudd_bddIte(dd, x[i], y1_, y2); - if (x1 == NULL) { + x1 = Cudd_bddIte(dd, x[i], y1_, y2); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); Cudd_RecursiveDeref(dd, y1_); Cudd_RecursiveDeref(dd, y2); - return(NULL); - } - cuddRef(x1); - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); } cuddDeref(x1); return(Cudd_Not(x1)); @@ -575,9 +607,9 @@ Cudd_Dxygtdxz( 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: - \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). + \sum_{i=0}^{N-1}(|x_i - y_i| \cdot 2^{N-i-1}). The BDD is built bottom-up. - It has 7*N-3 internal nodes, if the variables are ordered as follows: + 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] @@ -606,15 +638,15 @@ Cudd_Dxygtdyz( cuddRef(y1_); y2 = Cudd_bddIte(dd, y[N-1], z[N-1], zero); if (y2 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - return(NULL); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); } cuddRef(y2); x1 = Cudd_bddIte(dd, x[N-1], y1_, Cudd_Not(y2)); if (x1 == NULL) { - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); - return(NULL); + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); } cuddRef(x1); Cudd_RecursiveDeref(dd, y1_); @@ -622,69 +654,69 @@ Cudd_Dxygtdyz( /* Loop to build the rest of the BDD. */ for (i = N-2; i >= 0; i--) { - z1 = Cudd_bddIte(dd, z[i], x1, zero); - if (z1 == NULL) { - Cudd_RecursiveDeref(dd, x1); - return(NULL); - } - cuddRef(z1); - z2 = Cudd_bddIte(dd, z[i], x1, one); - if (z2 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - return(NULL); - } - cuddRef(z2); - z3 = Cudd_bddIte(dd, z[i], one, x1); - if (z3 == NULL) { - Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - return(NULL); - } - cuddRef(z3); - z4 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); - if (z4 == NULL) { + z1 = Cudd_bddIte(dd, z[i], x1, zero); + if (z1 == NULL) { + Cudd_RecursiveDeref(dd, x1); + return(NULL); + } + cuddRef(z1); + z2 = Cudd_bddIte(dd, z[i], x1, one); + if (z2 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + return(NULL); + } + cuddRef(z2); + z3 = Cudd_bddIte(dd, z[i], one, x1); + if (z3 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + return(NULL); + } + cuddRef(z3); + z4 = Cudd_bddIte(dd, z[i], one, Cudd_Not(x1)); + if (z4 == NULL) { + Cudd_RecursiveDeref(dd, x1); + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + return(NULL); + } + cuddRef(z4); Cudd_RecursiveDeref(dd, x1); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - return(NULL); - } - cuddRef(z4); - Cudd_RecursiveDeref(dd, x1); - y1_ = Cudd_bddIte(dd, y[i], z2, z1); - if (y1_ == NULL) { - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - return(NULL); - } - cuddRef(y1_); - y2 = Cudd_bddIte(dd, y[i], z4, Cudd_Not(z3)); - if (y2 == NULL) { + y1_ = Cudd_bddIte(dd, y[i], z2, z1); + if (y1_ == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + return(NULL); + } + cuddRef(y1_); + y2 = Cudd_bddIte(dd, y[i], z4, Cudd_Not(z3)); + if (y2 == NULL) { + Cudd_RecursiveDeref(dd, z1); + Cudd_RecursiveDeref(dd, z2); + Cudd_RecursiveDeref(dd, z3); + Cudd_RecursiveDeref(dd, z4); + Cudd_RecursiveDeref(dd, y1_); + return(NULL); + } + cuddRef(y2); Cudd_RecursiveDeref(dd, z1); Cudd_RecursiveDeref(dd, z2); Cudd_RecursiveDeref(dd, z3); Cudd_RecursiveDeref(dd, z4); - Cudd_RecursiveDeref(dd, y1_); - return(NULL); - } - cuddRef(y2); - Cudd_RecursiveDeref(dd, z1); - Cudd_RecursiveDeref(dd, z2); - Cudd_RecursiveDeref(dd, z3); - Cudd_RecursiveDeref(dd, z4); - x1 = Cudd_bddIte(dd, x[i], y1_, Cudd_Not(y2)); - if (x1 == NULL) { + x1 = Cudd_bddIte(dd, x[i], y1_, Cudd_Not(y2)); + if (x1 == NULL) { + Cudd_RecursiveDeref(dd, y1_); + Cudd_RecursiveDeref(dd, y2); + return(NULL); + } + cuddRef(x1); Cudd_RecursiveDeref(dd, y1_); Cudd_RecursiveDeref(dd, y2); - return(NULL); - } - cuddRef(x1); - Cudd_RecursiveDeref(dd, y1_); - Cudd_RecursiveDeref(dd, y2); } cuddDeref(x1); return(Cudd_Not(x1)); @@ -694,6 +726,464 @@ Cudd_Dxygtdyz( /**Function******************************************************************** + Synopsis [Generates a BDD for the function x - y ≥ c.] + + Description [This function generates a BDD for the function x -y ≥ c. + Both x and y are N-bit numbers, x\[0\] x\[1\] ... x\[N-1\] and + y\[0\] y\[1\] ... y\[N-1\], with 0 the most significant bit. + The BDD is built bottom-up. + It has a linear number of nodes if the variables are ordered as follows: + x\[0\] y\[0\] x\[1\] y\[1\] ... x\[N-1\] y\[N-1\].] + + SideEffects [None] + + SeeAlso [Cudd_Xgty] + +******************************************************************************/ +DdNode * +Cudd_Inequality( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + int c /* right-hand side constant */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + /* The nodes at level i represent values of the difference that are + ** multiples of 2^i. We use variables with names starting with k + ** to denote the multipliers of 2^i in such multiples. */ + int kTrue = c; + int kFalse = c - 1; + /* Mask used to compute the ceiling function. Since we divide by 2^i, + ** we want to know whether the dividend is a multiple of 2^i. If it is, + ** then ceiling and floor coincide; otherwise, they differ by one. */ + int mask = 1; + int i; + + DdNode *f = NULL; /* the eventual result */ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + + /* Two x-labeled nodes are created at most at each iteration. They are + ** stored, along with their k values, in these variables. At each level, + ** the old nodes are freed and the new nodes are copied into the old map. + */ + DdNode *map[2] = {0}; + int invalidIndex = 1 << (N-1); + int index[2] = {invalidIndex, invalidIndex}; + + /* This should never happen. */ + if (N < 0) return(NULL); + + /* If there are no bits, both operands are 0. The result depends on c. */ + if (N == 0) { + if (c >= 0) return(one); + else return(zero); + } + + /* The maximum or the minimum difference comparing to c can generate the terminal case */ + if ((1 << N) - 1 < c) return(zero); + else if ((-(1 << N) + 1) >= c) return(one); + + /* Build the result bottom up. */ + for (i = 1; i <= N; i++) { + int kTrueLower, kFalseLower; + int leftChild, middleChild, rightChild; + DdNode *g0, *g1, *fplus, *fequal, *fminus; + int j; + DdNode *newMap[2]; + int newIndex[2]; + + kTrueLower = kTrue; + kFalseLower = kFalse; + /* kTrue = ceiling((c-1)/2^i) + 1 */ + kTrue = ((c-1) >> i) + ((c & mask) != 1) + 1; + mask = (mask << 1) | 1; + /* kFalse = floor(c/2^i) - 1 */ + kFalse = (c >> i) - 1; + newIndex[0] = invalidIndex; + newIndex[1] = invalidIndex; + + for (j = kFalse + 1; j < kTrue; j++) { + /* Skip if node is not reachable from top of BDD. */ + if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue; + + /* Find f- */ + leftChild = (j << 1) - 1; + if (leftChild >= kTrueLower) { + fminus = one; + } else if (leftChild <= kFalseLower) { + fminus = zero; + } else { + assert(leftChild == index[0] || leftChild == index[1]); + if (leftChild == index[0]) { + fminus = map[0]; + } else { + fminus = map[1]; + } + } + + /* Find f= */ + middleChild = j << 1; + if (middleChild >= kTrueLower) { + fequal = one; + } else if (middleChild <= kFalseLower) { + fequal = zero; + } else { + assert(middleChild == index[0] || middleChild == index[1]); + if (middleChild == index[0]) { + fequal = map[0]; + } else { + fequal = map[1]; + } + } + + /* Find f+ */ + rightChild = (j << 1) + 1; + if (rightChild >= kTrueLower) { + fplus = one; + } else if (rightChild <= kFalseLower) { + fplus = zero; + } else { + assert(rightChild == index[0] || rightChild == index[1]); + if (rightChild == index[0]) { + fplus = map[0]; + } else { + fplus = map[1]; + } + } + + /* Build new nodes. */ + g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus); + if (g1 == NULL) { + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g1); + g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal); + if (g0 == NULL) { + Cudd_IterDerefBdd(dd, g1); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g0); + f = Cudd_bddIte(dd, x[N - i], g1, g0); + if (f == NULL) { + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(f); + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + + /* Save newly computed node in map. */ + assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex); + if (newIndex[0] == invalidIndex) { + newIndex[0] = j; + newMap[0] = f; + } else { + newIndex[1] = j; + newMap[1] = f; + } + } + + /* Copy new map to map. */ + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + map[0] = newMap[0]; + map[1] = newMap[1]; + index[0] = newIndex[0]; + index[1] = newIndex[1]; + } + + cuddDeref(f); + return(f); + +} /* end of Cudd_Inequality */ + + +/**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] + +******************************************************************************/ +DdNode * +Cudd_Disequality( + DdManager * dd /* DD manager */, + int N /* number of x and y variables */, + int c /* right-hand side constant */, + DdNode ** x /* array of x variables */, + DdNode ** y /* array of y variables */) +{ + /* The nodes at level i represent values of the difference that are + ** multiples of 2^i. We use variables with names starting with k + ** to denote the multipliers of 2^i in such multiples. */ + int kTrueLb = c + 1; + int kTrueUb = c - 1; + int kFalse = c; + /* Mask used to compute the ceiling function. Since we divide by 2^i, + ** we want to know whether the dividend is a multiple of 2^i. If it is, + ** then ceiling and floor coincide; otherwise, they differ by one. */ + int mask = 1; + int i; + + DdNode *f = NULL; /* the eventual result */ + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + + /* Two x-labeled nodes are created at most at each iteration. They are + ** stored, along with their k values, in these variables. At each level, + ** the old nodes are freed and the new nodes are copied into the old map. + */ + DdNode *map[2] = {0}; + int invalidIndex = 1 << (N-1); + int index[2] = {invalidIndex, invalidIndex}; + + /* This should never happen. */ + if (N < 0) return(NULL); + + /* If there are no bits, both operands are 0. The result depends on c. */ + if (N == 0) { + if (c != 0) return(one); + else return(zero); + } + + /* The maximum or the minimum difference comparing to c can generate the terminal case */ + if ((1 << N) - 1 < c || (-(1 << N) + 1) > c) return(one); + + /* Build the result bottom up. */ + for (i = 1; i <= N; i++) { + int kTrueLbLower, kTrueUbLower; + int leftChild, middleChild, rightChild; + DdNode *g0, *g1, *fplus, *fequal, *fminus; + int j; + DdNode *newMap[2]; + int newIndex[2]; + + kTrueLbLower = kTrueLb; + kTrueUbLower = kTrueUb; + /* kTrueLb = floor((c-1)/2^i) + 2 */ + kTrueLb = ((c-1) >> i) + 2; + /* kTrueUb = ceiling((c+1)/2^i) - 2 */ + kTrueUb = ((c+1) >> i) + (((c+2) & mask) != 1) - 2; + mask = (mask << 1) | 1; + newIndex[0] = invalidIndex; + newIndex[1] = invalidIndex; + + for (j = kTrueUb + 1; j < kTrueLb; j++) { + /* Skip if node is not reachable from top of BDD. */ + if ((j >= (1 << (N - i))) || (j <= -(1 << (N -i)))) continue; + + /* Find f- */ + leftChild = (j << 1) - 1; + if (leftChild >= kTrueLbLower || leftChild <= kTrueUbLower) { + fminus = one; + } else if (i == 1 && leftChild == kFalse) { + fminus = zero; + } else { + assert(leftChild == index[0] || leftChild == index[1]); + if (leftChild == index[0]) { + fminus = map[0]; + } else { + fminus = map[1]; + } + } + + /* Find f= */ + middleChild = j << 1; + if (middleChild >= kTrueLbLower || middleChild <= kTrueUbLower) { + fequal = one; + } else if (i == 1 && middleChild == kFalse) { + fequal = zero; + } else { + assert(middleChild == index[0] || middleChild == index[1]); + if (middleChild == index[0]) { + fequal = map[0]; + } else { + fequal = map[1]; + } + } + + /* Find f+ */ + rightChild = (j << 1) + 1; + if (rightChild >= kTrueLbLower || rightChild <= kTrueUbLower) { + fplus = one; + } else if (i == 1 && rightChild == kFalse) { + fplus = zero; + } else { + assert(rightChild == index[0] || rightChild == index[1]); + if (rightChild == index[0]) { + fplus = map[0]; + } else { + fplus = map[1]; + } + } + + /* Build new nodes. */ + g1 = Cudd_bddIte(dd, y[N - i], fequal, fplus); + if (g1 == NULL) { + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g1); + g0 = Cudd_bddIte(dd, y[N - i], fminus, fequal); + if (g0 == NULL) { + Cudd_IterDerefBdd(dd, g1); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(g0); + f = Cudd_bddIte(dd, x[N - i], g1, g0); + if (f == NULL) { + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + if (newIndex[0] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[0]); + if (newIndex[1] != invalidIndex) Cudd_IterDerefBdd(dd, newMap[1]); + return(NULL); + } + cuddRef(f); + Cudd_IterDerefBdd(dd, g1); + Cudd_IterDerefBdd(dd, g0); + + /* Save newly computed node in map. */ + assert(newIndex[0] == invalidIndex || newIndex[1] == invalidIndex); + if (newIndex[0] == invalidIndex) { + newIndex[0] = j; + newMap[0] = f; + } else { + newIndex[1] = j; + newMap[1] = f; + } + } + + /* Copy new map to map. */ + if (index[0] != invalidIndex) Cudd_IterDerefBdd(dd, map[0]); + if (index[1] != invalidIndex) Cudd_IterDerefBdd(dd, map[1]); + map[0] = newMap[0]; + map[1] = newMap[1]; + index[0] = newIndex[0]; + index[1] = newIndex[1]; + } + + cuddDeref(f); + return(f); + +} /* end of Cudd_Disequality */ + + +/**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] + +******************************************************************************/ +DdNode * +Cudd_bddInterval( + DdManager * dd /* DD manager */, + int N /* number of x variables */, + DdNode ** x /* array of x variables */, + unsigned int lowerB /* lower bound */, + unsigned int upperB /* upper bound */) +{ + DdNode *one, *zero; + DdNode *r, *rl, *ru; + int i; + + one = DD_ONE(dd); + zero = Cudd_Not(one); + + rl = one; + cuddRef(rl); + ru = one; + cuddRef(ru); + + /* Loop to build the rest of the BDDs. */ + for (i = N-1; i >= 0; i--) { + DdNode *vl, *vu; + vl = Cudd_bddIte(dd, x[i], + lowerB&1 ? rl : one, + lowerB&1 ? zero : rl); + if (vl == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(vl); + Cudd_IterDerefBdd(dd, rl); + rl = vl; + lowerB >>= 1; + vu = Cudd_bddIte(dd, x[i], + upperB&1 ? ru : zero, + upperB&1 ? one : ru); + if (vu == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(vu); + Cudd_IterDerefBdd(dd, ru); + ru = vu; + upperB >>= 1; + } + + /* Conjoin the two bounds. */ + r = Cudd_bddAnd(dd, rl, ru); + if (r == NULL) { + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + return(NULL); + } + cuddRef(r); + Cudd_IterDerefBdd(dd, rl); + Cudd_IterDerefBdd(dd, ru); + cuddDeref(r); + return(r); + +} /* end of Cudd_bddInterval */ + + +/**Function******************************************************************** + Synopsis [Computes the compatible projection of R w.r.t. cube Y.] Description [Computes the compatible projection of relation R with @@ -716,10 +1206,10 @@ Cudd_CProjection( DdNode *support; if (cuddCheckCube(dd,Y) == 0) { - (void) fprintf(dd->err, - "Error: The third argument of Cudd_CProjection should be a cube\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); + (void) fprintf(dd->err, + "Error: The third argument of Cudd_CProjection should be a cube\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); } /* Compute the support of Y, which is used by the abstraction step @@ -730,13 +1220,13 @@ Cudd_CProjection( cuddRef(support); do { - dd->reordered = 0; - res = cuddCProjectionRecur(dd,R,Y,support); + dd->reordered = 0; + res = cuddCProjectionRecur(dd,R,Y,support); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd,support); - return(NULL); + Cudd_RecursiveDeref(dd,support); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd,support); @@ -776,30 +1266,30 @@ Cudd_addHamming( cuddRef(result); for (i = 0; i < nVars; i++) { - tempBdd = Cudd_bddIte(dd,xVars[i],Cudd_Not(yVars[i]),yVars[i]); - if (tempBdd == NULL) { - Cudd_RecursiveDeref(dd,result); - return(NULL); - } - cuddRef(tempBdd); - tempAdd = Cudd_BddToAdd(dd,tempBdd); - if (tempAdd == NULL) { + tempBdd = Cudd_bddIte(dd,xVars[i],Cudd_Not(yVars[i]),yVars[i]); + if (tempBdd == NULL) { + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(tempBdd); + tempAdd = Cudd_BddToAdd(dd,tempBdd); + if (tempAdd == NULL) { + Cudd_RecursiveDeref(dd,tempBdd); + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(tempAdd); Cudd_RecursiveDeref(dd,tempBdd); - Cudd_RecursiveDeref(dd,result); - return(NULL); - } - cuddRef(tempAdd); - Cudd_RecursiveDeref(dd,tempBdd); - temp = Cudd_addApply(dd,Cudd_addPlus,tempAdd,result); - if (temp == NULL) { + temp = Cudd_addApply(dd,Cudd_addPlus,tempAdd,result); + if (temp == NULL) { + Cudd_RecursiveDeref(dd,tempAdd); + Cudd_RecursiveDeref(dd,result); + return(NULL); + } + cuddRef(temp); Cudd_RecursiveDeref(dd,tempAdd); Cudd_RecursiveDeref(dd,result); - return(NULL); - } - cuddRef(temp); - Cudd_RecursiveDeref(dd,tempAdd); - Cudd_RecursiveDeref(dd,result); - result = temp; + result = temp; } cuddDeref(result); @@ -837,7 +1327,7 @@ Cudd_MinHammingDist( table = cuddHashTableInit(dd,1,2); if (table == NULL) { - return(CUDD_OUT_OF_MEM); + return(CUDD_OUT_OF_MEM); } epsilon = Cudd_ReadEpsilon(dd); Cudd_SetEpsilon(dd,(CUDD_VALUE_TYPE)0.0); @@ -846,7 +1336,7 @@ Cudd_MinHammingDist( Cudd_SetEpsilon(dd,epsilon); return(res); - + } /* end of Cudd_MinHammingDist */ @@ -877,32 +1367,32 @@ Cudd_bddClosestCube( /* Compute the cube and distance as a single ADD. */ do { - dd->reordered = 0; - res = cuddBddClosestCube(dd,f,g,CUDD_CONST_INDEX + 1.0); + dd->reordered = 0; + res = cuddBddClosestCube(dd,f,g,CUDD_CONST_INDEX + 1.0); } while (dd->reordered == 1); if (res == NULL) return(NULL); cuddRef(res); /* Unpack distance and cube. */ do { - dd->reordered = 0; - acube = separateCube(dd, res, &rdist); + dd->reordered = 0; + acube = separateCube(dd, res, &rdist); } while (dd->reordered == 1); if (acube == NULL) { - Cudd_RecursiveDeref(dd, res); - return(NULL); + Cudd_RecursiveDeref(dd, res); + return(NULL); } cuddRef(acube); Cudd_RecursiveDeref(dd, res); /* Convert cube from ADD to BDD. */ do { - dd->reordered = 0; - res = cuddAddBddDoPattern(dd, acube); + dd->reordered = 0; + res = cuddAddBddDoPattern(dd, acube); } while (dd->reordered == 1); if (res == NULL) { - Cudd_RecursiveDeref(dd, acube); - return(NULL); + Cudd_RecursiveDeref(dd, acube); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, acube); @@ -940,8 +1430,7 @@ cuddCProjectionRecur( { DdNode *res, *res1, *res2, *resA; DdNode *r, *y, *RT, *RE, *YT, *YE, *Yrest, *Ra, *Ran, *Gamma, *Alpha; - unsigned int topR, topY, top; - unsigned int index = 0; // Suppress "might be used uninitialized" + unsigned int topR, topY, top, index; DdNode *one = DD_ONE(dd); statLine(dd); @@ -965,114 +1454,114 @@ cuddCProjectionRecur( /* Compute the cofactors of R */ if (topR == top) { - index = r->index; - RT = cuddT(r); - RE = cuddE(r); - if (r != R) { - RT = Cudd_Not(RT); RE = Cudd_Not(RE); - } + index = r->index; + RT = cuddT(r); + RE = cuddE(r); + if (r != R) { + RT = Cudd_Not(RT); RE = Cudd_Not(RE); + } } else { - RT = RE = R; + RT = RE = R; } if (topY > top) { - /* Y does not depend on the current top variable. - ** We just need to compute the results on the two cofactors of R - ** and make them the children of a node labeled r->index. - */ - res1 = cuddCProjectionRecur(dd,RT,Y,Ysupp); - if (res1 == NULL) return(NULL); - cuddRef(res1); - res2 = cuddCProjectionRecur(dd,RE,Y,Ysupp); - if (res2 == NULL) { - Cudd_RecursiveDeref(dd,res1); - return(NULL); - } - cuddRef(res2); - res = cuddBddIteRecur(dd, dd->vars[index], res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(dd,res1); - Cudd_RecursiveDeref(dd,res2); - return(NULL); - } - /* If we have reached this point, res1 and res2 are now - ** incorporated in res. cuddDeref is therefore sufficient. - */ - cuddDeref(res1); - cuddDeref(res2); - } else { - /* Compute the cofactors of Y */ - index = y->index; - YT = cuddT(y); - YE = cuddE(y); - if (y != Y) { - YT = Cudd_Not(YT); YE = Cudd_Not(YE); - } - if (YT == Cudd_Not(one)) { - Alpha = Cudd_Not(dd->vars[index]); - Yrest = YE; - Ra = RE; - Ran = RT; - } else { - Alpha = dd->vars[index]; - Yrest = YT; - Ra = RT; - Ran = RE; - } - Gamma = cuddBddExistAbstractRecur(dd,Ra,cuddT(Ysupp)); - if (Gamma == NULL) return(NULL); - if (Gamma == one) { - res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); + /* Y does not depend on the current top variable. + ** We just need to compute the results on the two cofactors of R + ** and make them the children of a node labeled r->index. + */ + res1 = cuddCProjectionRecur(dd,RT,Y,Ysupp); if (res1 == NULL) return(NULL); cuddRef(res1); - res = cuddBddAndRecur(dd, Alpha, res1); - if (res == NULL) { - Cudd_RecursiveDeref(dd,res1); - return(NULL); + res2 = cuddCProjectionRecur(dd,RE,Y,Ysupp); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); } - cuddDeref(res1); - } else if (Gamma == Cudd_Not(one)) { - res1 = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); - if (res1 == NULL) return(NULL); - cuddRef(res1); - res = cuddBddAndRecur(dd, Cudd_Not(Alpha), res1); + cuddRef(res2); + res = cuddBddIteRecur(dd, dd->vars[index], res1, res2); if (res == NULL) { - Cudd_RecursiveDeref(dd,res1); - return(NULL); + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(NULL); } + /* If we have reached this point, res1 and res2 are now + ** incorporated in res. cuddDeref is therefore sufficient. + */ cuddDeref(res1); + cuddDeref(res2); } else { - cuddRef(Gamma); - resA = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); - if (resA == NULL) { - Cudd_RecursiveDeref(dd,Gamma); - return(NULL); - } - cuddRef(resA); - res2 = cuddBddAndRecur(dd, Cudd_Not(Gamma), resA); - if (res2 == NULL) { - Cudd_RecursiveDeref(dd,Gamma); - Cudd_RecursiveDeref(dd,resA); - return(NULL); + /* Compute the cofactors of Y */ + index = y->index; + YT = cuddT(y); + YE = cuddE(y); + if (y != Y) { + YT = Cudd_Not(YT); YE = Cudd_Not(YE); } - cuddRef(res2); - Cudd_RecursiveDeref(dd,Gamma); - Cudd_RecursiveDeref(dd,resA); - res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); - if (res1 == NULL) { - Cudd_RecursiveDeref(dd,res2); - return(NULL); + if (YT == Cudd_Not(one)) { + Alpha = Cudd_Not(dd->vars[index]); + Yrest = YE; + Ra = RE; + Ran = RT; + } else { + Alpha = dd->vars[index]; + Yrest = YT; + Ra = RT; + Ran = RE; } - cuddRef(res1); - res = cuddBddIteRecur(dd, Alpha, res1, res2); - if (res == NULL) { - Cudd_RecursiveDeref(dd,res1); - Cudd_RecursiveDeref(dd,res2); - return(NULL); + Gamma = cuddBddExistAbstractRecur(dd,Ra,cuddT(Ysupp)); + if (Gamma == NULL) return(NULL); + if (Gamma == one) { + res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res = cuddBddAndRecur(dd, Alpha, res1); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddDeref(res1); + } else if (Gamma == Cudd_Not(one)) { + res1 = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); + if (res1 == NULL) return(NULL); + cuddRef(res1); + res = cuddBddAndRecur(dd, Cudd_Not(Alpha), res1); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + return(NULL); + } + cuddDeref(res1); + } else { + cuddRef(Gamma); + resA = cuddCProjectionRecur(dd,Ran,Yrest,cuddT(Ysupp)); + if (resA == NULL) { + Cudd_RecursiveDeref(dd,Gamma); + return(NULL); + } + cuddRef(resA); + res2 = cuddBddAndRecur(dd, Cudd_Not(Gamma), resA); + if (res2 == NULL) { + Cudd_RecursiveDeref(dd,Gamma); + Cudd_RecursiveDeref(dd,resA); + return(NULL); + } + cuddRef(res2); + Cudd_RecursiveDeref(dd,Gamma); + Cudd_RecursiveDeref(dd,resA); + res1 = cuddCProjectionRecur(dd,Ra,Yrest,cuddT(Ysupp)); + if (res1 == NULL) { + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + cuddRef(res1); + res = cuddBddIteRecur(dd, Alpha, res1, res2); + if (res == NULL) { + Cudd_RecursiveDeref(dd,res1); + Cudd_RecursiveDeref(dd,res2); + return(NULL); + } + cuddDeref(res1); + cuddDeref(res2); } - cuddDeref(res1); - cuddDeref(res2); - } } cuddCacheInsert2(dd,Cudd_CProjection,R,Y,res); @@ -1089,14 +1578,64 @@ cuddCProjectionRecur( Description [Performs the recursive step of Cudd_bddClosestCube. Returns the cube if succesful; NULL otherwise. The procedure uses a four-way recursion to examine all four combinations of cofactors of - f and g. The most interesting feature of this function is the - scheme used for caching the results in the global computed table. - Since we have a cube and a distance, we combine them to form an ADD. - The combination replaces the zero child of the top node of the cube - with the negative of the distance. (The use of the negative is to - avoid ambiguity with 1.) The degenerate cases (zero and one) are - treated specially because the distance is known (0 for one, and - infinity for zero).] + <code>f</code> and <code>g</code> according to the following formula. + <pre> + H(f,g) = min(H(ft,gt), H(fe,ge), H(ft,ge)+1, H(fe,gt)+1) + </pre> + Bounding is based on the following observations. + <ul> + <li> If we already found two points at distance 0, there is no point in + continuing. Furthermore, + <li> If F == not(G) then the best we can hope for is a minimum distance + of 1. If we have already found two points at distance 1, there is + no point in continuing. (Indeed, H(F,G) == 1 in this case. We + have to continue, though, to find the cube.) + </ul> + The variable <code>bound</code> is set at the largest value of the distance + that we are still interested in. Therefore, we desist when + <pre> + (bound == -1) and (F != not(G)) or (bound == 0) and (F == not(G)). + </pre> + If we were maximally aggressive in using the bound, we would always + set the bound to the minimum distance seen thus far minus one. That + is, we would maintain the invariant + <pre> + bound < minD, + </pre> + except at the very beginning, when we have no value for + <code>minD</code>.<p> + + However, we do not use <code>bound < minD</code> when examining the + two negative cofactors, because we try to find a large cube at + minimum distance. To do so, we try to find a cube in the negative + cofactors at the same or smaller distance from the cube found in the + positive cofactors.<p> + + When we compute <code>H(ft,ge)</code> and <code>H(fe,gt)</code> we + know that we are going to add 1 to the result of the recursive call + to account for the difference in the splitting variable. Therefore, + we decrease the bound correspondingly.<p> + + Another important observation concerns the need of examining all + four pairs of cofators only when both <code>f</code> and + <code>g</code> depend on the top variable.<p> + + Suppose <code>gt == ge == g</code>. (That is, <code>g</code> does + not depend on the top variable.) Then + <pre> + H(f,g) = min(H(ft,g), H(fe,g), H(ft,g)+1, H(fe,g)+1) + = min(H(ft,g), H(fe,g)) . + </pre> + Therefore, under these circumstances, we skip the two "cross" cases.<p> + + An interesting feature of this function is the scheme used for + caching the results in the global computed table. Since we have a + cube and a distance, we combine them to form an ADD. The + combination replaces the zero child of the top node of the cube with + the negative of the distance. (The use of the negative is to avoid + ambiguity with 1.) The degenerate cases (zero and one) are treated + specially because the distance is known (0 for one, and infinity for + zero).] SideEffects [None] @@ -1119,7 +1658,7 @@ cuddBddClosestCube( unsigned int topf, topg, index; statLine(dd); - if (bound < (f == Cudd_Not(g))) return(azero); + if (bound < (int)(f == Cudd_Not(g))) return(azero); /* Terminal cases. */ if (g == lzero || f == lzero) return(azero); if (f == one && g == one) return(one); @@ -1128,9 +1667,8 @@ cuddBddClosestCube( F = Cudd_Regular(f); G = Cudd_Regular(g); if (F->ref != 1 || G->ref != 1) { - res = cuddCacheLookup2(dd,(DdNode * (*)(DdManager *, DdNode *, - DdNode *)) Cudd_bddClosestCube, f, g); - if (res != NULL) return(res); + res = cuddCacheLookup2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g); + if (res != NULL) return(res); } topf = cuddI(dd,F->index); @@ -1138,27 +1676,27 @@ cuddBddClosestCube( /* Compute cofactors. */ if (topf <= topg) { - index = F->index; - ft = cuddT(F); - fe = cuddE(F); - if (Cudd_IsComplement(f)) { - ft = Cudd_Not(ft); - fe = Cudd_Not(fe); - } + index = F->index; + ft = cuddT(F); + fe = cuddE(F); + if (Cudd_IsComplement(f)) { + ft = Cudd_Not(ft); + fe = Cudd_Not(fe); + } } else { - index = G->index; - ft = fe = f; + index = G->index; + ft = fe = f; } if (topg <= topf) { - gt = cuddT(G); - ge = cuddE(G); - if (Cudd_IsComplement(g)) { - gt = Cudd_Not(gt); - ge = Cudd_Not(ge); - } + gt = cuddT(G); + ge = cuddE(G); + if (Cudd_IsComplement(g)) { + gt = Cudd_Not(gt); + ge = Cudd_Not(ge); + } } else { - gt = ge = g; + gt = ge = g; } tt = cuddBddClosestCube(dd,ft,gt,bound); @@ -1166,8 +1704,8 @@ cuddBddClosestCube( cuddRef(tt); ctt = separateCube(dd,tt,&dtt); if (ctt == NULL) { - Cudd_RecursiveDeref(dd, tt); - return(NULL); + Cudd_RecursiveDeref(dd, tt); + return(NULL); } cuddRef(ctt); Cudd_RecursiveDeref(dd, tt); @@ -1176,86 +1714,99 @@ cuddBddClosestCube( ee = cuddBddClosestCube(dd,fe,ge,bound); if (ee == NULL) { - Cudd_RecursiveDeref(dd, ctt); - return(NULL); + Cudd_RecursiveDeref(dd, ctt); + return(NULL); } cuddRef(ee); cee = separateCube(dd,ee,&dee); if (cee == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, ee); - return(NULL); + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, ee); + return(NULL); } cuddRef(cee); Cudd_RecursiveDeref(dd, ee); minD = ddMin(dtt, dee); - bound = ddMin(bound,minD-1); + if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1); if (minD > 0 && topf == topg) { - DdNode *te = cuddBddClosestCube(dd,ft,ge,bound-1); - if (te == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); - return(NULL); - } - cuddRef(te); - cte = separateCube(dd,te,&dte); - if (cte == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); + DdNode *te = cuddBddClosestCube(dd,ft,ge,bound-1); + if (te == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + return(NULL); + } + cuddRef(te); + cte = separateCube(dd,te,&dte); + if (cte == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, te); + return(NULL); + } + cuddRef(cte); Cudd_RecursiveDeref(dd, te); - return(NULL); - } - cuddRef(cte); - Cudd_RecursiveDeref(dd, te); - dte += 1.0; - minD = ddMin(minD, dte); + dte += 1.0; + minD = ddMin(minD, dte); } else { - cte = azero; - cuddRef(cte); - dte = CUDD_CONST_INDEX + 1.0; + cte = azero; + cuddRef(cte); + dte = CUDD_CONST_INDEX + 1.0; } - bound = ddMin(bound,minD-1); + if (minD <= CUDD_CONST_INDEX) bound = ddMin(bound,minD-1); if (minD > 0 && topf == topg) { - DdNode *et = cuddBddClosestCube(dd,fe,gt,bound-1); - if (et == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); - Cudd_RecursiveDeref(dd, cte); - return(NULL); - } - cuddRef(et); - cet = separateCube(dd,et,&det); - if (cet == NULL) { - Cudd_RecursiveDeref(dd, ctt); - Cudd_RecursiveDeref(dd, cee); - Cudd_RecursiveDeref(dd, cte); + DdNode *et = cuddBddClosestCube(dd,fe,gt,bound-1); + if (et == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + return(NULL); + } + cuddRef(et); + cet = separateCube(dd,et,&det); + if (cet == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, et); + return(NULL); + } + cuddRef(cet); Cudd_RecursiveDeref(dd, et); - return(NULL); - } - cuddRef(cet); - Cudd_RecursiveDeref(dd, et); - det += 1.0; - minD = ddMin(minD, det); + det += 1.0; + minD = ddMin(minD, det); } else { - cet = azero; - cuddRef(cet); - det = CUDD_CONST_INDEX + 1.0; + cet = azero; + cuddRef(cet); + det = CUDD_CONST_INDEX + 1.0; } if (minD == dtt) { - if (dtt == dee && ctt == cee) { - res = createResult(dd,CUDD_CONST_INDEX,1,ctt,dtt); - } else { - res = createResult(dd,index,1,ctt,dtt); - } + if (dtt == dee && ctt == cee) { + res = createResult(dd,CUDD_CONST_INDEX,1,ctt,dtt); + } else { + res = createResult(dd,index,1,ctt,dtt); + } } else if (minD == dee) { - res = createResult(dd,index,0,cee,dee); + res = createResult(dd,index,0,cee,dee); } else if (minD == dte) { - res = createResult(dd,index,(topf <= topg),cte,dte); +#ifdef DD_DEBUG + assert(topf == topg); +#endif + res = createResult(dd,index,1,cte,dte); } else { - res = createResult(dd,index,(topf > topg),cet,det); +#ifdef DD_DEBUG + assert(topf == topg); +#endif + res = createResult(dd,index,0,cet,det); + } + if (res == NULL) { + Cudd_RecursiveDeref(dd, ctt); + Cudd_RecursiveDeref(dd, cee); + Cudd_RecursiveDeref(dd, cte); + Cudd_RecursiveDeref(dd, cet); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd, ctt); @@ -1263,9 +1814,10 @@ cuddBddClosestCube( Cudd_RecursiveDeref(dd, cte); Cudd_RecursiveDeref(dd, cet); - if (F->ref != 1 || G->ref != 1) - cuddCacheInsert2(dd,(DdNode * (*)(DdManager *, DdNode *, - DdNode *)) Cudd_bddClosestCube, f, g, res); + /* Only cache results that are different from azero to avoid + ** storing results that depend on the value of the bound. */ + if ((F->ref != 1 || G->ref != 1) && res != azero) + cuddCacheInsert2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g, res); cuddDeref(res); return(res); @@ -1309,10 +1861,10 @@ cuddMinHammingDistRecur( DdHashTable * table, int upperBound) { - DdNode *F, *Ft, *Fe; - double h, hT, hE; - DdNode *zero, *res; - DdManager *dd = table->manager; + DdNode *F, *Ft, *Fe; + double h, hT, hE; + DdNode *zero, *res; + DdManager *dd = table->manager; statLine(dd); if (upperBound == 0) return(0); @@ -1320,49 +1872,49 @@ cuddMinHammingDistRecur( F = Cudd_Regular(f); if (cuddIsConstant(F)) { - zero = Cudd_Not(DD_ONE(dd)); - if (f == dd->background || f == zero) { - return(upperBound); - } else { - return(0); - } + zero = Cudd_Not(DD_ONE(dd)); + if (f == dd->background || f == zero) { + return(upperBound); + } else { + return(0); + } } if ((res = cuddHashTableLookup1(table,f)) != NULL) { - h = cuddV(res); - if (res->ref == 0) { - dd->dead++; - dd->constants.dead++; - } - return((int) h); + h = cuddV(res); + if (res->ref == 0) { + dd->dead++; + dd->constants.dead++; + } + return((int) h); } Ft = cuddT(F); Fe = cuddE(F); if (Cudd_IsComplement(f)) { - Ft = Cudd_Not(Ft); Fe = Cudd_Not(Fe); + Ft = Cudd_Not(Ft); Fe = Cudd_Not(Fe); } if (minterm[F->index] == 0) { - DdNode *temp = Ft; - Ft = Fe; Fe = temp; + DdNode *temp = Ft; + Ft = Fe; Fe = temp; } hT = cuddMinHammingDistRecur(Ft,minterm,table,upperBound); if (hT == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); if (hT == 0) { - hE = upperBound; + hE = upperBound; } else { - hE = cuddMinHammingDistRecur(Fe,minterm,table,upperBound - 1); - if (hE == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); + hE = cuddMinHammingDistRecur(Fe,minterm,table,upperBound - 1); + if (hE == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); } h = ddMin(hT, hE + 1); if (F->ref != 1) { - ptrint fanout = (ptrint) F->ref; - cuddSatDec(fanout); - res = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) h); - if (!cuddHashTableInsert1(table,f,res,fanout)) { - cuddRef(res); Cudd_RecursiveDeref(dd, res); - return(CUDD_OUT_OF_MEM); - } + ptrint fanout = (ptrint) F->ref; + cuddSatDec(fanout); + res = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) h); + if (!cuddHashTableInsert1(table,f,res,fanout)) { + cuddRef(res); Cudd_RecursiveDeref(dd, res); + return(CUDD_OUT_OF_MEM); + } } return((int) h); @@ -1392,9 +1944,9 @@ separateCube( /* One and zero are special cases because the distance is implied. */ if (Cudd_IsConstant(f)) { - *distance = (f == DD_ONE(dd)) ? 0.0 : - (1.0 + (CUDD_VALUE_TYPE) CUDD_CONST_INDEX); - return(f); + *distance = (f == DD_ONE(dd)) ? 0.0 : + (1.0 + (CUDD_VALUE_TYPE) CUDD_CONST_INDEX); + return(f); } /* Find out which branch points to the distance and replace the top @@ -1402,16 +1954,16 @@ separateCube( t = cuddT(f); if (Cudd_IsConstant(t) && cuddV(t) <= 0) { #ifdef DD_DEBUG - assert(!Cudd_IsConstant(cuddE(f)) || cuddE(f) == DD_ONE(dd)); + assert(!Cudd_IsConstant(cuddE(f)) || cuddE(f) == DD_ONE(dd)); #endif - *distance = -cuddV(t); - cube = cuddUniqueInter(dd, f->index, DD_ZERO(dd), cuddE(f)); + *distance = -cuddV(t); + cube = cuddUniqueInter(dd, f->index, DD_ZERO(dd), cuddE(f)); } else { #ifdef DD_DEBUG - assert(!Cudd_IsConstant(t) || t == DD_ONE(dd)); + assert(!Cudd_IsConstant(t) || t == DD_ONE(dd)); #endif - *distance = -cuddV(cuddE(f)); - cube = cuddUniqueInter(dd, f->index, t, DD_ZERO(dd)); + *distance = -cuddV(cuddE(f)); + cube = cuddUniqueInter(dd, f->index, t, DD_ZERO(dd)); } return(cube); @@ -1443,7 +1995,7 @@ createResult( /* Special case. The cube is either one or zero, and we do not ** add any variables. Hence, the result is also one or zero, - ** and the distance remains implied by teh value of the constant. */ + ** and the distance remains implied by the value of the constant. */ if (index == CUDD_CONST_INDEX && Cudd_IsConstant(cube)) return(cube); constant = cuddUniqueConst(dd,-distance); @@ -1451,31 +2003,33 @@ createResult( cuddRef(constant); if (index == CUDD_CONST_INDEX) { - /* Replace the top node. */ - if (cuddT(cube) == DD_ZERO(dd)) { - res = cuddUniqueInter(dd,cube->index,constant,cuddE(cube)); - } else { - res = cuddUniqueInter(dd,cube->index,cuddT(cube),constant); - } + /* Replace the top node. */ + if (cuddT(cube) == DD_ZERO(dd)) { + res = cuddUniqueInter(dd,cube->index,constant,cuddE(cube)); + } else { + res = cuddUniqueInter(dd,cube->index,cuddT(cube),constant); + } } else { - /* Add a new top node. */ + /* Add a new top node. */ #ifdef DD_DEBUG - assert(cuddI(dd,index) < cuddI(dd,cube->index)); + assert(cuddI(dd,index) < cuddI(dd,cube->index)); #endif - if (phase) { - res = cuddUniqueInter(dd,index,cube,constant); - } else { - res = cuddUniqueInter(dd,index,constant,cube); - } + if (phase) { + res = cuddUniqueInter(dd,index,cube,constant); + } else { + res = cuddUniqueInter(dd,index,constant,cube); + } } if (res == NULL) { - Cudd_RecursiveDeref(dd, constant); - return(NULL); + Cudd_RecursiveDeref(dd, constant); + return(NULL); } cuddDeref(constant); /* safe because constant is part of res */ return(res); } /* end of createResult */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddRead.c b/src/bdd/cudd/cuddRead.c index 52670a6c..06789589 100644 --- a/src/bdd/cudd/cuddRead.c +++ b/src/bdd/cudd/cuddRead.c @@ -7,19 +7,46 @@ Synopsis [Functions to read in a matrix] Description [External procedures included in this module: - <ul> - <li> Cudd_addRead() - <li> Cudd_bddRead() - </ul>] + <ul> + <li> Cudd_addRead() + <li> Cudd_bddRead() + </ul>] SeeAlso [cudd_addHarwell.c] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -30,6 +57,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -50,7 +78,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddRead.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddRead.c,v 1.6 2004/08/13 18:04:50 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -145,85 +173,85 @@ Cudd_addRead( err = fscanf(fp, "%d %d", &u, &v); if (err == EOF) { - return(0); + return(0); } else if (err != 2) { - return(0); + return(0); } *m = u; /* Compute the number of x variables. */ lx = *x; lxn = *xn; - u--; /* row and column numbers start from 0 */ + u--; /* row and column numbers start from 0 */ for (lnx=0; u > 0; lnx++) { - u >>= 1; + u >>= 1; } - /* Here we rely on the fact that ABC_REALLOC of a null pointer is - ** translates to an ABC_ALLOC. + /* Here we rely on the fact that REALLOC of a null pointer is + ** translates to an ALLOC. */ if (lnx > *nx) { - *x = lx = ABC_REALLOC(DdNode *, *x, lnx); - if (lx == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - *xn = lxn = ABC_REALLOC(DdNode *, *xn, lnx); - if (lxn == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } + *x = lx = ABC_REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *xn = lxn = ABC_REALLOC(DdNode *, *xn, lnx); + if (lxn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } } *n = v; /* Compute the number of y variables. */ ly = *y; lyn = *yn_; - v--; /* row and column numbers start from 0 */ + v--; /* row and column numbers start from 0 */ for (lny=0; v > 0; lny++) { - v >>= 1; + v >>= 1; } - /* Here we rely on the fact that ABC_REALLOC of a null pointer is - ** translates to an ABC_ALLOC. + /* Here we rely on the fact that REALLOC of a null pointer is + ** translates to an ALLOC. */ if (lny > *ny) { - *y = ly = ABC_REALLOC(DdNode *, *y, lny); - if (ly == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } - *yn_ = lyn = ABC_REALLOC(DdNode *, *yn_, lny); - if (lyn == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } + *y = ly = ABC_REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } + *yn_ = lyn = ABC_REALLOC(DdNode *, *yn_, lny); + if (lyn == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } } /* Create all new variables. */ for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) { - do { - dd->reordered = 0; - lx[i] = cuddUniqueInter(dd, nv, one, zero); - } while (dd->reordered == 1); - if (lx[i] == NULL) return(0); + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); cuddRef(lx[i]); - do { - dd->reordered = 0; - lxn[i] = cuddUniqueInter(dd, nv, zero, one); - } while (dd->reordered == 1); - if (lxn[i] == NULL) return(0); + do { + dd->reordered = 0; + lxn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lxn[i] == NULL) return(0); cuddRef(lxn[i]); } for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) { - do { - dd->reordered = 0; - ly[i] = cuddUniqueInter(dd, nv, one, zero); - } while (dd->reordered == 1); - if (ly[i] == NULL) return(0); - cuddRef(ly[i]); - do { - dd->reordered = 0; - lyn[i] = cuddUniqueInter(dd, nv, zero, one); - } while (dd->reordered == 1); - if (lyn[i] == NULL) return(0); - cuddRef(lyn[i]); + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); + do { + dd->reordered = 0; + lyn[i] = cuddUniqueInter(dd, nv, zero, one); + } while (dd->reordered == 1); + if (lyn[i] == NULL) return(0); + cuddRef(lyn[i]); } *nx = lnx; *ny = lny; @@ -232,69 +260,69 @@ Cudd_addRead( cuddRef(*E); while (! feof(fp)) { - err = fscanf(fp, "%d %d %lf", &u, &v, &val); - if (err == EOF) { - break; - } else if (err != 3) { - return(0); - } else if (u >= *m || v >= *n || u < 0 || v < 0) { - return(0); - } + err = fscanf(fp, "%d %d %lf", &u, &v, &val); + if (err == EOF) { + break; + } else if (err != 3) { + return(0); + } else if (u >= *m || v >= *n || u < 0 || v < 0) { + return(0); + } - minterm1 = one; cuddRef(minterm1); - - /* Build minterm1 corresponding to this arc */ - for (i = lnx - 1; i>=0; i--) { - if (u & 1) { - w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lx[i]); - } else { - w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lxn[i]); + minterm1 = one; cuddRef(minterm1); + + /* Build minterm1 corresponding to this arc */ + for (i = lnx - 1; i>=0; i--) { + if (u & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lx[i]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lxn[i]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + u >>= 1; } - if (w == NULL) { - Cudd_RecursiveDeref(dd, minterm1); - return(0); + for (i = lny - 1; i>=0; i--) { + if (v & 1) { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, ly[i]); + } else { + w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lyn[i]); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + v >>= 1; } - cuddRef(w); - Cudd_RecursiveDeref(dd, minterm1); - minterm1 = w; - u >>= 1; - } - for (i = lny - 1; i>=0; i--) { - if (v & 1) { - w = Cudd_addApply(dd, Cudd_addTimes, minterm1, ly[i]); - } else { - w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lyn[i]); + /* Create new constant node if necessary. + ** This call will never cause reordering. + */ + neW = cuddUniqueConst(dd, val); + if (neW == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); } + cuddRef(neW); + + w = Cudd_addIte(dd, minterm1, neW, *E); if (w == NULL) { - Cudd_RecursiveDeref(dd, minterm1); - return(0); + Cudd_RecursiveDeref(dd, minterm1); + Cudd_RecursiveDeref(dd, neW); + return(0); } cuddRef(w); Cudd_RecursiveDeref(dd, minterm1); - minterm1 = w; - v >>= 1; - } - /* Create new constant node if necessary. - ** This call will never cause reordering. - */ - neW = cuddUniqueConst(dd, val); - if (neW == NULL) { - Cudd_RecursiveDeref(dd, minterm1); - return(0); - } - cuddRef(neW); - - w = Cudd_addIte(dd, minterm1, neW, *E); - if (w == NULL) { - Cudd_RecursiveDeref(dd, minterm1); Cudd_RecursiveDeref(dd, neW); - return(0); - } - cuddRef(w); - Cudd_RecursiveDeref(dd, minterm1); - Cudd_RecursiveDeref(dd, neW); - Cudd_RecursiveDeref(dd, *E); - *E = w; + Cudd_RecursiveDeref(dd, *E); + *E = w; } return(1); @@ -365,57 +393,57 @@ Cudd_bddRead( err = fscanf(fp, "%d %d", &u, &v); if (err == EOF) { - return(0); + return(0); } else if (err != 2) { - return(0); + return(0); } *m = u; /* Compute the number of x variables. */ lx = *x; - u--; /* row and column numbers start from 0 */ + u--; /* row and column numbers start from 0 */ for (lnx=0; u > 0; lnx++) { - u >>= 1; + u >>= 1; } if (lnx > *nx) { - *x = lx = ABC_REALLOC(DdNode *, *x, lnx); - if (lx == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } + *x = lx = ABC_REALLOC(DdNode *, *x, lnx); + if (lx == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } } *n = v; /* Compute the number of y variables. */ ly = *y; - v--; /* row and column numbers start from 0 */ + v--; /* row and column numbers start from 0 */ for (lny=0; v > 0; lny++) { - v >>= 1; + v >>= 1; } if (lny > *ny) { - *y = ly = ABC_REALLOC(DdNode *, *y, lny); - if (ly == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); - } + *y = ly = ABC_REALLOC(DdNode *, *y, lny); + if (ly == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(0); + } } /* Create all new variables. */ for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) { - do { - dd->reordered = 0; - lx[i] = cuddUniqueInter(dd, nv, one, zero); - } while (dd->reordered == 1); - if (lx[i] == NULL) return(0); + do { + dd->reordered = 0; + lx[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (lx[i] == NULL) return(0); cuddRef(lx[i]); } for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) { - do { - dd->reordered = 0; - ly[i] = cuddUniqueInter(dd, nv, one, zero); - } while (dd->reordered == 1); - if (ly[i] == NULL) return(0); - cuddRef(ly[i]); + do { + dd->reordered = 0; + ly[i] = cuddUniqueInter(dd, nv, one, zero); + } while (dd->reordered == 1); + if (ly[i] == NULL) return(0); + cuddRef(ly[i]); } *nx = lnx; *ny = lny; @@ -424,59 +452,59 @@ Cudd_bddRead( cuddRef(*E); while (! feof(fp)) { - err = fscanf(fp, "%d %d", &u, &v); - if (err == EOF) { - break; - } else if (err != 2) { - return(0); - } else if (u >= *m || v >= *n || u < 0 || v < 0) { - return(0); - } - - minterm1 = one; cuddRef(minterm1); - - /* Build minterm1 corresponding to this arc. */ - for (i = lnx - 1; i>=0; i--) { - if (u & 1) { - w = Cudd_bddAnd(dd, minterm1, lx[i]); - } else { - w = Cudd_bddAnd(dd, minterm1, Cudd_Not(lx[i])); + err = fscanf(fp, "%d %d", &u, &v); + if (err == EOF) { + break; + } else if (err != 2) { + return(0); + } else if (u >= *m || v >= *n || u < 0 || v < 0) { + return(0); } - if (w == NULL) { - Cudd_RecursiveDeref(dd, minterm1); - return(0); + + minterm1 = one; cuddRef(minterm1); + + /* Build minterm1 corresponding to this arc. */ + for (i = lnx - 1; i>=0; i--) { + if (u & 1) { + w = Cudd_bddAnd(dd, minterm1, lx[i]); + } else { + w = Cudd_bddAnd(dd, minterm1, Cudd_Not(lx[i])); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd,minterm1); + minterm1 = w; + u >>= 1; } - cuddRef(w); - Cudd_RecursiveDeref(dd,minterm1); - minterm1 = w; - u >>= 1; - } - for (i = lny - 1; i>=0; i--) { - if (v & 1) { - w = Cudd_bddAnd(dd, minterm1, ly[i]); - } else { - w = Cudd_bddAnd(dd, minterm1, Cudd_Not(ly[i])); + for (i = lny - 1; i>=0; i--) { + if (v & 1) { + w = Cudd_bddAnd(dd, minterm1, ly[i]); + } else { + w = Cudd_bddAnd(dd, minterm1, Cudd_Not(ly[i])); + } + if (w == NULL) { + Cudd_RecursiveDeref(dd, minterm1); + return(0); + } + cuddRef(w); + Cudd_RecursiveDeref(dd, minterm1); + minterm1 = w; + v >>= 1; } + + w = Cudd_bddAnd(dd, Cudd_Not(minterm1), Cudd_Not(*E)); if (w == NULL) { - Cudd_RecursiveDeref(dd, minterm1); - return(0); + Cudd_RecursiveDeref(dd, minterm1); + return(0); } + w = Cudd_Not(w); cuddRef(w); Cudd_RecursiveDeref(dd, minterm1); - minterm1 = w; - v >>= 1; - } - - w = Cudd_bddAnd(dd, Cudd_Not(minterm1), Cudd_Not(*E)); - if (w == NULL) { - Cudd_RecursiveDeref(dd, minterm1); - return(0); - } - w = Cudd_Not(w); - cuddRef(w); - Cudd_RecursiveDeref(dd, minterm1); - Cudd_RecursiveDeref(dd, *E); - *E = w; + Cudd_RecursiveDeref(dd, *E); + *E = w; } return(1); @@ -491,5 +519,7 @@ Cudd_bddRead( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddRef.c b/src/bdd/cudd/cuddRef.c index a8f654af..183d30ca 100644 --- a/src/bdd/cudd/cuddRef.c +++ b/src/bdd/cudd/cuddRef.c @@ -7,43 +7,71 @@ Synopsis [Functions that manipulate the reference counts.] Description [External procedures included in this module: - <ul> - <li> Cudd_Ref() - <li> Cudd_RecursiveDeref() - <li> Cudd_IterDerefBdd() - <li> Cudd_DelayedDerefBdd() - <li> Cudd_RecursiveDerefZdd() - <li> Cudd_Deref() - <li> Cudd_CheckZeroRef() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddReclaim() - <li> cuddReclaimZdd() - <li> cuddClearDeathRow() - <li> cuddShrinkDeathRow() - <li> cuddIsInDeathRow() - <li> cuddTimesInDeathRow() - </ul> - ] + <ul> + <li> Cudd_Ref() + <li> Cudd_RecursiveDeref() + <li> Cudd_IterDerefBdd() + <li> Cudd_DelayedDerefBdd() + <li> Cudd_RecursiveDerefZdd() + <li> Cudd_Deref() + <li> Cudd_CheckZeroRef() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddReclaim() + <li> cuddReclaimZdd() + <li> cuddClearDeathRow() + <li> cuddShrinkDeathRow() + <li> cuddIsInDeathRow() + <li> cuddTimesInDeathRow() + </ul> + ] SeeAlso [] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -64,7 +92,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddRef.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddRef.c,v 1.28 2004/08/13 18:04:50 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -134,35 +162,35 @@ Cudd_RecursiveDeref( unsigned int live = table->keys - table->dead; if (live > table->peakLiveNodes) { - table->peakLiveNodes = live; + table->peakLiveNodes = live; } N = Cudd_Regular(n); do { #ifdef DD_DEBUG - assert(N->ref != 0); + assert(N->ref != 0); #endif - if (N->ref == 1) { - N->ref = 0; - table->dead++; + if (N->ref == 1) { + N->ref = 0; + table->dead++; #ifdef DD_STATS - table->nodesDropped++; + table->nodesDropped++; #endif - if (cuddIsConstant(N)) { - table->constants.dead++; - N = stack[--SP]; + if (cuddIsConstant(N)) { + table->constants.dead++; + N = stack[--SP]; + } else { + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } } else { - ord = table->perm[N->index]; - stack[SP++] = Cudd_Regular(cuddE(N)); - table->subtables[ord].dead++; - N = cuddT(N); + cuddSatDec(N->ref); + N = stack[--SP]; } - } else { - cuddSatDec(N->ref); - N = stack[--SP]; - } } while (SP != 0); } /* end of Cudd_RecursiveDeref */ @@ -197,30 +225,30 @@ Cudd_IterDerefBdd( unsigned int live = table->keys - table->dead; if (live > table->peakLiveNodes) { - table->peakLiveNodes = live; + table->peakLiveNodes = live; } N = Cudd_Regular(n); do { #ifdef DD_DEBUG - assert(N->ref != 0); + assert(N->ref != 0); #endif - if (N->ref == 1) { - N->ref = 0; - table->dead++; + if (N->ref == 1) { + N->ref = 0; + table->dead++; #ifdef DD_STATS - table->nodesDropped++; + table->nodesDropped++; #endif - ord = table->perm[N->index]; - stack[SP++] = Cudd_Regular(cuddE(N)); - table->subtables[ord].dead++; - N = cuddT(N); - } else { - cuddSatDec(N->ref); - N = stack[--SP]; - } + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } } while (SP != 0); } /* end of Cudd_IterDerefBdd */ @@ -254,7 +282,7 @@ Cudd_DelayedDerefBdd( unsigned int live = table->keys - table->dead; if (live > table->peakLiveNodes) { - table->peakLiveNodes = live; + table->peakLiveNodes = live; } n = Cudd_Regular(n); @@ -267,10 +295,10 @@ Cudd_DelayedDerefBdd( #else if (cuddIsConstant(n) || n->ref > 1) { #ifdef DD_DEBUG - assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table))); + assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table))); #endif - cuddSatDec(n->ref); - return; + cuddSatDec(n->ref); + return; } N = table->deathRow[table->nextDead]; @@ -278,29 +306,29 @@ Cudd_DelayedDerefBdd( if (N != NULL) { #endif #ifdef DD_DEBUG - assert(!Cudd_IsComplement(N)); + assert(!Cudd_IsComplement(N)); #endif - stack = table->stack; - SP = 1; - do { + stack = table->stack; + SP = 1; + do { #ifdef DD_DEBUG - assert(N->ref != 0); + assert(N->ref != 0); #endif - if (N->ref == 1) { - N->ref = 0; - table->dead++; + if (N->ref == 1) { + N->ref = 0; + table->dead++; #ifdef DD_STATS - table->nodesDropped++; + table->nodesDropped++; #endif - ord = table->perm[N->index]; - stack[SP++] = Cudd_Regular(cuddE(N)); - table->subtables[ord].dead++; - N = cuddT(N); - } else { - cuddSatDec(N->ref); - N = stack[--SP]; - } - } while (SP != 0); + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead++; + N = cuddT(N); + } else { + cuddSatDec(N->ref); + N = stack[--SP]; + } + } while (SP != 0); #ifndef DD_NO_DEATH_ROW } table->deathRow[table->nextDead] = n; @@ -310,29 +338,29 @@ Cudd_DelayedDerefBdd( table->nextDead &= table->deadMask; #if 0 if (table->nextDead == table->deathRowDepth) { - if (table->deathRowDepth < table->looseUpTo / 2) { -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long) = MMoutOfMemory; - DdNodePtr *newRow; - MMoutOfMemory = Cudd_OutOfMem; - newRow = ABC_REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth); - MMoutOfMemory = saveHandler; - if (newRow == NULL) { - table->nextDead = 0; + if (table->deathRowDepth < table->looseUpTo / 2) { + extern void (*MMoutOfMemory)(long); + void (*saveHandler)(long) = MMoutOfMemory; + DdNodePtr *newRow; + MMoutOfMemory = Cudd_OutOfMem; + newRow = ABC_REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth); + MMoutOfMemory = saveHandler; + if (newRow == NULL) { + table->nextDead = 0; + } else { + int i; + table->memused += table->deathRowDepth; + i = table->deathRowDepth; + table->deathRowDepth <<= 1; + for (; i < table->deathRowDepth; i++) { + newRow[i] = NULL; + } + table->deadMask = table->deathRowDepth - 1; + table->deathRow = newRow; + } } else { - int i; - table->memused += table->deathRowDepth; - i = table->deathRowDepth; - table->deathRowDepth <<= 1; - for (; i < table->deathRowDepth; i++) { - newRow[i] = NULL; + table->nextDead = 0; } - table->deadMask = table->deathRowDepth - 1; - table->deathRow = newRow; - } - } else { - table->nextDead = 0; - } } #endif #endif @@ -367,26 +395,26 @@ Cudd_RecursiveDerefZdd( do { #ifdef DD_DEBUG - assert(N->ref != 0); + assert(N->ref != 0); #endif - cuddSatDec(N->ref); + cuddSatDec(N->ref); - if (N->ref == 0) { - table->deadZ++; + if (N->ref == 0) { + table->deadZ++; #ifdef DD_STATS - table->nodesDropped++; + table->nodesDropped++; #endif #ifdef DD_DEBUG - assert(!cuddIsConstant(N)); + assert(!cuddIsConstant(N)); #endif - ord = table->permZ[N->index]; - stack[SP++] = cuddE(N); - table->subtableZ[ord].dead++; - N = cuddT(N); - } else { - N = stack[--SP]; - } + ord = table->permZ[N->index]; + stack[SP++] = cuddE(N); + table->subtableZ[ord].dead++; + N = cuddT(N); + } else { + N = stack[--SP]; + } } while (SP != 0); } /* end of Cudd_RecursiveDerefZdd */ @@ -440,7 +468,7 @@ Cudd_CheckZeroRef( { int size; int i, j; - int remain; /* the expected number of remaining references to one */ + int remain; /* the expected number of remaining references to one */ DdNodePtr *nodelist; DdNode *node; DdNode *sentinel = &(manager->sentinel); @@ -455,53 +483,53 @@ Cudd_CheckZeroRef( /* First look at the BDD/ADD subtables. */ remain = 1; /* reference from the manager */ size = manager->size; - remain += 2 * size; /* reference from the BDD projection functions */ + remain += 2 * size; /* reference from the BDD projection functions */ for (i = 0; i < size; i++) { - subtable = &(manager->subtables[i]); - nodelist = subtable->nodelist; - for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - while (node != sentinel) { - if (node->ref != 0 && node->ref != DD_MAXREF) { - index = (int) node->index; - if (node != manager->vars[index]) { - count++; - } else { - if (node->ref != 1) { - count++; - } + subtable = &(manager->subtables[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + while (node != sentinel) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + index = (int) node->index; + if (node != manager->vars[index]) { + count++; + } else { + if (node->ref != 1) { + count++; + } + } + } + node = node->next; } } - node = node->next; - } - } } /* Then look at the ZDD subtables. */ size = manager->sizeZ; if (size) /* references from ZDD universe */ - remain += 2; + remain += 2; for (i = 0; i < size; i++) { - subtable = &(manager->subtableZ[i]); - nodelist = subtable->nodelist; - for (j = 0; (unsigned) j < subtable->slots; j++) { - node = nodelist[j]; - while (node != NULL) { - if (node->ref != 0 && node->ref != DD_MAXREF) { - index = (int) node->index; - if (node == manager->univ[manager->permZ[index]]) { - if (node->ref > 2) { - count++; - } - } else { - count++; + subtable = &(manager->subtableZ[i]); + nodelist = subtable->nodelist; + for (j = 0; (unsigned) j < subtable->slots; j++) { + node = nodelist[j]; + while (node != NULL) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + index = (int) node->index; + if (node == manager->univ[manager->permZ[index]]) { + if (node->ref > 2) { + count++; + } + } else { + count++; + } + } + node = node->next; } } - node = node->next; - } - } } /* Now examine the constant table. Plusinfinity, minusinfinity, and @@ -511,25 +539,25 @@ Cudd_CheckZeroRef( */ nodelist = manager->constants.nodelist; for (j = 0; (unsigned) j < manager->constants.slots; j++) { - node = nodelist[j]; - while (node != NULL) { - if (node->ref != 0 && node->ref != DD_MAXREF) { - if (node == manager->one) { - if ((int) node->ref != remain) { - count++; - } - } else if (node == manager->zero || - node == manager->plusinfinity || - node == manager->minusinfinity) { - if (node->ref != 1) { - count++; + node = nodelist[j]; + while (node != NULL) { + if (node->ref != 0 && node->ref != DD_MAXREF) { + if (node == manager->one) { + if ((int) node->ref != remain) { + count++; + } + } else if (node == manager->zero || + node == manager->plusinfinity || + node == manager->minusinfinity) { + if (node->ref != 1) { + count++; + } + } else { + count++; + } } - } else { - count++; - } + node = node->next; } - node = node->next; - } } return(count); @@ -570,22 +598,22 @@ cuddReclaim( #endif do { - if (N->ref == 0) { - N->ref = 1; - table->dead--; - if (cuddIsConstant(N)) { - table->constants.dead--; - N = stack[--SP]; + if (N->ref == 0) { + N->ref = 1; + table->dead--; + if (cuddIsConstant(N)) { + table->constants.dead--; + N = stack[--SP]; + } else { + ord = table->perm[N->index]; + stack[SP++] = Cudd_Regular(cuddE(N)); + table->subtables[ord].dead--; + N = cuddT(N); + } } else { - ord = table->perm[N->index]; - stack[SP++] = Cudd_Regular(cuddE(N)); - table->subtables[ord].dead--; - N = cuddT(N); + cuddSatInc(N->ref); + N = stack[--SP]; } - } else { - cuddSatInc(N->ref); - N = stack[--SP]; - } } while (SP != 0); N = Cudd_Regular(n); @@ -623,21 +651,21 @@ cuddReclaimZdd( #endif do { - cuddSatInc(N->ref); + cuddSatInc(N->ref); - if (N->ref == 1) { - table->deadZ--; - table->reclaimed++; + if (N->ref == 1) { + table->deadZ--; + table->reclaimed++; #ifdef DD_DEBUG - assert(!cuddIsConstant(N)); + assert(!cuddIsConstant(N)); #endif - ord = table->permZ[N->index]; - stack[SP++] = cuddE(N); - table->subtableZ[ord].dead--; - N = cuddT(N); - } else { - N = stack[--SP]; - } + ord = table->permZ[N->index]; + stack[SP++] = cuddE(N); + table->subtableZ[ord].dead--; + N = cuddT(N); + } else { + N = stack[--SP]; + } } while (SP != 0); cuddSatDec(n->ref); @@ -664,18 +692,18 @@ cuddShrinkDeathRow( int i; if (table->deathRowDepth > 3) { - for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) { - if (table->deathRow[i] == NULL) break; - Cudd_IterDerefBdd(table,table->deathRow[i]); - table->deathRow[i] = NULL; - } - table->deathRowDepth /= 4; - table->deadMask = table->deathRowDepth - 2; - if ((unsigned) table->nextDead > table->deadMask) { - table->nextDead = 0; - } - table->deathRow = ABC_REALLOC(DdNodePtr, table->deathRow, - table->deathRowDepth); + for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) { + if (table->deathRow[i] == NULL) break; + Cudd_IterDerefBdd(table,table->deathRow[i]); + table->deathRow[i] = NULL; + } + table->deathRowDepth /= 4; + table->deadMask = table->deathRowDepth - 1; + if ((unsigned) table->nextDead > table->deadMask) { + table->nextDead = 0; + } + table->deathRow = ABC_REALLOC(DdNodePtr, table->deathRow, + table->deathRowDepth); } #endif @@ -702,13 +730,13 @@ cuddClearDeathRow( int i; for (i = 0; i < table->deathRowDepth; i++) { - if (table->deathRow[i] == NULL) break; - Cudd_IterDerefBdd(table,table->deathRow[i]); - table->deathRow[i] = NULL; + if (table->deathRow[i] == NULL) break; + Cudd_IterDerefBdd(table,table->deathRow[i]); + table->deathRow[i] = NULL; } #ifdef DD_DEBUG for (; i < table->deathRowDepth; i++) { - assert(table->deathRow[i] == NULL); + assert(table->deathRow[i] == NULL); } #endif table->nextDead = 0; @@ -739,9 +767,9 @@ cuddIsInDeathRow( int i; for (i = 0; i < dd->deathRowDepth; i++) { - if (f == dd->deathRow[i]) { - return(i); - } + if (f == dd->deathRow[i]) { + return(i); + } } #endif @@ -771,7 +799,7 @@ cuddTimesInDeathRow( int i; for (i = 0; i < dd->deathRowDepth; i++) { - count += f == dd->deathRow[i]; + count += f == dd->deathRow[i]; } #endif @@ -782,5 +810,7 @@ cuddTimesInDeathRow( /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddReorder.c b/src/bdd/cudd/cuddReorder.c index 020a1b5e..383be18a 100644 --- a/src/bdd/cudd/cuddReorder.c +++ b/src/bdd/cudd/cuddReorder.c @@ -7,41 +7,68 @@ Synopsis [Functions for dynamic variable reordering.] Description [External procedures included in this file: - <ul> - <li> Cudd_ReduceHeap() - <li> Cudd_ShuffleHeap() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddDynamicAllocNode() - <li> cuddSifting() - <li> cuddSwapping() - <li> cuddNextHigh() - <li> cuddNextLow() - <li> cuddSwapInPlace() - <li> cuddBddAlignToZdd() - </ul> - Static procedures included in this module: - <ul> - <li> ddUniqueCompare() - <li> ddSwapAny() - <li> ddSiftingAux() - <li> ddSiftingUp() - <li> ddSiftingDown() - <li> ddSiftingBackward() - <li> ddReorderPreprocess() - <li> ddReorderPostprocess() - <li> ddShuffle() - <li> ddSiftUp() - <li> bddFixTree() - </ul>] + <ul> + <li> Cudd_ReduceHeap() + <li> Cudd_ShuffleHeap() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddDynamicAllocNode() + <li> cuddSifting() + <li> cuddSwapping() + <li> cuddNextHigh() + <li> cuddNextLow() + <li> cuddSwapInPlace() + <li> cuddBddAlignToZdd() + </ul> + Static procedures included in this module: + <ul> + <li> ddUniqueCompare() + <li> ddSwapAny() + <li> ddSiftingAux() + <li> ddSiftingUp() + <li> ddSiftingDown() + <li> ddSiftingBackward() + <li> ddReorderPreprocess() + <li> ddReorderPostprocess() + <li> ddShuffle() + <li> ddSiftUp() + <li> bddFixTree() + </ul>] Author [Shipra Panda, Bernard Plessier, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -51,6 +78,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -71,14 +99,14 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddReorder.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddReorder.c,v 1.69 2009/02/21 18:24:10 fabio Exp $"; #endif -static int *entry; +static int *entry; -int ddTotalNumberSwapping; +int ddTotalNumberSwapping; #ifdef DD_STATS -int ddTotalNISwaps; +int ddTotalNISwaps; #endif /*---------------------------------------------------------------------------*/ @@ -91,19 +119,19 @@ int ddTotalNISwaps; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int ddUniqueCompare ARGS((int *ptrX, int *ptrY)); -static Move * ddSwapAny ARGS((DdManager *table, int x, int y)); -static int ddSiftingAux ARGS((DdManager *table, int x, int xLow, int xHigh)); -static Move * ddSiftingUp ARGS((DdManager *table, int y, int xLow)); -static Move * ddSiftingDown ARGS((DdManager *table, int x, int xHigh)); -static int ddSiftingBackward ARGS((DdManager *table, int size, Move *moves)); -static int ddReorderPreprocess ARGS((DdManager *table)); -static int ddReorderPostprocess ARGS((DdManager *table)); -static int ddShuffle ARGS((DdManager *table, int *permutation)); -static int ddSiftUp ARGS((DdManager *table, int x, int xLow)); -static void bddFixTree ARGS((DdManager *table, MtrNode *treenode)); -static int ddUpdateMtrTree ARGS((DdManager *table, MtrNode *treenode, int *perm, int *invperm)); -static int ddCheckPermuation ARGS((DdManager *table, MtrNode *treenode, int *perm, int *invperm)); +static int ddUniqueCompare (int *ptrX, int *ptrY); +static Move * ddSwapAny (DdManager *table, int x, int y); +static int ddSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddSiftingUp (DdManager *table, int y, int xLow); +static Move * ddSiftingDown (DdManager *table, int x, int xHigh); +static int ddSiftingBackward (DdManager *table, int size, Move *moves); +static int ddReorderPreprocess (DdManager *table); +static int ddReorderPostprocess (DdManager *table); +static int ddShuffle (DdManager *table, int *permutation); +static int ddSiftUp (DdManager *table, int x, int xLow); +static void bddFixTree (DdManager *table, MtrNode *treenode); +static int ddUpdateMtrTree (DdManager *table, MtrNode *treenode, int *perm, int *invperm); +static int ddCheckPermuation (DdManager *table, MtrNode *treenode, int *perm, int *invperm); /**AutomaticEnd***************************************************************/ @@ -151,24 +179,23 @@ Cudd_ReduceHeap( int minsize /* bound below which no reordering occurs */) { DdHook *hook; - int result; + int result; unsigned int nextDyn; #ifdef DD_STATS unsigned int initialSize; unsigned int finalSize; #endif long localTime; - int TimeStop = table->TimeStop; /* Don't reorder if there are too many dead nodes. */ if (table->keys - table->dead < (unsigned) minsize) - return(1); + return(1); if (heuristic == CUDD_REORDER_SAME) { - heuristic = table->autoMethod; + heuristic = table->autoMethod; } if (heuristic == CUDD_REORDER_NONE) { - return(1); + return(1); } /* This call to Cudd_ReduceHeap does initiate reordering. Therefore @@ -181,16 +208,16 @@ Cudd_ReduceHeap( /* Run the hook functions. */ hook = table->preReorderingHook; while (hook != NULL) { - int res = (hook->f)(table, "BDD", (void *)heuristic); - if (res == 0) return(0); - hook = hook->next; + int res = (hook->f)(table, "BDD", (void *)heuristic); + if (res == 0) return(0); + hook = hook->next; } if (!ddReorderPreprocess(table)) return(0); ddTotalNumberSwapping = 0; - + if (table->keys > table->peakLiveNodes) { - table->peakLiveNodes = table->keys; + table->peakLiveNodes = table->keys; } #ifdef DD_STATS initialSize = table->keys - table->isolated; @@ -199,89 +226,89 @@ Cudd_ReduceHeap( switch(heuristic) { case CUDD_REORDER_RANDOM: case CUDD_REORDER_RANDOM_PIVOT: - (void) fprintf(table->out,"#:I_RANDOM "); - break; + (void) fprintf(table->out,"#:I_RANDOM "); + break; case CUDD_REORDER_SIFT: case CUDD_REORDER_SIFT_CONVERGE: case CUDD_REORDER_SYMM_SIFT: case CUDD_REORDER_SYMM_SIFT_CONV: case CUDD_REORDER_GROUP_SIFT: case CUDD_REORDER_GROUP_SIFT_CONV: - (void) fprintf(table->out,"#:I_SIFTING "); - break; + (void) fprintf(table->out,"#:I_SIFTING "); + break; case CUDD_REORDER_WINDOW2: case CUDD_REORDER_WINDOW3: case CUDD_REORDER_WINDOW4: case CUDD_REORDER_WINDOW2_CONV: case CUDD_REORDER_WINDOW3_CONV: case CUDD_REORDER_WINDOW4_CONV: - (void) fprintf(table->out,"#:I_WINDOW "); - break; + (void) fprintf(table->out,"#:I_WINDOW "); + break; case CUDD_REORDER_ANNEALING: - (void) fprintf(table->out,"#:I_ANNEAL "); - break; + (void) fprintf(table->out,"#:I_ANNEAL "); + break; case CUDD_REORDER_GENETIC: - (void) fprintf(table->out,"#:I_GENETIC "); - break; + (void) fprintf(table->out,"#:I_GENETIC "); + break; case CUDD_REORDER_LINEAR: case CUDD_REORDER_LINEAR_CONVERGE: - (void) fprintf(table->out,"#:I_LINSIFT "); - break; + (void) fprintf(table->out,"#:I_LINSIFT "); + break; case CUDD_REORDER_EXACT: - (void) fprintf(table->out,"#:I_EXACT "); - break; + (void) fprintf(table->out,"#:I_EXACT "); + break; default: - return(0); + return(0); } - (void) fprintf(table->out,"%8d: initial size",initialSize); + (void) fprintf(table->out,"%8d: initial size",initialSize); #endif /* See if we should use alternate threshold for maximum growth. */ if (table->reordCycle && table->reorderings % table->reordCycle == 0) { - double saveGrowth = table->maxGrowth; - table->maxGrowth = table->maxGrowthAlt; - result = cuddTreeSifting(table,heuristic,TimeStop); - table->maxGrowth = saveGrowth; + double saveGrowth = table->maxGrowth; + table->maxGrowth = table->maxGrowthAlt; + result = cuddTreeSifting(table,heuristic); + table->maxGrowth = saveGrowth; } else { - result = cuddTreeSifting(table,heuristic,TimeStop); + result = cuddTreeSifting(table,heuristic); } #ifdef DD_STATS (void) fprintf(table->out,"\n"); finalSize = table->keys - table->isolated; - (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n", - ((double)(util_cpu_time() - localTime)/1000.0)); + ((double)(util_cpu_time() - localTime)/1000.0)); (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n", - ddTotalNumberSwapping); + ddTotalNumberSwapping); (void) fprintf(table->out,"#:M_REORDER %8d: NI swaps\n",ddTotalNISwaps); #endif if (result == 0) - return(0); + return(0); if (!ddReorderPostprocess(table)) - return(0); + return(0); if (table->realign) { - if (!cuddZddAlignToBdd(table)) - return(0); + if (!cuddZddAlignToBdd(table)) + return(0); } nextDyn = (table->keys - table->constants.keys + 1) * - DD_DYN_RATIO + table->constants.keys; + DD_DYN_RATIO + table->constants.keys; if (table->reorderings < 20 || nextDyn > table->nextDyn) - table->nextDyn = nextDyn; + table->nextDyn = nextDyn; else - table->nextDyn += 20; + table->nextDyn += 20; table->reordered = 1; /* Run hook functions. */ hook = table->postReorderingHook; while (hook != NULL) { - int res = (hook->f)(table, "BDD", (void *)localTime); - if (res == 0) return(0); - hook = hook->next; + int res = (hook->f)(table, "BDD", (void *)localTime); + if (res == 0) return(0); + hook = hook->next; } /* Update cumulative reordering time. */ table->reordTime += util_cpu_time() - localTime; @@ -313,36 +340,36 @@ Cudd_ShuffleHeap( int * permutation /* required variable permutation */) { - int result; + int result; int i; int identity = 1; int *perm; /* Don't waste time in case of identity permutation. */ for (i = 0; i < table->size; i++) { - if (permutation[i] != table->invperm[i]) { - identity = 0; - break; - } + if (permutation[i] != table->invperm[i]) { + identity = 0; + break; + } } if (identity == 1) { - return(1); + return(1); } if (!ddReorderPreprocess(table)) return(0); if (table->keys > table->peakLiveNodes) { - table->peakLiveNodes = table->keys; + table->peakLiveNodes = table->keys; } perm = ABC_ALLOC(int, table->size); for (i = 0; i < table->size; i++) - perm[permutation[i]] = i; + perm[permutation[i]] = i; if (!ddCheckPermuation(table,table->tree,perm,permutation)) { - ABC_FREE(perm); - return(0); + ABC_FREE(perm); + return(0); } if (!ddUpdateMtrTree(table,table->tree,perm,permutation)) { - ABC_FREE(perm); - return(0); + ABC_FREE(perm); + return(0); } ABC_FREE(perm); @@ -382,66 +409,68 @@ cuddDynamicAllocNode( int i; DdNodePtr *mem; DdNode *list, *node; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; if (table->nextFree == NULL) { /* free list is empty */ - /* Try to allocate a new block. */ - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - mem = (DdNodePtr *) ABC_ALLOC(DdNode, DD_MEM_CHUNK + 1); - MMoutOfMemory = saveHandler; - if (mem == NULL && table->stash != NULL) { - ABC_FREE(table->stash); - table->stash = NULL; - /* Inhibit resizing of tables. */ - table->maxCacheHard = table->cacheSlots - 1; - table->cacheSlack = -(int)(table->cacheSlots + 1); - for (i = 0; i < table->size; i++) { - table->subtables[i].maxKeys <<= 2; + /* Try to allocate a new block. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdNodePtr *) ABC_ALLOC(DdNode, DD_MEM_CHUNK + 1); + MMoutOfMemory = saveHandler; + if (mem == NULL && table->stash != NULL) { + ABC_FREE(table->stash); + table->stash = NULL; + /* Inhibit resizing of tables. */ + table->maxCacheHard = table->cacheSlots - 1; + table->cacheSlack = - (int) (table->cacheSlots + 1); + for (i = 0; i < table->size; i++) { + table->subtables[i].maxKeys <<= 2; + } + mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); } - mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); - } - if (mem == NULL) { - /* Out of luck. Call the default handler to do - ** whatever it specifies for a failed malloc. If this - ** handler returns, then set error code, print - ** warning, and return. */ - (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); - table->errorCode = CUDD_MEMORY_OUT; + if (mem == NULL) { + /* Out of luck. Call the default handler to do + ** whatever it specifies for a failed malloc. If this + ** handler returns, then set error code, print + ** warning, and return. */ + (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); + table->errorCode = CUDD_MEMORY_OUT; #ifdef DD_VERBOSE - (void) fprintf(table->err, - "cuddDynamicAllocNode: out of memory"); - (void) fprintf(table->err,"Memory in use = %ld\n", - table->memused); + (void) fprintf(table->err, + "cuddDynamicAllocNode: out of memory"); + (void) fprintf(table->err,"Memory in use = %lu\n", + table->memused); #endif - return(NULL); - } else { /* successful allocation; slice memory */ - unsigned long offset; - table->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); - mem[0] = (DdNode *) table->memoryList; - table->memoryList = mem; - - /* Here we rely on the fact that the size of a DdNode is a - ** power of 2 and a multiple of the size of a pointer. - ** If we align one node, all the others will be aligned - ** as well. */ - offset = (unsigned long) mem & (sizeof(DdNode) - 1); - mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); + return(NULL); + } else { /* successful allocation; slice memory */ + unsigned long offset; + table->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); + mem[0] = (DdNode *) table->memoryList; + table->memoryList = mem; + + /* Here we rely on the fact that the size of a DdNode is a + ** power of 2 and a multiple of the size of a pointer. + ** If we align one node, all the others will be aligned + ** as well. */ + offset = (unsigned long) mem & (sizeof(DdNode) - 1); + mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); #ifdef DD_DEBUG - assert(((unsigned long) mem & (sizeof(DdNode) - 1)) == 0); + assert(((unsigned long) mem & (sizeof(DdNode) - 1)) == 0); #endif - list = (DdNode *) mem; + list = (DdNode *) mem; - i = 1; - do { - list[i - 1].next = &list[i]; - } while (++i < DD_MEM_CHUNK); + i = 1; + do { + list[i - 1].ref = 0; + list[i - 1].next = &list[i]; + } while (++i < DD_MEM_CHUNK); - list[DD_MEM_CHUNK - 1].next = NULL; + list[DD_MEM_CHUNK-1].ref = 0; + list[DD_MEM_CHUNK - 1].next = NULL; - table->nextFree = &list[0]; - } + table->nextFree = &list[0]; + } } /* if free list empty */ node = table->nextFree; @@ -476,13 +505,13 @@ cuddSifting( int lower, int upper) { - int i; - int *var; - int size; - int x; - int result; + int i; + int *var; + int size; + int x; + int result; #ifdef DD_STATS - int previousSize; + int previousSize; #endif size = table->size; @@ -491,46 +520,46 @@ cuddSifting( var = NULL; entry = ABC_ALLOC(int,size); if (entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddSiftingOutOfMem; } var = ABC_ALLOC(int,size); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddSiftingOutOfMem; } for (i = 0; i < size; i++) { - x = table->perm[i]; - entry[i] = table->subtables[x].keys; - var[i] = i; + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; } - qsort((void *)var,size,sizeof(int),(int (*)(const void *, const void *))ddUniqueCompare); + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddUniqueCompare); /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { - if (ddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->perm[var[i]]; - - if (x < lower || x > upper || table->subtables[x].bindVar == 1) - continue; + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->perm[var[i]]; + + if (x < lower || x > upper || table->subtables[x].bindVar == 1) + continue; #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - result = ddSiftingAux(table, x, lower, upper); - if (!result) goto cuddSiftingOutOfMem; + result = ddSiftingAux(table, x, lower, upper); + if (!result) goto cuddSiftingOutOfMem; #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"+"); /* should never happen */ - (void) fprintf(table->err,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->err,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } @@ -544,7 +573,7 @@ cuddSiftingOutOfMem: if (entry != NULL) ABC_FREE(entry); if (var != NULL) ABC_FREE(var); - return(0); + return(0); } /* end of cuddSifting */ @@ -574,15 +603,15 @@ cuddSwapping( int upper, Cudd_ReorderingType heuristic) { - int i, j; - int max, keys; - int nvars; - int x, y; - int iterate; + int i, j; + int max, keys; + int nvars; + int x, y; + int iterate; int previousSize; Move *moves, *move; - int pivot = 0; // Suppress "might be used uninitialized" - int modulo; + int pivot; + int modulo; int result; #ifdef DD_DEBUG @@ -594,61 +623,61 @@ cuddSwapping( iterate = nvars; for (i = 0; i < iterate; i++) { - if (ddTotalNumberSwapping >= table->siftMaxSwap) - break; - if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { - max = -1; - for (j = lower; j <= upper; j++) { - if ((keys = table->subtables[j].keys) > max) { - max = keys; - pivot = j; - } - } + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { + max = -1; + for (j = lower; j <= upper; j++) { + if ((keys = table->subtables[j].keys) > max) { + max = keys; + pivot = j; + } + } - modulo = upper - pivot; - if (modulo == 0) { - y = pivot; - } else{ - y = pivot + 1 + ((int) Cudd_Random() % modulo); - } + modulo = upper - pivot; + if (modulo == 0) { + y = pivot; + } else{ + y = pivot + 1 + ((int) Cudd_Random() % modulo); + } - modulo = pivot - lower - 1; - if (modulo < 1) { - x = lower; - } else{ - do { - x = (int) Cudd_Random() % modulo; - } while (x == y); + modulo = pivot - lower - 1; + if (modulo < 1) { + x = lower; + } else{ + do { + x = (int) Cudd_Random() % modulo; + } while (x == y); + } + } else { + x = ((int) Cudd_Random() % nvars) + lower; + do { + y = ((int) Cudd_Random() % nvars) + lower; + } while (x == y); + } + previousSize = table->keys - table->isolated; + moves = ddSwapAny(table,x,y); + if (moves == NULL) goto cuddSwappingOutOfMem; + result = ddSiftingBackward(table,previousSize,moves); + if (!result) goto cuddSwappingOutOfMem; + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } - } else { - x = ((int) Cudd_Random() % nvars) + lower; - do { - y = ((int) Cudd_Random() % nvars) + lower; - } while (x == y); - } - previousSize = table->keys - table->isolated; - moves = ddSwapAny(table,x,y); - if (moves == NULL) goto cuddSwappingOutOfMem; - result = ddSiftingBackward(table,previousSize,moves); - if (!result) goto cuddSwappingOutOfMem; - while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; - } #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"+"); /* should never happen */ - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif #if 0 - (void) fprintf(table->out,"#:t_SWAPPING %8d: tmp size\n", - table->keys - table->isolated); + (void) fprintf(table->out,"#:t_SWAPPING %8d: tmp size\n", + table->keys - table->isolated); #endif } @@ -656,9 +685,9 @@ cuddSwapping( cuddSwappingOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(0); @@ -686,7 +715,7 @@ cuddNextHigh( return(x+1); } /* end of cuddNextHigh */ - + /**Function******************************************************************** @@ -746,10 +775,10 @@ cuddSwapInPlace( DdNodePtr *previousP; DdNode *tmp; DdNode *sentinel = &(table->sentinel); -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; -#if DD_DEBUG +#ifdef DD_DEBUG int count,idcheck; #endif @@ -766,7 +795,7 @@ cuddSwapInPlace( /* Get parameters of x subtable. */ xindex = table->invperm[x]; - xlist = table->subtables[x].nodelist; + xlist = table->subtables[x].nodelist; oldxkeys = table->subtables[x].keys; xslots = table->subtables[x].slots; xshift = table->subtables[x].shift; @@ -780,365 +809,370 @@ cuddSwapInPlace( if (!cuddTestInteract(table,xindex,yindex)) { #ifdef DD_STATS - ddTotalNISwaps++; + ddTotalNISwaps++; #endif - newxkeys = oldxkeys; - newykeys = oldykeys; + newxkeys = oldxkeys; + newykeys = oldykeys; } else { - newxkeys = 0; - newykeys = oldykeys; - - /* Check whether the two projection functions involved in this - ** swap are isolated. At the end, we'll be able to tell how many - ** isolated projection functions are there by checking only these - ** two functions again. This is done to eliminate the isolated - ** projection functions from the node count. - */ - isolated = - ((table->vars[xindex]->ref == 1) + - (table->vars[yindex]->ref == 1)); + newxkeys = 0; + newykeys = oldykeys; + + /* Check whether the two projection functions involved in this + ** swap are isolated. At the end, we'll be able to tell how many + ** isolated projection functions are there by checking only these + ** two functions again. This is done to eliminate the isolated + ** projection functions from the node count. + */ + isolated = - ((table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1)); - /* The nodes in the x layer that do not depend on - ** y will stay there; the others are put in a chain. - ** The chain is handled as a LIFO; g points to the beginning. - */ - g = NULL; - if ((oldxkeys >= xslots || (unsigned) xslots == table->initSlots) && - oldxkeys <= DD_MAX_SUBTABLE_DENSITY * xslots) { - for (i = 0; i < xslots; i++) { - previousP = &(xlist[i]); - f = *previousP; - while (f != sentinel) { - next = f->next; - f1 = cuddT(f); f0 = cuddE(f); - if (f1->index != (DdHalfWord) yindex && - Cudd_Regular(f0)->index != (DdHalfWord) yindex) { - /* stays */ - newxkeys++; - *previousP = f; - previousP = &(f->next); - } else { - f->index = yindex; - f->next = g; - g = f; + /* The nodes in the x layer that do not depend on + ** y will stay there; the others are put in a chain. + ** The chain is handled as a LIFO; g points to the beginning. + */ + g = NULL; + if ((oldxkeys >= xslots || (unsigned) xslots == table->initSlots) && + oldxkeys <= DD_MAX_SUBTABLE_DENSITY * xslots) { + for (i = 0; i < xslots; i++) { + previousP = &(xlist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if (f1->index != (DdHalfWord) yindex && + Cudd_Regular(f0)->index != (DdHalfWord) yindex) { + /* stays */ + newxkeys++; + *previousP = f; + previousP = &(f->next); + } else { + f->index = yindex; + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + *previousP = sentinel; + } /* for each slot of the x subtable */ + } else { /* resize xlist */ + DdNode *h = NULL; + DdNodePtr *newxlist; + unsigned int newxslots; + int newxshift; + /* Empty current xlist. Nodes that stay go to list h; + ** nodes that move go to list g. */ + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if (f1->index != (DdHalfWord) yindex && + Cudd_Regular(f0)->index != (DdHalfWord) yindex) { + /* stays */ + f->next = h; + h = f; + newxkeys++; + } else { + f->index = yindex; + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ + } /* for each slot of the x subtable */ + /* Decide size of new subtable. */ + newxshift = xshift; + newxslots = xslots; + while ((unsigned) oldxkeys > DD_MAX_SUBTABLE_DENSITY * newxslots) { + newxshift--; + newxslots <<= 1; } - f = next; - } /* while there are elements in the collision chain */ - *previousP = sentinel; - } /* for each slot of the x subtable */ - } else { /* resize xlist */ - DdNode *h = NULL; - DdNodePtr *newxlist; - unsigned int newxslots; - int newxshift; - /* Empty current xlist. Nodes that stay go to list h; - ** nodes that move go to list g. */ - for (i = 0; i < xslots; i++) { - f = xlist[i]; - while (f != sentinel) { - next = f->next; - f1 = cuddT(f); f0 = cuddE(f); - if (f1->index != (DdHalfWord) yindex && - Cudd_Regular(f0)->index != (DdHalfWord) yindex) { - /* stays */ - f->next = h; - h = f; - newxkeys++; + while ((unsigned) oldxkeys < newxslots && + newxslots > table->initSlots) { + newxshift++; + newxslots >>= 1; + } + /* Try to allocate new table. Be ready to back off. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + newxlist = ABC_ALLOC(DdNodePtr, newxslots); + MMoutOfMemory = saveHandler; + if (newxlist == NULL) { + (void) fprintf(table->err, "Unable to resize subtable %d for lack of memory\n", i); + newxlist = xlist; + newxslots = xslots; + newxshift = xshift; } else { - f->index = yindex; - f->next = g; - g = f; + table->slots += ((int) newxslots - xslots); + table->minDead = (unsigned) + (table->gcFrac * (double) table->slots); + table->cacheSlack = (int) + ddMin(table->maxCacheHard, DD_MAX_CACHE_TO_SLOTS_RATIO + * table->slots) - 2 * (int) table->cacheSlots; + table->memused += + ((int) newxslots - xslots) * sizeof(DdNodePtr); + ABC_FREE(xlist); + xslots = newxslots; + xshift = newxshift; + xlist = newxlist; + } + /* Initialize new subtable. */ + for (i = 0; i < xslots; i++) { + xlist[i] = sentinel; + } + /* Move nodes that were parked in list h to their new home. */ + f = h; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + f0 = cuddE(f); + /* Check xlist for pair (f11,f01). */ + posn = ddHash(f1, f0, xshift); + /* For each element tmp in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + tmp = *previousP; + while (f1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (f1 == cuddT(tmp) && f0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; + *previousP = f; + f = next; } - f = next; - } /* while there are elements in the collision chain */ - } /* for each slot of the x subtable */ - /* Decide size of new subtable. */ - if (oldxkeys > DD_MAX_SUBTABLE_DENSITY * xslots) { - newxshift = xshift - 1; - newxslots = xslots << 1; - } else { - newxshift = xshift + 1; - newxslots = xslots >> 1; - } - /* Try to allocate new table. Be ready to back off. */ - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - newxlist = ABC_ALLOC(DdNodePtr, newxslots); - MMoutOfMemory = saveHandler; - if (newxlist == NULL) { - (void) fprintf(table->err, "Unable to resize subtable %d for lack of memory\n", i); - newxlist = xlist; - newxslots = xslots; - newxshift = xshift; - } else { - table->slots += (newxslots - xslots); - table->minDead = (unsigned) - (table->gcFrac * (double) table->slots); - table->cacheSlack = (int) - ddMin(table->maxCacheHard, DD_MAX_CACHE_TO_SLOTS_RATIO - * table->slots) - 2 * (int) table->cacheSlots; - table->memused += (newxslots - xslots) * sizeof(DdNodePtr); - ABC_FREE(xlist); - xslots = newxslots; - xshift = newxshift; - xlist = newxlist; - } - /* Initialize new subtable. */ - for (i = 0; i < xslots; i++) { - xlist[i] = sentinel; - } - /* Move nodes that were parked in list h to their new home. */ - f = h; - while (f != NULL) { - next = f->next; - f1 = cuddT(f); - f0 = cuddE(f); - /* Check xlist for pair (f11,f01). */ - posn = ddHash(f1, f0, xshift); - /* For each element tmp in collision list xlist[posn]. */ - previousP = &(xlist[posn]); - tmp = *previousP; - while (f1 < cuddT(tmp)) { - previousP = &(tmp->next); - tmp = *previousP; - } - while (f1 == cuddT(tmp) && f0 < cuddE(tmp)) { - previousP = &(tmp->next); - tmp = *previousP; - } - f->next = *previousP; - *previousP = f; - f = next; } - } #ifdef DD_COUNT - table->swapSteps += oldxkeys - newxkeys; + table->swapSteps += oldxkeys - newxkeys; #endif - /* Take care of the x nodes that must be re-expressed. - ** They form a linked list pointed by g. Their index has been - ** already changed to yindex. - */ - f = g; - while (f != NULL) { - next = f->next; - /* Find f1, f0, f11, f10, f01, f00. */ - f1 = cuddT(f); + /* Take care of the x nodes that must be re-expressed. + ** They form a linked list pointed by g. Their index has been + ** already changed to yindex. + */ + f = g; + while (f != NULL) { + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); #ifdef DD_DEBUG - assert(!(Cudd_IsComplement(f1))); + assert(!(Cudd_IsComplement(f1))); #endif - if ((int) f1->index == yindex) { - f11 = cuddT(f1); f10 = cuddE(f1); - } else { - f11 = f10 = f1; - } + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = f10 = f1; + } #ifdef DD_DEBUG - assert(!(Cudd_IsComplement(f11))); + assert(!(Cudd_IsComplement(f11))); #endif - f0 = cuddE(f); - comple = Cudd_IsComplement(f0); - f0 = Cudd_Regular(f0); - if ((int) f0->index == yindex) { - f01 = cuddT(f0); f00 = cuddE(f0); - } else { - f01 = f00 = f0; - } - if (comple) { - f01 = Cudd_Not(f01); - f00 = Cudd_Not(f00); - } - /* Decrease ref count of f1. */ - cuddSatDec(f1->ref); - /* Create the new T child. */ - if (f11 == f01) { - newf1 = f11; - cuddSatInc(newf1->ref); - } else { - /* Check xlist for triple (xindex,f11,f01). */ - posn = ddHash(f11, f01, xshift); - /* For each element newf1 in collision list xlist[posn]. */ - previousP = &(xlist[posn]); - newf1 = *previousP; - while (f11 < cuddT(newf1)) { - previousP = &(newf1->next); - newf1 = *previousP; - } - while (f11 == cuddT(newf1) && f01 < cuddE(newf1)) { - previousP = &(newf1->next); - newf1 = *previousP; - } - if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { - cuddSatInc(newf1->ref); - } else { /* no match */ - newf1 = cuddDynamicAllocNode(table); - if (newf1 == NULL) - goto cuddSwapOutOfMem; - newf1->index = xindex; newf1->ref = 1; - cuddT(newf1) = f11; - cuddE(newf1) = f01; - /* Insert newf1 in the collision list xlist[posn]; - ** increase the ref counts of f11 and f01. - */ - newxkeys++; - newf1->next = *previousP; - *previousP = newf1; - cuddSatInc(f11->ref); - tmp = Cudd_Regular(f01); - cuddSatInc(tmp->ref); - } - } - cuddT(f) = newf1; + f0 = cuddE(f); + comple = Cudd_IsComplement(f0); + f0 = Cudd_Regular(f0); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == f01) { + newf1 = f11; + cuddSatInc(newf1->ref); + } else { + /* Check xlist for triple (xindex,f11,f01). */ + posn = ddHash(f11, f01, xshift); + /* For each element newf1 in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + newf1 = *previousP; + while (f11 < cuddT(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + while (f11 == cuddT(newf1) && f01 < cuddE(newf1)) { + previousP = &(newf1->next); + newf1 = *previousP; + } + if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { + cuddSatInc(newf1->ref); + } else { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto cuddSwapOutOfMem; + newf1->index = xindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f01; + /* Insert newf1 in the collision list xlist[posn]; + ** increase the ref counts of f11 and f01. + */ + newxkeys++; + newf1->next = *previousP; + *previousP = newf1; + cuddSatInc(f11->ref); + tmp = Cudd_Regular(f01); + cuddSatInc(tmp->ref); + } + } + cuddT(f) = newf1; #ifdef DD_DEBUG - assert(!(Cudd_IsComplement(newf1))); + assert(!(Cudd_IsComplement(newf1))); #endif - /* Do the same for f0, keeping complement dots into account. */ - /* Decrease ref count of f0. */ - tmp = Cudd_Regular(f0); - cuddSatDec(tmp->ref); - /* Create the new E child. */ - if (f10 == f00) { - newf0 = f00; - tmp = Cudd_Regular(newf0); - cuddSatInc(tmp->ref); - } else { - /* make sure f10 is regular */ - newcomplement = Cudd_IsComplement(f10); - if (newcomplement) { - f10 = Cudd_Not(f10); - f00 = Cudd_Not(f00); - } - /* Check xlist for triple (xindex,f10,f00). */ - posn = ddHash(f10, f00, xshift); - /* For each element newf0 in collision list xlist[posn]. */ - previousP = &(xlist[posn]); - newf0 = *previousP; - while (f10 < cuddT(newf0)) { - previousP = &(newf0->next); - newf0 = *previousP; - } - while (f10 == cuddT(newf0) && f00 < cuddE(newf0)) { - previousP = &(newf0->next); - newf0 = *previousP; - } - if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { - cuddSatInc(newf0->ref); - } else { /* no match */ - newf0 = cuddDynamicAllocNode(table); - if (newf0 == NULL) - goto cuddSwapOutOfMem; - newf0->index = xindex; newf0->ref = 1; - cuddT(newf0) = f10; - cuddE(newf0) = f00; - /* Insert newf0 in the collision list xlist[posn]; - ** increase the ref counts of f10 and f00. - */ - newxkeys++; - newf0->next = *previousP; - *previousP = newf0; - cuddSatInc(f10->ref); - tmp = Cudd_Regular(f00); - cuddSatInc(tmp->ref); - } - if (newcomplement) { - newf0 = Cudd_Not(newf0); - } - } - cuddE(f) = newf0; - - /* Insert the modified f in ylist. - ** The modified f does not already exists in ylist. - ** (Because of the uniqueness of the cofactors.) - */ - posn = ddHash(newf1, newf0, yshift); - newykeys++; - previousP = &(ylist[posn]); - tmp = *previousP; - while (newf1 < cuddT(tmp)) { - previousP = &(tmp->next); - tmp = *previousP; - } - while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { - previousP = &(tmp->next); - tmp = *previousP; - } - f->next = *previousP; - *previousP = f; - f = next; - } /* while f != NULL */ - - /* GC the y layer. */ - - /* For each node f in ylist. */ - for (i = 0; i < yslots; i++) { - previousP = &(ylist[i]); - f = *previousP; - while (f != sentinel) { - next = f->next; - if (f->ref == 0) { - tmp = cuddT(f); - cuddSatDec(tmp->ref); - tmp = Cudd_Regular(cuddE(f)); + /* Do the same for f0, keeping complement dots into account. */ + /* Decrease ref count of f0. */ + tmp = Cudd_Regular(f0); cuddSatDec(tmp->ref); - cuddDeallocNode(table,f); - newykeys--; - } else { + /* Create the new E child. */ + if (f10 == f00) { + newf0 = f00; + tmp = Cudd_Regular(newf0); + cuddSatInc(tmp->ref); + } else { + /* make sure f10 is regular */ + newcomplement = Cudd_IsComplement(f10); + if (newcomplement) { + f10 = Cudd_Not(f10); + f00 = Cudd_Not(f00); + } + /* Check xlist for triple (xindex,f10,f00). */ + posn = ddHash(f10, f00, xshift); + /* For each element newf0 in collision list xlist[posn]. */ + previousP = &(xlist[posn]); + newf0 = *previousP; + while (f10 < cuddT(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + while (f10 == cuddT(newf0) && f00 < cuddE(newf0)) { + previousP = &(newf0->next); + newf0 = *previousP; + } + if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { + cuddSatInc(newf0->ref); + } else { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto cuddSwapOutOfMem; + newf0->index = xindex; newf0->ref = 1; + cuddT(newf0) = f10; + cuddE(newf0) = f00; + /* Insert newf0 in the collision list xlist[posn]; + ** increase the ref counts of f10 and f00. + */ + newxkeys++; + newf0->next = *previousP; + *previousP = newf0; + cuddSatInc(f10->ref); + tmp = Cudd_Regular(f00); + cuddSatInc(tmp->ref); + } + if (newcomplement) { + newf0 = Cudd_Not(newf0); + } + } + cuddE(f) = newf0; + + /* Insert the modified f in ylist. + ** The modified f does not already exists in ylist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, yshift); + newykeys++; + previousP = &(ylist[posn]); + tmp = *previousP; + while (newf1 < cuddT(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) { + previousP = &(tmp->next); + tmp = *previousP; + } + f->next = *previousP; *previousP = f; - previousP = &(f->next); - } - f = next; - } /* while f */ - *previousP = sentinel; - } /* for i */ + f = next; + } /* while f != NULL */ + + /* GC the y layer. */ + + /* For each node f in ylist. */ + for (i = 0; i < yslots; i++) { + previousP = &(ylist[i]); + f = *previousP; + while (f != sentinel) { + next = f->next; + if (f->ref == 0) { + tmp = cuddT(f); + cuddSatDec(tmp->ref); + tmp = Cudd_Regular(cuddE(f)); + cuddSatDec(tmp->ref); + cuddDeallocNode(table,f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = sentinel; + } /* for i */ -#if DD_DEBUG +#ifdef DD_DEBUG #if 0 - (void) fprintf(table->out,"Swapping %d and %d\n",x,y); + (void) fprintf(table->out,"Swapping %d and %d\n",x,y); #endif - count = 0; - idcheck = 0; - for (i = 0; i < yslots; i++) { - f = ylist[i]; - while (f != sentinel) { - count++; - if (f->index != (DdHalfWord) yindex) - idcheck++; - f = f->next; + count = 0; + idcheck = 0; + for (i = 0; i < yslots; i++) { + f = ylist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) yindex) + idcheck++; + f = f->next; + } } - } - if (count != newykeys) { - (void) fprintf(table->out, - "Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n", - oldykeys,newykeys,count); - } - if (idcheck != 0) - (void) fprintf(table->out, - "Error in id's of ylist\twrong id's = %d\n", - idcheck); - count = 0; - idcheck = 0; - for (i = 0; i < xslots; i++) { - f = xlist[i]; - while (f != sentinel) { - count++; - if (f->index != (DdHalfWord) xindex) - idcheck++; - f = f->next; + if (count != newykeys) { + (void) fprintf(table->out, + "Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n", + oldykeys,newykeys,count); } - } - if (count != newxkeys) { - (void) fprintf(table->out, - "Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n", - oldxkeys,newxkeys,count); - } - if (idcheck != 0) - (void) fprintf(table->out, - "Error in id's of xlist\twrong id's = %d\n", - idcheck); + if (idcheck != 0) + (void) fprintf(table->out, + "Error in id's of ylist\twrong id's = %d\n", + idcheck); + count = 0; + idcheck = 0; + for (i = 0; i < xslots; i++) { + f = xlist[i]; + while (f != sentinel) { + count++; + if (f->index != (DdHalfWord) xindex) + idcheck++; + f = f->next; + } + } + if (count != newxkeys) { + (void) fprintf(table->out, + "Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n", + oldxkeys,newxkeys,count); + } + if (idcheck != 0) + (void) fprintf(table->out, + "Error in id's of xlist\twrong id's = %d\n", + idcheck); #endif - isolated += (table->vars[xindex]->ref == 1) + - (table->vars[yindex]->ref == 1); - table->isolated += isolated; + isolated += (table->vars[xindex]->ref == 1) + + (table->vars[yindex]->ref == 1); + table->isolated += isolated; } /* Set the appropriate fields in table. */ @@ -1212,31 +1246,31 @@ int cuddBddAlignToZdd( DdManager * table /* DD manager */) { - int *invperm; /* permutation array */ - int M; /* ratio of ZDD variables to BDD variables */ - int i; /* loop index */ - int result; /* return value */ + int *invperm; /* permutation array */ + int M; /* ratio of ZDD variables to BDD variables */ + int i; /* loop index */ + int result; /* return value */ /* We assume that a ratio of 0 is OK. */ if (table->size == 0) - return(1); + return(1); M = table->sizeZ / table->size; /* Check whether the number of ZDD variables is a multiple of the ** number of BDD variables. */ if (M * table->size != table->sizeZ) - return(0); + return(0); /* Create and initialize the inverse permutation array. */ invperm = ABC_ALLOC(int,table->size); if (invperm == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < table->sizeZ; i += M) { - int indexZ = table->invpermZ[i]; - int index = indexZ / M; - invperm[i / M] = index; + int indexZ = table->invpermZ[i]; + int index = indexZ / M; + invperm[i / M] = index; } /* Eliminate dead nodes. Do not scan the cache again, because we ** assume that Cudd_zddReduceHeap has already cleared it. @@ -1246,7 +1280,7 @@ cuddBddAlignToZdd( /* Initialize number of isolated projection functions. */ table->isolated = 0; for (i = 0; i < table->size; i++) { - if (table->vars[i]->ref == 1) table->isolated++; + if (table->vars[i]->ref == 1) table->isolated++; } /* Initialize the interaction matrix. */ @@ -1287,7 +1321,7 @@ ddUniqueCompare( { #if 0 if (entry[*ptrY] == entry[*ptrX]) { - return((*ptrX) - (*ptrY)); + return((*ptrX) - (*ptrY)); } #endif return(entry[*ptrY] - entry[*ptrX]); @@ -1310,15 +1344,15 @@ ddSwapAny( int x, int y) { - Move *move, *moves; - int xRef,yRef; - int xNext,yNext; - int size; - int limitSize; - int tmp; + Move *move, *moves; + int xRef,yRef; + int xNext,yNext; + int size; + int limitSize; + int tmp; if (x >y) { - tmp = x; x = y; y = tmp; + tmp = x; x = y; y = tmp; } xRef = x; yRef = y; @@ -1329,64 +1363,86 @@ ddSwapAny( limitSize = table->keys - table->isolated; for (;;) { - if ( xNext == yNext) { - size = cuddSwapInPlace(table,x,xNext); - if (size == 0) goto ddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSwapAnyOutOfMem; - move->x = x; - move->y = xNext; - move->size = size; - move->next = moves; - moves = move; - - size = cuddSwapInPlace(table,yNext,y); - if (size == 0) goto ddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSwapAnyOutOfMem; - move->x = yNext; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - - size = cuddSwapInPlace(table,x,xNext); - if (size == 0) goto ddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSwapAnyOutOfMem; - move->x = x; - move->y = xNext; - move->size = size; - move->next = moves; - moves = move; + if ( xNext == yNext) { + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else if (x == yNext) { + + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; - tmp = x; x = y; y = tmp; - - } else if (x == yNext) { - - size = cuddSwapInPlace(table,x,xNext); - if (size == 0) goto ddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSwapAnyOutOfMem; - move->x = x; - move->y = xNext; - move->size = size; - move->next = moves; - moves = move; - - tmp = x; x = y; y = tmp; + } else { + size = cuddSwapInPlace(table,x,xNext); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = x; + move->y = xNext; + move->size = size; + move->next = moves; + moves = move; + + size = cuddSwapInPlace(table,yNext,y); + if (size == 0) goto ddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSwapAnyOutOfMem; + move->x = yNext; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + x = xNext; + y = yNext; + } - } else { - size = cuddSwapInPlace(table,x,xNext); - if (size == 0) goto ddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSwapAnyOutOfMem; - move->x = x; - move->y = xNext; - move->size = size; - move->next = moves; - moves = move; + xNext = cuddNextHigh(table,x); + yNext = cuddNextLow(table,y); + if (xNext > yRef) break; + if ((double) size > table->maxGrowth * (double) limitSize) break; + if (size < limitSize) limitSize = size; + } + if (yNext>=xRef) { size = cuddSwapInPlace(table,yNext,y); if (size == 0) goto ddSwapAnyOutOfMem; move = (Move *) cuddDynamicAllocNode(table); @@ -1396,37 +1452,15 @@ ddSwapAny( move->size = size; move->next = moves; moves = move; - - x = xNext; - y = yNext; - } - - xNext = cuddNextHigh(table,x); - yNext = cuddNextLow(table,y); - if (xNext > yRef) break; - - if ((double) size > table->maxGrowth * (double) limitSize) break; - if (size < limitSize) limitSize = size; - } - if (yNext>=xRef) { - size = cuddSwapInPlace(table,yNext,y); - if (size == 0) goto ddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSwapAnyOutOfMem; - move->x = yNext; - move->y = y; - move->size = size; - move->next = moves; - moves = move; } return(moves); - + ddSwapAnyOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(NULL); @@ -1453,11 +1487,11 @@ ddSiftingAux( int xHigh) { - Move *move; - Move *moveUp; /* list of up moves */ - Move *moveDown; /* list of down moves */ - int initialSize; - int result; + Move *move; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; initialSize = table->keys - table->isolated; @@ -1465,75 +1499,75 @@ ddSiftingAux( moveUp = NULL; if (x == xLow) { - moveDown = ddSiftingDown(table,x,xHigh); - /* At this point x --> xHigh unless bounding occurred. */ - if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddSiftingBackward(table,initialSize,moveDown); - if (!result) goto ddSiftingAuxOutOfMem; + moveDown = ddSiftingDown(table,x,xHigh); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddSiftingAuxOutOfMem; } else if (x == xHigh) { - moveUp = ddSiftingUp(table,x,xLow); - /* At this point x --> xLow unless bounding occurred. */ - if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddSiftingBackward(table,initialSize,moveUp); - if (!result) goto ddSiftingAuxOutOfMem; + moveUp = ddSiftingUp(table,x,xLow); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddSiftingAuxOutOfMem; } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ - moveDown = ddSiftingDown(table,x,xHigh); - /* At this point x --> xHigh unless bounding occurred. */ - if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; - if (moveDown != NULL) { - x = moveDown->y; - } - moveUp = ddSiftingUp(table,x,xLow); - if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; - /* Move backward and stop at best position */ - result = ddSiftingBackward(table,initialSize,moveUp); - if (!result) goto ddSiftingAuxOutOfMem; + moveDown = ddSiftingDown(table,x,xHigh); + /* At this point x --> xHigh unless bounding occurred. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + if (moveDown != NULL) { + x = moveDown->y; + } + moveUp = ddSiftingUp(table,x,xLow); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position */ + result = ddSiftingBackward(table,initialSize,moveUp); + if (!result) goto ddSiftingAuxOutOfMem; } else { /* must go up first: shorter */ - moveUp = ddSiftingUp(table,x,xLow); - /* At this point x --> xLow unless bounding occurred. */ - if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; - if (moveUp != NULL) { - x = moveUp->x; - } - moveDown = ddSiftingDown(table,x,xHigh); - if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; - /* Move backward and stop at best position. */ - result = ddSiftingBackward(table,initialSize,moveDown); - if (!result) goto ddSiftingAuxOutOfMem; + moveUp = ddSiftingUp(table,x,xLow); + /* At this point x --> xLow unless bounding occurred. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + if (moveUp != NULL) { + x = moveUp->x; + } + moveDown = ddSiftingDown(table,x,xHigh); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem; + /* Move backward and stop at best position. */ + result = ddSiftingBackward(table,initialSize,moveDown); + if (!result) goto ddSiftingAuxOutOfMem; } while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(1); ddSiftingAuxOutOfMem: if (moveDown != (Move *) CUDD_OUT_OF_MEM) { - while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; - } + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } } if (moveUp != (Move *) CUDD_OUT_OF_MEM) { - while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; - } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } } return(0); @@ -1558,14 +1592,14 @@ ddSiftingUp( int y, int xLow) { - Move *moves; - Move *move; - int x; - int size; - int limitSize; - int xindex, yindex; - int isolated; - int L; /* lower bound on DD size */ + Move *moves; + Move *move; + int x; + int size; + int limitSize; + int xindex, yindex; + int isolated; + int L; /* lower bound on DD size */ #ifdef DD_DEBUG int checkL; int z; @@ -1583,62 +1617,62 @@ ddSiftingUp( */ limitSize = L = table->keys - table->isolated; for (x = xLow + 1; x < y; x++) { - xindex = table->invperm[x]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[xindex]->ref == 1; - L -= table->subtables[x].keys - isolated; - } + xindex = table->invperm[x]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L -= table->subtables[x].keys - isolated; + } } isolated = table->vars[yindex]->ref == 1; L -= table->subtables[y].keys - isolated; x = cuddNextLow(table,y); while (x >= xLow && L <= limitSize) { - xindex = table->invperm[x]; + xindex = table->invperm[x]; #ifdef DD_DEBUG - checkL = table->keys - table->isolated; - for (z = xLow + 1; z < y; z++) { - zindex = table->invperm[z]; - if (cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - checkL -= table->subtables[z].keys - isolated; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z < y; z++) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } } - } - isolated = table->vars[yindex]->ref == 1; - checkL -= table->subtables[y].keys - isolated; - assert(L == checkL); + isolated = table->vars[yindex]->ref == 1; + checkL -= table->subtables[y].keys - isolated; + assert(L == checkL); #endif - size = cuddSwapInPlace(table,x,y); - if (size == 0) goto ddSiftingUpOutOfMem; - /* Update the lower bound. */ - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[xindex]->ref == 1; - L += table->subtables[y].keys - isolated; - } - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSiftingUpOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - if ((double) size > (double) limitSize * table->maxGrowth) break; - if (size < limitSize) limitSize = size; - y = x; - x = cuddNextLow(table,y); + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + y = x; + x = cuddNextLow(table,y); } return(moves); ddSiftingUpOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return((Move *) CUDD_OUT_OF_MEM); } /* end of ddSiftingUp */ - + /**Function******************************************************************** @@ -1658,18 +1692,18 @@ ddSiftingDown( int x, int xHigh) { - Move *moves; - Move *move; - int y; - int size; - int R; /* upper bound on node decrease */ - int limitSize; - int xindex, yindex; - int isolated; + Move *moves; + Move *move; + int y; + int size; + int R; /* upper bound on node decrease */ + int limitSize; + int xindex, yindex; + int isolated; #ifdef DD_DEBUG - int checkR; - int z; - int zindex; + int checkR; + int z; + int zindex; #endif moves = NULL; @@ -1678,53 +1712,53 @@ ddSiftingDown( limitSize = size = table->keys - table->isolated; R = 0; for (y = xHigh; y > x; y--) { - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[yindex]->ref == 1; - R += table->subtables[y].keys - isolated; - } + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R += table->subtables[y].keys - isolated; + } } y = cuddNextHigh(table,x); while (y <= xHigh && size - R < limitSize) { #ifdef DD_DEBUG - checkR = 0; - for (z = xHigh; z > x; z--) { - zindex = table->invperm[z]; - if (cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - checkR += table->subtables[z].keys - isolated; + checkR = 0; + for (z = xHigh; z > x; z--) { + zindex = table->invperm[z]; + if (cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } } - } - assert(R == checkR); + assert(R == checkR); #endif - /* Update upper bound on node decrease. */ - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[yindex]->ref == 1; - R -= table->subtables[y].keys - isolated; - } - size = cuddSwapInPlace(table,x,y); - if (size == 0) goto ddSiftingDownOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSiftingDownOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - if ((double) size > (double) limitSize * table->maxGrowth) break; - if (size < limitSize) limitSize = size; - x = y; - y = cuddNextHigh(table,x); + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); + if (size == 0) goto ddSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) break; + if (size < limitSize) limitSize = size; + x = y; + y = cuddNextHigh(table,x); } return(moves); ddSiftingDownOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return((Move *) CUDD_OUT_OF_MEM); @@ -1751,18 +1785,18 @@ ddSiftingBackward( Move * moves) { Move *move; - int res; + int res; for (move = moves; move != NULL; move = move->next) { - if (move->size < size) { - size = move->size; - } + if (move->size < size) { + size = move->size; + } } for (move = moves; move != NULL; move = move->next) { - if (move->size == size) return(1); - res = cuddSwapInPlace(table,(int)move->x,(int)move->y); - if (!res) return(0); + if (move->size == size) return(1); + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); } return(1); @@ -1800,7 +1834,7 @@ ddReorderPreprocess( /* Initialize number of isolated projection functions. */ table->isolated = 0; for (i = 0; i < table->size; i++) { - if (table->vars[i]->ref == 1) table->isolated++; + if (table->vars[i]->ref == 1) table->isolated++; } /* Initialize the interaction matrix. */ @@ -1859,16 +1893,16 @@ ddShuffle( DdManager * table, int * permutation) { - int index; - int level; - int position; - int numvars; - int result; + int index; + int level; + int position; + int numvars; + int result; #ifdef DD_STATS - long localTime; - int initialSize; - int finalSize; - int previousSize; + long localTime; + int initialSize; + int finalSize; + int previousSize; #endif ddTotalNumberSwapping = 0; @@ -1876,40 +1910,40 @@ ddShuffle( localTime = util_cpu_time(); initialSize = table->keys - table->isolated; (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n", - initialSize); + initialSize); ddTotalNISwaps = 0; #endif numvars = table->size; for (level = 0; level < numvars; level++) { - index = permutation[level]; - position = table->perm[index]; + index = permutation[level]; + position = table->perm[index]; #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - result = ddSiftUp(table,position,level); - if (!result) return(0); + result = ddSiftUp(table,position,level); + if (!result) return(0); #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"+"); /* should never happen */ - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } #ifdef DD_STATS (void) fprintf(table->out,"\n"); finalSize = table->keys - table->isolated; - (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize); + (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize); (void) fprintf(table->out,"#:T_SHUFFLE %8g: total time (sec)\n", - ((double)(util_cpu_time() - localTime)/1000.0)); + ((double)(util_cpu_time() - localTime)/1000.0)); (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n", - ddTotalNumberSwapping); + ddTotalNumberSwapping); (void) fprintf(table->out,"#:M_SHUFFLE %8d: NI swaps\n",ddTotalNISwaps); #endif @@ -1942,12 +1976,12 @@ ddSiftUp( y = cuddNextLow(table,x); while (y >= xLow) { - size = cuddSwapInPlace(table,y,x); - if (size == 0) { - return(0); - } - x = y; - y = cuddNextLow(table,x); + size = cuddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddNextLow(table,x); } return(1); @@ -1974,15 +2008,15 @@ bddFixTree( { if (treenode == NULL) return; treenode->low = ((int) treenode->index < table->size) ? - table->perm[treenode->index] : treenode->index; + table->perm[treenode->index] : treenode->index; if (treenode->child != NULL) { - bddFixTree(table, treenode->child); + bddFixTree(table, treenode->child); } if (treenode->younger != NULL) - bddFixTree(table, treenode->younger); + bddFixTree(table, treenode->younger); if (treenode->parent != NULL && treenode->low < treenode->parent->low) { - treenode->parent->low = treenode->low; - treenode->parent->index = treenode->index; + treenode->parent->low = treenode->low; + treenode->parent->index = treenode->index; } return; @@ -2008,36 +2042,41 @@ ddUpdateMtrTree( int * perm, int * invperm) { - int i, size, index, level; - int minLevel = table->size, maxLevel = 0, minIndex = 0; // Suppress "might be used uninitialized" + int i, size; + int index, level, minLevel, maxLevel, minIndex; if (treenode == NULL) return(1); + minLevel = CUDD_MAXINDEX; + maxLevel = 0; + minIndex = -1; /* i : level */ for (i = treenode->low; i < treenode->low + treenode->size; i++) { - index = table->invperm[i]; - level = perm[index]; - if (level < minLevel) { - minLevel = level; - minIndex = index; - } - if (level > maxLevel) - maxLevel = level; + index = table->invperm[i]; + level = perm[index]; + if (level < minLevel) { + minLevel = level; + minIndex = index; + } + if (level > maxLevel) + maxLevel = level; } size = maxLevel - minLevel + 1; + if (minIndex == -1) return(0); if (size == treenode->size) { - treenode->low = minLevel; - treenode->index = minIndex; - } else - return(0); + treenode->low = minLevel; + treenode->index = minIndex; + } else { + return(0); + } if (treenode->child != NULL) { - if (!ddUpdateMtrTree(table, treenode->child, perm, invperm)) - return(0); + if (!ddUpdateMtrTree(table, treenode->child, perm, invperm)) + return(0); } if (treenode->younger != NULL) { - if (!ddUpdateMtrTree(table, treenode->younger, perm, invperm)) - return(0); + if (!ddUpdateMtrTree(table, treenode->younger, perm, invperm)) + return(0); } return(1); } @@ -2062,8 +2101,8 @@ ddCheckPermuation( int * perm, int * invperm) { - int i, size, index, level; - int minLevel, maxLevel; + int i, size; + int index, level, minLevel, maxLevel; if (treenode == NULL) return(1); @@ -2071,26 +2110,28 @@ ddCheckPermuation( maxLevel = 0; /* i : level */ for (i = treenode->low; i < treenode->low + treenode->size; i++) { - index = table->invperm[i]; - level = perm[index]; - if (level < minLevel) - minLevel = level; - if (level > maxLevel) - maxLevel = level; + index = table->invperm[i]; + level = perm[index]; + if (level < minLevel) + minLevel = level; + if (level > maxLevel) + maxLevel = level; } size = maxLevel - minLevel + 1; if (size != treenode->size) - return(0); + return(0); if (treenode->child != NULL) { - if (!ddCheckPermuation(table, treenode->child, perm, invperm)) - return(0); + if (!ddCheckPermuation(table, treenode->child, perm, invperm)) + return(0); } if (treenode->younger != NULL) { - if (!ddCheckPermuation(table, treenode->younger, perm, invperm)) - return(0); + if (!ddCheckPermuation(table, treenode->younger, perm, invperm)) + return(0); } return(1); } + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddSat.c b/src/bdd/cudd/cuddSat.c index cb0534c3..c3a161b4 100644 --- a/src/bdd/cudd/cuddSat.c +++ b/src/bdd/cudd/cuddSat.c @@ -8,37 +8,64 @@ problems.] Description [External procedures included in this file: - <ul> - <li> Cudd_Eval() - <li> Cudd_ShortestPath() - <li> Cudd_LargestCube() - <li> Cudd_ShortestLength() - <li> Cudd_Decreasing() - <li> Cudd_Increasing() - <li> Cudd_EquivDC() - <li> Cudd_bddLeqUnless() - <li> Cudd_EqualSupNorm() - <li> Cudd_bddMakePrime() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddMakePrime() - </ul> - Static procedures included in this module: - <ul> - <li> freePathPair() - <li> getShortest() - <li> getPath() - <li> getLargest() - <li> getCube() - </ul>] + <ul> + <li> Cudd_Eval() + <li> Cudd_ShortestPath() + <li> Cudd_LargestCube() + <li> Cudd_ShortestLength() + <li> Cudd_Decreasing() + <li> Cudd_Increasing() + <li> Cudd_EquivDC() + <li> Cudd_bddLeqUnless() + <li> Cudd_EqualSupNorm() + <li> Cudd_bddMakePrime() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddBddMakePrime() + </ul> + Static procedures included in this module: + <ul> + <li> freePathPair() + <li> getShortest() + <li> getPath() + <li> getLargest() + <li> getCube() + </ul>] Author [Seh-Woong Jeong, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -48,11 +75,12 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define DD_BIGGY 1000000 +#define DD_BIGGY 1000000 /*---------------------------------------------------------------------------*/ /* Stucture declarations */ @@ -63,8 +91,8 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ typedef struct cuddPathPair { - int pos; - int neg; + int pos; + int neg; } cuddPathPair; /*---------------------------------------------------------------------------*/ @@ -72,16 +100,20 @@ typedef struct cuddPathPair { /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddSat.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddSat.c,v 1.36 2009/03/08 02:49:02 fabio Exp $"; #endif -static DdNode *one, *zero; +static DdNode *one, *zero; /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ -#define WEIGHT(weight, col) ((weight) == NULL ? 1 : weight[col]) +#define WEIGHT(weight, col) ((weight) == NULL ? 1 : weight[col]) + +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -89,14 +121,17 @@ static DdNode *one, *zero; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static enum st_retval freePathPair ARGS((char *key, char *value, char *arg)); -static cuddPathPair getShortest ARGS((DdNode *root, int *cost, int *support, st_table *visited)); -static DdNode * getPath ARGS((DdManager *manager, st_table *visited, DdNode *f, int *weight, int cost)); -static cuddPathPair getLargest ARGS((DdNode *root, st_table *visited)); -static DdNode * getCube ARGS((DdManager *manager, st_table *visited, DdNode *f, int cost)); +static enum st_retval freePathPair (char *key, char *value, char *arg); +static cuddPathPair getShortest (DdNode *root, int *cost, int *support, st_table *visited); +static DdNode * getPath (DdManager *manager, st_table *visited, DdNode *f, int *weight, int cost); +static cuddPathPair getLargest (DdNode *root, st_table *visited); +static DdNode * getCube (DdManager *manager, st_table *visited, DdNode *f, int cost); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -131,12 +166,12 @@ Cudd_Eval( ptr = Cudd_Regular(f); while (!cuddIsConstant(ptr)) { - if (inputs[ptr->index] == 1) { - ptr = cuddT(ptr); - } else { - comple ^= Cudd_IsComplement(cuddE(ptr)); - ptr = Cudd_Regular(cuddE(ptr)); - } + if (inputs[ptr->index] == 1) { + ptr = cuddT(ptr); + } else { + comple ^= Cudd_IsComplement(cuddE(ptr)); + ptr = Cudd_Regular(cuddE(ptr)); + } } return(Cudd_NotCond(ptr,comple)); @@ -170,55 +205,59 @@ Cudd_ShortestPath( int * support, int * length) { - register DdNode *F; + DdNode *F; st_table *visited; - DdNode *sol; + DdNode *sol; cuddPathPair *rootPair; - int complement, cost; - int i; + int complement, cost; + int i; one = DD_ONE(manager); zero = DD_ZERO(manager); - /* Initialize support. */ + /* Initialize support. Support does not depend on variable order. + ** Hence, it does not need to be reinitialized if reordering occurs. + */ if (support) { - for (i = 0; i < manager->size; i++) { + for (i = 0; i < manager->size; i++) { support[i] = 0; - } + } } if (f == Cudd_Not(one) || f == zero) { - *length = DD_BIGGY; - return(Cudd_Not(one)); + *length = DD_BIGGY; + return(Cudd_Not(one)); } /* From this point on, a path exists. */ - /* Initialize visited table. */ - visited = st_init_table(st_ptrcmp, st_ptrhash); + do { + manager->reordered = 0; - /* Now get the length of the shortest path(s) from f to 1. */ - (void) getShortest(f, weight, support, visited); + /* Initialize visited table. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); - complement = Cudd_IsComplement(f); + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getShortest(f, weight, support, visited); - F = Cudd_Regular(f); + complement = Cudd_IsComplement(f); - st_lookup(visited, (char *)F, (char **)&rootPair); - - if (complement) { - cost = rootPair->neg; - } else { - cost = rootPair->pos; - } + F = Cudd_Regular(f); - /* Recover an actual shortest path. */ - do { - manager->reordered = 0; - sol = getPath(manager,visited,f,weight,cost); - } while (manager->reordered == 1); + if (!st_lookup(visited, (const char *)F, (char **)&rootPair)) return(NULL); - st_foreach(visited, (ST_PFSR)freePathPair, NULL); - st_free_table(visited); + if (complement) { + cost = rootPair->neg; + } else { + cost = rootPair->pos; + } + + /* Recover an actual shortest path. */ + sol = getPath(manager,visited,f,weight,cost); + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + } while (manager->reordered == 1); *length = cost; return(sol); @@ -248,47 +287,49 @@ Cudd_LargestCube( DdNode * f, int * length) { - register DdNode *F; + register DdNode *F; st_table *visited; - DdNode *sol; + DdNode *sol; cuddPathPair *rootPair; - int complement, cost; + int complement, cost; one = DD_ONE(manager); zero = DD_ZERO(manager); if (f == Cudd_Not(one) || f == zero) { - *length = DD_BIGGY; - return(Cudd_Not(one)); + *length = DD_BIGGY; + return(Cudd_Not(one)); } /* From this point on, a path exists. */ - /* Initialize visited table. */ - visited = st_init_table(st_ptrcmp, st_ptrhash); + do { + manager->reordered = 0; - /* Now get the length of the shortest path(s) from f to 1. */ - (void) getLargest(f, visited); + /* Initialize visited table. */ + visited = st_init_table(st_ptrcmp, st_ptrhash); - complement = Cudd_IsComplement(f); + /* Now get the length of the shortest path(s) from f to 1. */ + (void) getLargest(f, visited); - F = Cudd_Regular(f); + complement = Cudd_IsComplement(f); - st_lookup(visited, (char *)F, (char **)&rootPair); - - if (complement) { - cost = rootPair->neg; - } else { - cost = rootPair->pos; - } + F = Cudd_Regular(f); - /* Recover an actual shortest path. */ - do { - manager->reordered = 0; - sol = getCube(manager,visited,f,cost); - } while (manager->reordered == 1); + if (!st_lookup(visited, (const char *)F, (char **)&rootPair)) return(NULL); - st_foreach(visited, (ST_PFSR)freePathPair, NULL); - st_free_table(visited); + if (complement) { + cost = rootPair->neg; + } else { + cost = rootPair->pos; + } + + /* Recover an actual shortest path. */ + sol = getCube(manager,visited,f,cost); + + st_foreach(visited, freePathPair, NULL); + st_free_table(visited); + + } while (manager->reordered == 1); *length = cost; return(sol); @@ -304,7 +345,8 @@ Cudd_LargestCube( 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 successful; CUDD_OUT_OF_MEM otherwise.] + 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] @@ -317,16 +359,16 @@ Cudd_ShortestLength( DdNode * f, int * weight) { - register DdNode *F; + register DdNode *F; st_table *visited; cuddPathPair *my_pair; - int complement, cost; + int complement, cost; one = DD_ONE(manager); zero = DD_ZERO(manager); if (f == Cudd_Not(one) || f == zero) { - return(DD_BIGGY); + return(DD_BIGGY); } /* From this point on, a path exists. */ @@ -340,15 +382,15 @@ Cudd_ShortestLength( F = Cudd_Regular(f); - st_lookup(visited, (char *)F, (char **)&my_pair); + if (!st_lookup(visited, (const char *)F, (char **)&my_pair)) return(CUDD_OUT_OF_MEM); if (complement) { - cost = my_pair->neg; + cost = my_pair->neg; } else { - cost = my_pair->pos; + cost = my_pair->pos; } - st_foreach(visited, (ST_PFSR)freePathPair, NULL); + st_foreach(visited, freePathPair, NULL); st_free_table(visited); return(cost); @@ -379,7 +421,7 @@ Cudd_Decreasing( { unsigned int topf, level; DdNode *F, *fv, *fvn, *res; - DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *); + DD_CTFP cacheOp; statLine(dd); #ifdef DD_DEBUG @@ -394,40 +436,40 @@ Cudd_Decreasing( */ level = (unsigned) dd->perm[i]; if (topf > level) { - return(DD_ONE(dd)); + return(DD_ONE(dd)); } /* From now on, f is not constant. */ /* Check cache. */ - cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) Cudd_Decreasing; + cacheOp = (DD_CTFP) Cudd_Decreasing; res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]); if (res != NULL) { - return(res); + return(res); } /* Compute cofactors. */ fv = cuddT(F); fvn = cuddE(F); if (F != f) { - fv = Cudd_Not(fv); - fvn = Cudd_Not(fvn); + fv = Cudd_Not(fv); + fvn = Cudd_Not(fvn); } if (topf == (unsigned) level) { - /* Special case: if fv is regular, fv(1,...,1) = 1; - ** If in addition fvn is complemented, fvn(1,...,1) = 0. - ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not - ** monotonic decreasing in i. - */ - if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) { - return(Cudd_Not(DD_ONE(dd))); - } - res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd)); + /* Special case: if fv is regular, fv(1,...,1) = 1; + ** If in addition fvn is complemented, fvn(1,...,1) = 0. + ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not + ** monotonic decreasing in i. + */ + if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) { + return(Cudd_Not(DD_ONE(dd))); + } + res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd)); } else { - res = Cudd_Decreasing(dd,fv,i); - if (res == DD_ONE(dd)) { - res = Cudd_Decreasing(dd,fvn,i); - } + res = Cudd_Decreasing(dd,fv,i); + if (res == DD_ONE(dd)) { + res = Cudd_Decreasing(dd,fvn,i); + } } cuddCacheInsert2(dd,cacheOp,f,dd->vars[i],res); @@ -442,7 +484,7 @@ Cudd_Decreasing( variable.] Description [Determines whether the function represented by BDD f is - positive unate (monotonic decreasing) in variable i. It is based on + 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.] @@ -499,13 +541,13 @@ Cudd_EquivDC( /* Normalize call to increase cache efficiency. */ if (F > G) { - tmp = F; - F = G; - G = tmp; + tmp = F; + F = G; + G = tmp; } if (Cudd_IsComplement(F)) { - F = Cudd_Not(F); - G = Cudd_Not(G); + F = Cudd_Not(F); + G = Cudd_Not(G); } /* From now on, F is regular. */ @@ -525,36 +567,36 @@ Cudd_EquivDC( /* Compute cofactors. */ if (top == flevel) { - Fv = cuddT(F); - Fvn = cuddE(F); + Fv = cuddT(F); + Fvn = cuddE(F); } else { - Fv = Fvn = F; + Fv = Fvn = F; } if (top == glevel) { - Gv = cuddT(Gr); - Gvn = cuddE(Gr); - if (G != Gr) { - Gv = Cudd_Not(Gv); - Gvn = Cudd_Not(Gvn); - } + Gv = cuddT(Gr); + Gvn = cuddE(Gr); + if (G != Gr) { + Gv = Cudd_Not(Gv); + Gvn = Cudd_Not(Gvn); + } } else { - Gv = Gvn = G; + Gv = Gvn = G; } if (top == dlevel) { - Dv = cuddT(Dr); - Dvn = cuddE(Dr); - if (D != Dr) { - Dv = Cudd_Not(Dv); - Dvn = Cudd_Not(Dvn); - } + Dv = cuddT(Dr); + Dvn = cuddE(Dr); + if (D != Dr) { + Dv = Cudd_Not(Dv); + Dvn = Cudd_Not(Dvn); + } } else { - Dv = Dvn = D; + Dv = Dvn = D; } /* Solve recursively. */ res = Cudd_EquivDC(dd,Fv,Gv,Dv); if (res != 0) { - res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn); + res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn); } cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One)); @@ -594,10 +636,10 @@ Cudd_bddLeqUnless( /* Check terminal cases. */ if (f == g || g == One || f == Cudd_Not(One) || D == One || - D == f || D == Cudd_Not(g)) return(1); + D == f || D == Cudd_Not(g)) return(1); /* Check for two-operand cases. */ if (D == Cudd_Not(One) || D == g || D == Cudd_Not(f)) - return(Cudd_bddLeq(dd,f,g)); + return(Cudd_bddLeq(dd,f,g)); if (g == Cudd_Not(One) || g == Cudd_Not(f)) return(Cudd_bddLeq(dd,f,D)); if (f == One) return(Cudd_bddLeq(dd,Cudd_Not(g),D)); @@ -612,72 +654,72 @@ Cudd_bddLeqUnless( ** lowest address comes first. */ if (Cudd_IsComplement(D)) { - if (Cudd_IsComplement(g)) { - /* Special case: if f is regular and g is complemented, - ** f(1,...,1) = 1 > 0 = g(1,...,1). If D(1,...,1) = 0, return 0. - */ - if (!Cudd_IsComplement(f)) return(0); - /* !g <= D unless !f or !D <= g unless !f */ - tmp = D; - D = Cudd_Not(f); - if (g < tmp) { - f = Cudd_Not(g); - g = tmp; + if (Cudd_IsComplement(g)) { + /* Special case: if f is regular and g is complemented, + ** f(1,...,1) = 1 > 0 = g(1,...,1). If D(1,...,1) = 0, return 0. + */ + if (!Cudd_IsComplement(f)) return(0); + /* !g <= D unless !f or !D <= g unless !f */ + tmp = D; + D = Cudd_Not(f); + if (g < tmp) { + f = Cudd_Not(g); + g = tmp; + } else { + f = Cudd_Not(tmp); + } } else { - f = Cudd_Not(tmp); + if (Cudd_IsComplement(f)) { + /* !D <= !f unless g or !D <= g unless !f */ + tmp = f; + f = Cudd_Not(D); + if (tmp < g) { + D = g; + g = Cudd_Not(tmp); + } else { + D = Cudd_Not(tmp); + } + } else { + /* f <= D unless g or !D <= !f unless g */ + tmp = D; + D = g; + if (tmp < f) { + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } else { + g = tmp; + } + } } } else { - if (Cudd_IsComplement(f)) { - /* !D <= !f unless g or !D <= g unless !f */ - tmp = f; - f = Cudd_Not(D); - if (tmp < g) { - D = g; - g = Cudd_Not(tmp); + if (Cudd_IsComplement(g)) { + if (Cudd_IsComplement(f)) { + /* !g <= !f unless D or !g <= D unless !f */ + tmp = f; + f = Cudd_Not(g); + if (D < tmp) { + g = D; + D = Cudd_Not(tmp); + } else { + g = Cudd_Not(tmp); + } + } else { + /* f <= g unless D or !g <= !f unless D */ + if (g < f) { + tmp = g; + g = Cudd_Not(f); + f = Cudd_Not(tmp); + } + } } else { - D = Cudd_Not(tmp); - } - } else { - /* f <= D unless g or !D <= !f unless g */ - tmp = D; - D = g; - if (tmp < f) { - g = Cudd_Not(f); - f = Cudd_Not(tmp); - } else { - g = tmp; - } + /* f <= g unless D or f <= D unless g */ + if (D < g) { + tmp = D; + D = g; + g = tmp; + } } } - } else { - if (Cudd_IsComplement(g)) { - if (Cudd_IsComplement(f)) { - /* !g <= !f unless D or !g <= D unless !f */ - tmp = f; - f = Cudd_Not(g); - if (D < tmp) { - g = D; - D = Cudd_Not(tmp); - } else { - g = Cudd_Not(tmp); - } - } else { - /* f <= g unless D or !g <= !f unless D */ - if (g < f) { - tmp = g; - g = Cudd_Not(f); - f = Cudd_Not(tmp); - } - } - } else { - /* f <= g unless D or f <= D unless g */ - if (D < g) { - tmp = D; - D = g; - g = tmp; - } - } - } /* From now on, D is regular. */ @@ -696,36 +738,36 @@ Cudd_bddLeqUnless( /* Compute cofactors. */ if (top == flevel) { - Ft = cuddT(F); - Fe = cuddE(F); - if (F != f) { - Ft = Cudd_Not(Ft); - Fe = Cudd_Not(Fe); - } + Ft = cuddT(F); + Fe = cuddE(F); + if (F != f) { + Ft = Cudd_Not(Ft); + Fe = Cudd_Not(Fe); + } } else { - Ft = Fe = f; + Ft = Fe = f; } if (top == glevel) { - Gt = cuddT(G); - Ge = cuddE(G); - if (G != g) { - Gt = Cudd_Not(Gt); - Ge = Cudd_Not(Ge); - } + Gt = cuddT(G); + Ge = cuddE(G); + if (G != g) { + Gt = Cudd_Not(Gt); + Ge = Cudd_Not(Ge); + } } else { - Gt = Ge = g; + Gt = Ge = g; } if (top == dlevel) { - Dt = cuddT(D); - De = cuddE(D); + Dt = cuddT(D); + De = cuddE(D); } else { - Dt = De = D; + Dt = De = D; } /* Solve recursively. */ res = Cudd_bddLeqUnless(dd,Ft,Gt,Dt); if (res != 0) { - res = Cudd_bddLeqUnless(dd,Fe,Ge,De); + res = Cudd_bddLeqUnless(dd,Fe,Ge,De); } cuddCacheInsert(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D,Cudd_NotCond(One,!res)); @@ -765,36 +807,27 @@ Cudd_EqualSupNorm( /* Check terminal cases. */ if (f == g) return(1); if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) { - if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) { - return(1); - } else { - if (pr>0) { - (void) fprintf(dd->out,"Offending nodes:\n"); -#if SIZEOF_VOID_P == 8 - (void) fprintf(dd->out, - "f: address = %lx\t value = %40.30f\n", - (unsigned long) f, cuddV(f)); - (void) fprintf(dd->out, - "g: address = %lx\t value = %40.30f\n", - (unsigned long) g, cuddV(g)); -#else - (void) fprintf(dd->out, - "f: address = %x\t value = %40.30f\n", - (unsigned) f, cuddV(f)); - (void) fprintf(dd->out, - "g: address = %x\t value = %40.30f\n", - (unsigned) g, cuddV(g)); -#endif + if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) { + return(1); + } else { + if (pr>0) { + (void) fprintf(dd->out,"Offending nodes:\n"); + (void) fprintf(dd->out, + "f: address = %p\t value = %40.30f\n", + (void *) f, cuddV(f)); + (void) fprintf(dd->out, + "g: address = %p\t value = %40.30f\n", + (void *) g, cuddV(g)); + } + return(0); } - return(0); - } } /* We only insert the result in the cache if the comparison is ** successful. Therefore, if we hit we return 1. */ - r = cuddCacheLookup2(dd,(DdNode * (*)(DdManager *, DdNode *, DdNode *))Cudd_EqualSupNorm,f,g); + r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g); if (r != NULL) { - return(1); + return(1); } /* Compute the cofactors and solve the recursive subproblems. */ @@ -807,7 +840,7 @@ Cudd_EqualSupNorm( if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0); if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0); - cuddCacheInsert2(dd,(DdNode * (*)(DdManager *, DdNode *, DdNode *))Cudd_EqualSupNorm,f,g,DD_ONE(dd)); + cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g,DD_ONE(dd)); return(1); @@ -838,8 +871,8 @@ Cudd_bddMakePrime( if (!Cudd_bddLeq(dd,cube,f)) return(NULL); do { - dd->reordered = 0; - res = cuddBddMakePrime(dd,cube,f); + dd->reordered = 0; + res = cuddBddMakePrime(dd,cube,f); } while (dd->reordered == 1); return(res); @@ -877,36 +910,36 @@ cuddBddMakePrime( Cudd_Ref(res); scan = cube; while (!Cudd_IsConstant(scan)) { - DdNode *reg = Cudd_Regular(scan); - DdNode *var = dd->vars[reg->index]; - DdNode *expanded = Cudd_bddExistAbstract(dd,res,var); - if (expanded == NULL) { - return(NULL); - } - Cudd_Ref(expanded); - if (Cudd_bddLeq(dd,expanded,f)) { - Cudd_RecursiveDeref(dd,res); - res = expanded; - } else { - Cudd_RecursiveDeref(dd,expanded); - } - cuddGetBranches(scan,&t,&e); - if (t == zero) { - scan = e; - } else if (e == zero) { - scan = t; - } else { - Cudd_RecursiveDeref(dd,res); - return(NULL); /* cube is not a cube */ - } + DdNode *reg = Cudd_Regular(scan); + DdNode *var = dd->vars[reg->index]; + DdNode *expanded = Cudd_bddExistAbstract(dd,res,var); + if (expanded == NULL) { + return(NULL); + } + Cudd_Ref(expanded); + if (Cudd_bddLeq(dd,expanded,f)) { + Cudd_RecursiveDeref(dd,res); + res = expanded; + } else { + Cudd_RecursiveDeref(dd,expanded); + } + cuddGetBranches(scan,&t,&e); + if (t == zero) { + scan = e; + } else if (e == zero) { + scan = t; + } else { + Cudd_RecursiveDeref(dd,res); + return(NULL); /* cube is not a cube */ + } } if (scan == DD_ONE(dd)) { - Cudd_Deref(res); - return(res); + Cudd_Deref(res); + return(res); } else { - Cudd_RecursiveDeref(dd,res); - return(NULL); + Cudd_RecursiveDeref(dd,res); + return(NULL); } } /* end of cuddBddMakePrime */ @@ -936,7 +969,7 @@ freePathPair( cuddPathPair *pair; pair = (cuddPathPair *) value; - ABC_FREE(pair); + ABC_FREE(pair); return(ST_CONTINUE); } /* end of freePathPair */ @@ -968,20 +1001,20 @@ getShortest( st_table * visited) { cuddPathPair *my_pair, res_pair, pair_T, pair_E; - DdNode *my_root, *T, *E; - int weight; + DdNode *my_root, *T, *E; + int weight; my_root = Cudd_Regular(root); - if (st_lookup(visited, (char *)my_root, (char **)&my_pair)) { - if (Cudd_IsComplement(root)) { - res_pair.pos = my_pair->neg; - res_pair.neg = my_pair->pos; - } else { - res_pair.pos = my_pair->pos; - res_pair.neg = my_pair->neg; - } - return(res_pair); + if (st_lookup(visited, (const char *)my_root, (char **)&my_pair)) { + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); } /* In the case of a BDD the following test is equivalent to @@ -990,48 +1023,48 @@ getShortest( ** dichotomy of 0 and != 0. */ if (cuddIsConstant(my_root)) { - if (my_root != zero) { - res_pair.pos = 0; - res_pair.neg = DD_BIGGY; - } else { - res_pair.pos = DD_BIGGY; - res_pair.neg = 0; - } + if (my_root != zero) { + res_pair.pos = 0; + res_pair.neg = DD_BIGGY; + } else { + res_pair.pos = DD_BIGGY; + res_pair.neg = 0; + } } else { - T = cuddT(my_root); - E = cuddE(my_root); - - pair_T = getShortest(T, cost, support, visited); - pair_E = getShortest(E, cost, support, visited); - weight = WEIGHT(cost, my_root->index); - res_pair.pos = ddMin(pair_T.pos+weight, pair_E.pos); - res_pair.neg = ddMin(pair_T.neg+weight, pair_E.neg); - - /* Update support. */ - if (support != NULL) { - support[my_root->index] = 1; - } + T = cuddT(my_root); + E = cuddE(my_root); + + pair_T = getShortest(T, cost, support, visited); + pair_E = getShortest(E, cost, support, visited); + weight = WEIGHT(cost, my_root->index); + res_pair.pos = ddMin(pair_T.pos+weight, pair_E.pos); + res_pair.neg = ddMin(pair_T.neg+weight, pair_E.neg); + + /* Update support. */ + if (support != NULL) { + support[my_root->index] = 1; + } } my_pair = ABC_ALLOC(cuddPathPair, 1); if (my_pair == NULL) { - if (Cudd_IsComplement(root)) { - int tmp = res_pair.pos; - res_pair.pos = res_pair.neg; - res_pair.neg = tmp; - } - return(res_pair); + if (Cudd_IsComplement(root)) { + int tmp = res_pair.pos; + res_pair.pos = res_pair.neg; + res_pair.neg = tmp; + } + return(res_pair); } my_pair->pos = res_pair.pos; my_pair->neg = res_pair.neg; st_insert(visited, (char *)my_root, (char *)my_pair); if (Cudd_IsComplement(root)) { - res_pair.pos = my_pair->neg; - res_pair.neg = my_pair->pos; + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; } else { - res_pair.pos = my_pair->pos; - res_pair.neg = my_pair->neg; + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; } return(res_pair); @@ -1064,11 +1097,11 @@ getPath( int * weight, int cost) { - DdNode *sol, *tmp; - DdNode *my_dd, *T, *E; + DdNode *sol, *tmp; + DdNode *my_dd, *T, *E; cuddPathPair *T_pair, *E_pair; - int Tcost, Ecost; - int complement; + int Tcost, Ecost; + int complement; my_dd = Cudd_Regular(f); complement = Cudd_IsComplement(f); @@ -1077,50 +1110,50 @@ getPath( cuddRef(sol); while (!cuddIsConstant(my_dd)) { - Tcost = cost - WEIGHT(weight, my_dd->index); - Ecost = cost; - - T = cuddT(my_dd); - E = cuddE(my_dd); - - if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} - - st_lookup(visited, (char *)Cudd_Regular(T), (char **)&T_pair); - if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || - (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { - tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); - if (tmp == NULL) { - Cudd_RecursiveDeref(manager,sol); - return(NULL); + Tcost = cost - WEIGHT(weight, my_dd->index); + Ecost = cost; + + T = cuddT(my_dd); + E = cuddE(my_dd); + + if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} + + st_lookup(visited, (const char *)Cudd_Regular(T), (char **)&T_pair); + if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || + (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { + tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + + complement = Cudd_IsComplement(T); + my_dd = Cudd_Regular(T); + cost = Tcost; + continue; } - cuddRef(tmp); - Cudd_RecursiveDeref(manager,sol); - sol = tmp; - - complement = Cudd_IsComplement(T); - my_dd = Cudd_Regular(T); - cost = Tcost; - continue; - } - st_lookup(visited, (char *)Cudd_Regular(E), (char **)&E_pair); - if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || - (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { - tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); - if (tmp == NULL) { - Cudd_RecursiveDeref(manager,sol); - return(NULL); + st_lookup(visited, (const char *)Cudd_Regular(E), (char **)&E_pair); + if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || + (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { + tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + complement = Cudd_IsComplement(E); + my_dd = Cudd_Regular(E); + cost = Ecost; + continue; } - cuddRef(tmp); - Cudd_RecursiveDeref(manager,sol); - sol = tmp; - complement = Cudd_IsComplement(E); - my_dd = Cudd_Regular(E); - cost = Ecost; - continue; - } - (void) fprintf(manager->err,"We shouldn't be here!!\n"); - manager->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + (void) fprintf(manager->err,"We shouldn't be here!!\n"); + manager->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } cuddDeref(sol); @@ -1155,19 +1188,19 @@ getLargest( st_table * visited) { cuddPathPair *my_pair, res_pair, pair_T, pair_E; - DdNode *my_root, *T, *E; + DdNode *my_root, *T, *E; my_root = Cudd_Regular(root); - if (st_lookup(visited, (char *)my_root, (char **)&my_pair)) { - if (Cudd_IsComplement(root)) { - res_pair.pos = my_pair->neg; - res_pair.neg = my_pair->pos; - } else { - res_pair.pos = my_pair->pos; - res_pair.neg = my_pair->neg; - } - return(res_pair); + if (st_lookup(visited, (const char *)my_root, (char **)&my_pair)) { + if (Cudd_IsComplement(root)) { + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; + } else { + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; + } + return(res_pair); } /* In the case of a BDD the following test is equivalent to @@ -1176,42 +1209,43 @@ getLargest( ** dichotomy of 0 and != 0. */ if (cuddIsConstant(my_root)) { - if (my_root != zero) { - res_pair.pos = 0; - res_pair.neg = DD_BIGGY; - } else { - res_pair.pos = DD_BIGGY; - res_pair.neg = 0; - } + if (my_root != zero) { + res_pair.pos = 0; + res_pair.neg = DD_BIGGY; + } else { + res_pair.pos = DD_BIGGY; + res_pair.neg = 0; + } } else { - T = cuddT(my_root); - E = cuddE(my_root); + T = cuddT(my_root); + E = cuddE(my_root); - pair_T = getLargest(T, visited); - pair_E = getLargest(E, visited); - res_pair.pos = ddMin(pair_T.pos, pair_E.pos) + 1; - res_pair.neg = ddMin(pair_T.neg, pair_E.neg) + 1; + pair_T = getLargest(T, visited); + pair_E = getLargest(E, visited); + res_pair.pos = ddMin(pair_T.pos, pair_E.pos) + 1; + res_pair.neg = ddMin(pair_T.neg, pair_E.neg) + 1; } my_pair = ABC_ALLOC(cuddPathPair, 1); - if (my_pair == NULL) { /* simlpy do not cache this result */ - if (Cudd_IsComplement(root)) { - int tmp = res_pair.pos; - res_pair.pos = res_pair.neg; - res_pair.neg = tmp; - } - return(res_pair); + if (my_pair == NULL) { /* simply do not cache this result */ + if (Cudd_IsComplement(root)) { + int tmp = res_pair.pos; + res_pair.pos = res_pair.neg; + res_pair.neg = tmp; + } + return(res_pair); } my_pair->pos = res_pair.pos; my_pair->neg = res_pair.neg; + /* Caching may fail without affecting correctness. */ st_insert(visited, (char *)my_root, (char *)my_pair); if (Cudd_IsComplement(root)) { - res_pair.pos = my_pair->neg; - res_pair.neg = my_pair->pos; + res_pair.pos = my_pair->neg; + res_pair.neg = my_pair->pos; } else { - res_pair.pos = my_pair->pos; - res_pair.neg = my_pair->neg; + res_pair.pos = my_pair->pos; + res_pair.neg = my_pair->neg; } return(res_pair); @@ -1243,11 +1277,11 @@ getCube( DdNode * f, int cost) { - DdNode *sol, *tmp; - DdNode *my_dd, *T, *E; + DdNode *sol, *tmp; + DdNode *my_dd, *T, *E; cuddPathPair *T_pair, *E_pair; - int Tcost, Ecost; - int complement; + int Tcost, Ecost; + int complement; my_dd = Cudd_Regular(f); complement = Cudd_IsComplement(f); @@ -1256,55 +1290,57 @@ getCube( cuddRef(sol); while (!cuddIsConstant(my_dd)) { - Tcost = cost - 1; - Ecost = cost - 1; - - T = cuddT(my_dd); - E = cuddE(my_dd); - - if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} - - st_lookup(visited, (char *)Cudd_Regular(T), (char **)&T_pair); - if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || - (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { - tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); - if (tmp == NULL) { - Cudd_RecursiveDeref(manager,sol); - return(NULL); + Tcost = cost - 1; + Ecost = cost - 1; + + T = cuddT(my_dd); + E = cuddE(my_dd); + + if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);} + + if (!st_lookup(visited, (const char *)Cudd_Regular(T), (char **)&T_pair)) return(NULL); + if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) || + (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) { + tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + + complement = Cudd_IsComplement(T); + my_dd = Cudd_Regular(T); + cost = Tcost; + continue; } - cuddRef(tmp); - Cudd_RecursiveDeref(manager,sol); - sol = tmp; - - complement = Cudd_IsComplement(T); - my_dd = Cudd_Regular(T); - cost = Tcost; - continue; - } - st_lookup(visited, (char *)Cudd_Regular(E), (char **)&E_pair); - if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || - (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { - tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); - if (tmp == NULL) { - Cudd_RecursiveDeref(manager,sol); - return(NULL); + if (!st_lookup(visited, (const char *)Cudd_Regular(E), (char **)&E_pair)) return(NULL); + if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) || + (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) { + tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol); + if (tmp == NULL) { + Cudd_RecursiveDeref(manager,sol); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(manager,sol); + sol = tmp; + complement = Cudd_IsComplement(E); + my_dd = Cudd_Regular(E); + cost = Ecost; + continue; } - cuddRef(tmp); - Cudd_RecursiveDeref(manager,sol); - sol = tmp; - complement = Cudd_IsComplement(E); - my_dd = Cudd_Regular(E); - cost = Ecost; - continue; - } - (void) fprintf(manager->err,"We shouldn't be here!\n"); - manager->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + (void) fprintf(manager->err,"We shouldn't be here!\n"); + manager->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } cuddDeref(sol); return(sol); } /* end of getCube */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddSign.c b/src/bdd/cudd/cuddSign.c index b2b043a4..75d1f60c 100644 --- a/src/bdd/cudd/cuddSign.c +++ b/src/bdd/cudd/cuddSign.c @@ -4,24 +4,51 @@ PackageName [cudd] - Synopsis [Computation of signatures] + Synopsis [Computation of signatures.] Description [External procedures included in this module: - <ul> - <li> Cudd_CofMinterm(); - </ul> - Static procedures included in this module: - <ul> - <li> ddCofMintermAux() - </ul> - ] + <ul> + <li> Cudd_CofMinterm(); + </ul> + Static procedures included in this module: + <ul> + <li> ddCofMintermAux() + </ul> + ] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -32,6 +59,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -52,13 +80,13 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddSign.c,v 1.22 2009/02/20 02:14:58 fabio Exp $"; #endif static int size; #ifdef DD_STATS -static int num_calls; /* should equal 2n-1 (n is the # of nodes) */ +static int num_calls; /* should equal 2n-1 (n is the # of nodes) */ static int table_mem; #endif @@ -74,7 +102,7 @@ static int table_mem; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static double * ddCofMintermAux ARGS((DdManager *dd, DdNode *node, st_table *table)); +static double * ddCofMintermAux (DdManager *dd, DdNode *node, st_table *table); /**AutomaticEnd***************************************************************/ @@ -90,7 +118,7 @@ static double * ddCofMintermAux ARGS((DdManager *dd, DdNode *node, st_table *tab 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 hs as many + 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 @@ -105,9 +133,9 @@ Cudd_CofMinterm( DdNode * node) { st_table *table; - double *values; - double *result = NULL; - int i, firstLevel; + double *values; + double *result = NULL; + int i, firstLevel; #ifdef DD_STATS long startTime; @@ -118,52 +146,52 @@ Cudd_CofMinterm( table = st_init_table(st_ptrcmp, st_ptrhash); if (table == NULL) { - (void) fprintf(dd->err, - "out-of-memory, couldn't measure DD cofactors.\n"); - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + (void) fprintf(dd->err, + "out-of-memory, couldn't measure DD cofactors.\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } size = dd->size; values = ddCofMintermAux(dd, node, table); if (values != NULL) { - result = ABC_ALLOC(double,size + 1); - if (result != NULL) { + result = ABC_ALLOC(double,size + 1); + if (result != NULL) { #ifdef DD_STATS - table_mem += (size + 1) * sizeof(double); + table_mem += (size + 1) * sizeof(double); #endif - if (Cudd_IsConstant(node)) - firstLevel = 1; - else - firstLevel = cuddI(dd,Cudd_Regular(node)->index); - for (i = 0; i < size; i++) { - if (i >= cuddI(dd,Cudd_Regular(node)->index)) { - result[dd->invperm[i]] = values[i - firstLevel]; + if (Cudd_IsConstant(node)) + firstLevel = 1; + else + firstLevel = cuddI(dd,Cudd_Regular(node)->index); + for (i = 0; i < size; i++) { + if (i >= cuddI(dd,Cudd_Regular(node)->index)) { + result[dd->invperm[i]] = values[i - firstLevel]; + } else { + result[dd->invperm[i]] = values[size - firstLevel]; + } + } + result[size] = values[size - firstLevel]; } else { - result[dd->invperm[i]] = values[size - firstLevel]; - } + dd->errorCode = CUDD_MEMORY_OUT; } - result[size] = values[size - firstLevel]; - } else { - dd->errorCode = CUDD_MEMORY_OUT; - } } #ifdef DD_STATS table_mem += table->num_bins * sizeof(st_table_entry *); #endif if (Cudd_Regular(node)->ref == 1) ABC_FREE(values); - st_foreach(table, (ST_PFSR)cuddStCountfree, NULL); + st_foreach(table, cuddStCountfree, NULL); st_free_table(table); #ifdef DD_STATS (void) fprintf(dd->out,"Number of calls: %d\tTable memory: %d bytes\n", - num_calls, table_mem); + num_calls, table_mem); (void) fprintf(dd->out,"Time to compute measures: %s\n", - util_print_time(util_cpu_time() - startTime)); + util_print_time(util_cpu_time() - startTime)); #endif if (result == NULL) { - (void) fprintf(dd->out, - "out-of-memory, couldn't measure DD cofactors.\n"); - dd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(dd->out, + "out-of-memory, couldn't measure DD cofactors.\n"); + dd->errorCode = CUDD_MEMORY_OUT; } return(result); @@ -206,92 +234,93 @@ ddCofMintermAux( DdNode * node, st_table * table) { - DdNode *N; /* regular version of node */ - DdNode *Nv, *Nnv; - double *values; - double *valuesT, *valuesE; - int i; - int localSize, localSizeT, localSizeE; - double vT, vE; + DdNode *N; /* regular version of node */ + DdNode *Nv, *Nnv; + double *values; + double *valuesT, *valuesE; + int i; + int localSize, localSizeT, localSizeE; + double vT, vE; statLine(dd); #ifdef DD_STATS num_calls++; #endif - if (st_lookup(table, (char *) node, (char **) &values)) { - return(values); + if (st_lookup(table, (const char *)node, (char **)&values)) { + return(values); } N = Cudd_Regular(node); if (cuddIsConstant(N)) { - localSize = 1; + localSize = 1; } else { - localSize = size - cuddI(dd,N->index) + 1; + localSize = size - cuddI(dd,N->index) + 1; } values = ABC_ALLOC(double, localSize); if (values == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } if (cuddIsConstant(N)) { - if (node == DD_ZERO(dd) || node == Cudd_Not(DD_ONE(dd))) { - values[0] = 0.0; - } else { - values[0] = 1.0; - } + if (node == DD_ZERO(dd) || node == Cudd_Not(DD_ONE(dd))) { + values[0] = 0.0; + } else { + values[0] = 1.0; + } } else { - Nv = Cudd_NotCond(cuddT(N),N!=node); - Nnv = Cudd_NotCond(cuddE(N),N!=node); + Nv = Cudd_NotCond(cuddT(N),N!=node); + Nnv = Cudd_NotCond(cuddE(N),N!=node); - valuesT = ddCofMintermAux(dd, Nv, table); - if (valuesT == NULL) return(NULL); - valuesE = ddCofMintermAux(dd, Nnv, table); - if (valuesE == NULL) return(NULL); + valuesT = ddCofMintermAux(dd, Nv, table); + if (valuesT == NULL) return(NULL); + valuesE = ddCofMintermAux(dd, Nnv, table); + if (valuesE == NULL) return(NULL); - if (Cudd_IsConstant(Nv)) { - localSizeT = 1; - } else { - localSizeT = size - cuddI(dd,Cudd_Regular(Nv)->index) + 1; - } - if (Cudd_IsConstant(Nnv)) { - localSizeE = 1; - } else { - localSizeE = size - cuddI(dd,Cudd_Regular(Nnv)->index) + 1; - } - values[0] = valuesT[localSizeT - 1]; - for (i = 1; i < localSize; i++) { - if (i >= cuddI(dd,Cudd_Regular(Nv)->index) - cuddI(dd,N->index)) { - vT = valuesT[i - cuddI(dd,Cudd_Regular(Nv)->index) + - cuddI(dd,N->index)]; + if (Cudd_IsConstant(Nv)) { + localSizeT = 1; } else { - vT = valuesT[localSizeT - 1]; + localSizeT = size - cuddI(dd,Cudd_Regular(Nv)->index) + 1; } - if (i >= cuddI(dd,Cudd_Regular(Nnv)->index) - cuddI(dd,N->index)) { - vE = valuesE[i - cuddI(dd,Cudd_Regular(Nnv)->index) + - cuddI(dd,N->index)]; + if (Cudd_IsConstant(Nnv)) { + localSizeE = 1; } else { - vE = valuesE[localSizeE - 1]; + localSizeE = size - cuddI(dd,Cudd_Regular(Nnv)->index) + 1; } - values[i] = (vT + vE) / 2.0; - } - if (Cudd_Regular(Nv)->ref == 1) ABC_FREE(valuesT); - if (Cudd_Regular(Nnv)->ref == 1) ABC_FREE(valuesE); + values[0] = valuesT[localSizeT - 1]; + for (i = 1; i < localSize; i++) { + if (i >= cuddI(dd,Cudd_Regular(Nv)->index) - cuddI(dd,N->index)) { + vT = valuesT[i - cuddI(dd,Cudd_Regular(Nv)->index) + + cuddI(dd,N->index)]; + } else { + vT = valuesT[localSizeT - 1]; + } + if (i >= cuddI(dd,Cudd_Regular(Nnv)->index) - cuddI(dd,N->index)) { + vE = valuesE[i - cuddI(dd,Cudd_Regular(Nnv)->index) + + cuddI(dd,N->index)]; + } else { + vE = valuesE[localSizeE - 1]; + } + values[i] = (vT + vE) / 2.0; + } + if (Cudd_Regular(Nv)->ref == 1) ABC_FREE(valuesT); + if (Cudd_Regular(Nnv)->ref == 1) ABC_FREE(valuesE); } if (N->ref > 1) { - if (st_add_direct(table, (char *) node, (char *) values) == ST_OUT_OF_MEM) { - ABC_FREE(values); - return(NULL); - } + if (st_add_direct(table, (char *) node, (char *) values) == ST_OUT_OF_MEM) { + ABC_FREE(values); + return(NULL); + } #ifdef DD_STATS - table_mem += localSize * sizeof(double) + sizeof(st_table_entry); + table_mem += localSize * sizeof(double) + sizeof(st_table_entry); #endif } return(values); } /* end of ddCofMintermAux */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddSolve.c b/src/bdd/cudd/cuddSolve.c index 18d29dac..47570bf1 100644 --- a/src/bdd/cudd/cuddSolve.c +++ b/src/bdd/cudd/cuddSolve.c @@ -7,24 +7,51 @@ Synopsis [Boolean equation solver and related functions.] Description [External functions included in this modoule: - <ul> - <li> Cudd_SolveEqn() - <li> Cudd_VerifySol() - </ul> - Internal functions included in this module: - <ul> - <li> cuddSolveEqnRecur() - <li> cuddVerifySol() - </ul> ] + <ul> + <li> Cudd_SolveEqn() + <li> Cudd_VerifySol() + </ul> + Internal functions included in this module: + <ul> + <li> cuddSolveEqnRecur() + <li> cuddVerifySol() + </ul> ] SeeAlso [] Author [Balakrishna Kumthekar] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -34,6 +61,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -54,7 +82,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddSolve.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddSolve.c,v 1.12 2004/08/13 18:04:51 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -108,15 +136,15 @@ Cudd_SolveEqn( *yIndex = temp = ABC_ALLOC(int, n); if (temp == NULL) { - bdd->errorCode = CUDD_MEMORY_OUT; - (void) fprintf(bdd->out, - "Cudd_SolveEqn: Out of memory for yIndex\n"); - return(NULL); + bdd->errorCode = CUDD_MEMORY_OUT; + (void) fprintf(bdd->out, + "Cudd_SolveEqn: Out of memory for yIndex\n"); + return(NULL); } do { - bdd->reordered = 0; - res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0); + bdd->reordered = 0; + res = cuddSolveEqnRecur(bdd, F, Y, G, n, temp, 0); } while (bdd->reordered == 1); return(res); @@ -148,8 +176,8 @@ Cudd_VerifySol( DdNode *res; do { - bdd->reordered = 0; - res = cuddVerifySol(bdd, F, G, yIndex, n); + bdd->reordered = 0; + res = cuddVerifySol(bdd, F, G, yIndex, n); } while (bdd->reordered == 1); ABC_FREE(yIndex); @@ -199,7 +227,7 @@ cuddSolveEqnRecur( /* Base condition. */ if (Y == one) { - return F; + return F; } /* Cofactor of Y. */ @@ -209,61 +237,61 @@ cuddSolveEqnRecur( /* Universal abstraction of F with respect to the top variable index. */ Fm1 = cuddBddExistAbstractRecur(bdd, Cudd_Not(F), variables[yIndex[i]]); if (Fm1) { - Fm1 = Cudd_Not(Fm1); - cuddRef(Fm1); + Fm1 = Cudd_Not(Fm1); + cuddRef(Fm1); } else { - return(NULL); + return(NULL); } Fn = cuddSolveEqnRecur(bdd, Fm1, nextY, G, n, yIndex, i+1); if (Fn) { - cuddRef(Fn); + cuddRef(Fn); } else { - Cudd_RecursiveDeref(bdd, Fm1); - return(NULL); + Cudd_RecursiveDeref(bdd, Fm1); + return(NULL); } Fv = cuddCofactorRecur(bdd, F, variables[yIndex[i]]); if (Fv) { - cuddRef(Fv); + cuddRef(Fv); } else { - Cudd_RecursiveDeref(bdd, Fm1); - Cudd_RecursiveDeref(bdd, Fn); - return(NULL); + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + return(NULL); } Fvbar = cuddCofactorRecur(bdd, F, Cudd_Not(variables[yIndex[i]])); if (Fvbar) { - cuddRef(Fvbar); + cuddRef(Fvbar); } else { - Cudd_RecursiveDeref(bdd, Fm1); - Cudd_RecursiveDeref(bdd, Fn); - Cudd_RecursiveDeref(bdd, Fv); - return(NULL); + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + return(NULL); } /* Build i-th component of the solution. */ w = cuddBddIteRecur(bdd, variables[yIndex[i]], Cudd_Not(Fv), Fvbar); if (w) { - cuddRef(w); + cuddRef(w); } else { - Cudd_RecursiveDeref(bdd, Fm1); - Cudd_RecursiveDeref(bdd, Fn); - Cudd_RecursiveDeref(bdd, Fv); - Cudd_RecursiveDeref(bdd, Fvbar); - return(NULL); + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + Cudd_RecursiveDeref(bdd, Fvbar); + return(NULL); } T = cuddBddRestrictRecur(bdd, w, Cudd_Not(Fm1)); if(T) { - cuddRef(T); + cuddRef(T); } else { - Cudd_RecursiveDeref(bdd, Fm1); - Cudd_RecursiveDeref(bdd, Fn); - Cudd_RecursiveDeref(bdd, Fv); - Cudd_RecursiveDeref(bdd, Fvbar); - Cudd_RecursiveDeref(bdd, w); - return(NULL); + Cudd_RecursiveDeref(bdd, Fm1); + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, Fv); + Cudd_RecursiveDeref(bdd, Fvbar); + Cudd_RecursiveDeref(bdd, w); + return(NULL); } Cudd_RecursiveDeref(bdd,Fm1); @@ -273,16 +301,16 @@ cuddSolveEqnRecur( /* Substitute components of solution already found into solution. */ for (j = n-1; j > i; j--) { - w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]); - if(w) { - cuddRef(w); - } else { - Cudd_RecursiveDeref(bdd, Fn); - Cudd_RecursiveDeref(bdd, T); - return(NULL); - } - Cudd_RecursiveDeref(bdd,T); - T = w; + w = cuddBddComposeRecur(bdd,T, G[j], variables[yIndex[j]]); + if(w) { + cuddRef(w); + } else { + Cudd_RecursiveDeref(bdd, Fn); + Cudd_RecursiveDeref(bdd, T); + return(NULL); + } + Cudd_RecursiveDeref(bdd,T); + T = w; } G[i] = T; @@ -319,14 +347,14 @@ cuddVerifySol( R = F; cuddRef(R); for(j = n - 1; j >= 0; j--) { - w = Cudd_bddCompose(bdd, R, G[j], yIndex[j]); - if (w) { - cuddRef(w); - } else { - return(NULL); - } - Cudd_RecursiveDeref(bdd,R); - R = w; + w = Cudd_bddCompose(bdd, R, G[j], yIndex[j]); + if (w) { + cuddRef(w); + } else { + return(NULL); + } + Cudd_RecursiveDeref(bdd,R); + R = w; } cuddDeref(R); @@ -340,5 +368,7 @@ cuddVerifySol( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddSplit.c b/src/bdd/cudd/cuddSplit.c index bad35d60..4ac243b5 100644 --- a/src/bdd/cudd/cuddSplit.c +++ b/src/bdd/cudd/cuddSplit.c @@ -7,28 +7,55 @@ Synopsis [Returns a subset of minterms from a boolean function.] Description [External functions included in this modoule: - <ul> - <li> Cudd_SplitSet() - </ul> - Internal functions included in this module: - <ul> - <li> cuddSplitSetRecur() - </u> + <ul> + <li> Cudd_SplitSet() + </ul> + Internal functions included in this module: + <ul> + <li> cuddSplitSetRecur() + </u> Static functions included in this module: - <ul> - <li> selectMintermsFromUniverse() - <li> mintermsFromUniverse() - <li> bddAnnotateMintermCount() - </ul> ] + <ul> + <li> selectMintermsFromUniverse() + <li> mintermsFromUniverse() + <li> bddAnnotateMintermCount() + </ul> ] SeeAlso [] Author [Balakrishna Kumthekar] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -38,6 +65,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -68,9 +96,9 @@ ABC_NAMESPACE_IMPL_START /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * selectMintermsFromUniverse ARGS((DdManager *manager, int *varSeen, double n)); -static DdNode * mintermsFromUniverse ARGS((DdManager *manager, DdNode **vars, int numVars, double n, int index)); -static double bddAnnotateMintermCount ARGS((DdManager *manager, DdNode *node, double max, st_table *table)); +static DdNode * selectMintermsFromUniverse (DdManager *manager, int *varSeen, double n); +static DdNode * mintermsFromUniverse (DdManager *manager, DdNode **vars, int numVars, double n, int index); +static double bddAnnotateMintermCount (DdManager *manager, DdNode *node, double max, st_table *table); /**AutomaticEnd***************************************************************/ @@ -117,69 +145,71 @@ Cudd_SplitSet( /* Trivial cases. */ if (m == 0.0) { - return(zero); + return(zero); } if (S == zero) { - return(NULL); + return(NULL); } max = pow(2.0,(double)n); if (m > max) - return(NULL); - - do { - manager->reordered = 0; - /* varSeen is used to mark the variables that are encountered - ** while traversing the BDD S. - */ - varSeen = ABC_ALLOC(int, size); - if (varSeen == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; return(NULL); - } - for (i = 0; i < size; i++) { - varSeen[i] = -1; - } - for (i = 0; i < n; i++) { - index = (xVars[i])->index; - varSeen[manager->invperm[index]] = 0; - } - if (S == one) { - if (m == max) - return(S); - result = selectMintermsFromUniverse(manager,varSeen,m); - if (result) - cuddRef(result); - ABC_FREE(varSeen); - } else { - mtable = st_init_table(st_ptrcmp, st_ptrhash);; - if (mtable == NULL) { - (void) fprintf(manager->out, - "Cudd_SplitSet: out-of-memory.\n"); - ABC_FREE(varSeen); - manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - /* The nodes of BDD S are annotated by the number of minterms - ** in their onset. The node and the number of minterms in its - ** onset are stored in mtable. + do { + manager->reordered = 0; + /* varSeen is used to mark the variables that are encountered + ** while traversing the BDD S. */ - num = bddAnnotateMintermCount(manager,S,max,mtable); - if (m == num) { - st_foreach(mtable,(ST_PFSR)cuddStCountfree,NIL(char)); - st_free_table(mtable); - ABC_FREE(varSeen); - return(S); + varSeen = ABC_ALLOC(int, size); + if (varSeen == NULL) { + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (i = 0; i < size; i++) { + varSeen[i] = -1; + } + for (i = 0; i < n; i++) { + index = (xVars[i])->index; + varSeen[manager->invperm[index]] = 0; + } + + if (S == one) { + if (m == max) { + ABC_FREE(varSeen); + return(S); + } + result = selectMintermsFromUniverse(manager,varSeen,m); + if (result) + cuddRef(result); + ABC_FREE(varSeen); + } else { + mtable = st_init_table(st_ptrcmp,st_ptrhash); + if (mtable == NULL) { + (void) fprintf(manager->out, + "Cudd_SplitSet: out-of-memory.\n"); + ABC_FREE(varSeen); + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + /* The nodes of BDD S are annotated by the number of minterms + ** in their onset. The node and the number of minterms in its + ** onset are stored in mtable. + */ + num = bddAnnotateMintermCount(manager,S,max,mtable); + if (m == num) { + st_foreach(mtable,cuddStCountfree,NIL(char)); + st_free_table(mtable); + ABC_FREE(varSeen); + return(S); + } + + result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0); + if (result) + cuddRef(result); + st_foreach(mtable,cuddStCountfree,NULL); + st_free_table(mtable); + ABC_FREE(varSeen); } - - result = cuddSplitSetRecur(manager,mtable,varSeen,S,m,max,0); - if (result) - cuddRef(result); - st_foreach(mtable,(ST_PFSR)cuddStCountfree,NULL); - st_free_table(mtable); - ABC_FREE(varSeen); - } } while (manager->reordered == 1); cuddDeref(result); @@ -238,8 +268,8 @@ cuddSplitSetRecur( ** constant 0. */ if (Cudd_IsConstant(p)) { - q = selectMintermsFromUniverse(manager,varSeen,n); - return(q); + q = selectMintermsFromUniverse(manager,varSeen,n); + return(q); } N = Cudd_Regular(p); @@ -251,47 +281,47 @@ cuddSplitSetRecur( Nv = cuddT(N); Nnv = cuddE(N); if (Cudd_IsComplement(p)) { - Nv = Cudd_Not(Nv); - Nnv = Cudd_Not(Nnv); + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); } /* If both the children of 'p' are constants, extract n minterms from a ** constant node. */ if (Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) { - q = selectMintermsFromUniverse(manager,varSeen,n); - if (q == NULL) { - return(NULL); - } - cuddRef(q); - r = cuddBddAndRecur(manager,p,q); - if (r == NULL) { + q = selectMintermsFromUniverse(manager,varSeen,n); + if (q == NULL) { + return(NULL); + } + cuddRef(q); + r = cuddBddAndRecur(manager,p,q); + if (r == NULL) { + Cudd_RecursiveDeref(manager,q); + return(NULL); + } + cuddRef(r); Cudd_RecursiveDeref(manager,q); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDeref(manager,q); - cuddDeref(r); - return(r); + cuddDeref(r); + return(r); } /* Lookup the # of minterms in the onset of the node from the table. */ if (!Cudd_IsConstant(Nv)) { - st_lookup(mtable,(char *)Nv, (char **)&dummy); - numT = *dummy/(2*(1<<index)); + if (!st_lookup(mtable, (const char *)Nv, (char **)&dummy)) return(NULL); + numT = *dummy/(2*(1<<index)); } else if (Nv == one) { - numT = max/(2*(1<<index)); + numT = max/(2*(1<<index)); } else { - numT = 0; + numT = 0; } if (!Cudd_IsConstant(Nnv)) { - st_lookup(mtable,(char *)Nnv, (char **)&dummy); - numE = *dummy/(2*(1<<index)); + if (!st_lookup(mtable, (const char *)Nnv, (char **)&dummy)) return(NULL); + numE = *dummy/(2*(1<<index)); } else if (Nnv == one) { - numE = max/(2*(1<<index)); + numE = max/(2*(1<<index)); } else { - numE = 0; + numE = 0; } v = cuddUniqueInter(manager,variable,one,zero); @@ -299,72 +329,72 @@ cuddSplitSetRecur( /* If perfect match. */ if (numT == n) { - q = cuddBddAndRecur(manager,v,Nv); - if (q == NULL) { + q = cuddBddAndRecur(manager,v,Nv); + if (q == NULL) { + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(q); Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(q); - return(q); + cuddDeref(q); + return(q); } if (numE == n) { - q = cuddBddAndRecur(manager,Cudd_Not(v),Nnv); - if (q == NULL) { + q = cuddBddAndRecur(manager,Cudd_Not(v),Nnv); + if (q == NULL) { + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(q); Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(q); - return(q); + cuddDeref(q); + return(q); } /* If n is greater than numT, extract the difference from the ELSE child ** and retain the function represented by the THEN branch. */ if (numT < n) { - q = cuddSplitSetRecur(manager,mtable,varSeen, - Nnv,(n-numT),max,index+1); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - r = cuddBddIteRecur(manager,v,Nv,q); - if (r == NULL) { + q = cuddSplitSetRecur(manager,mtable,varSeen, + Nnv,(n-numT),max,index+1); + if (q == NULL) { + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(q); + r = cuddBddIteRecur(manager,v,Nv,q); + if (r == NULL) { + Cudd_RecursiveDeref(manager,q); + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(r); Cudd_RecursiveDeref(manager,q); Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(r); - return(r); + cuddDeref(r); + return(r); } /* If n is greater than numE, extract the difference from the THEN child ** and retain the function represented by the ELSE branch. */ if (numE < n) { - q = cuddSplitSetRecur(manager,mtable,varSeen, - Nv, (n-numE),max,index+1); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - r = cuddBddIteRecur(manager,v,q,Nnv); - if (r == NULL) { + q = cuddSplitSetRecur(manager,mtable,varSeen, + Nv, (n-numE),max,index+1); + if (q == NULL) { + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(q); + r = cuddBddIteRecur(manager,v,q,Nnv); + if (r == NULL) { + Cudd_RecursiveDeref(manager,q); + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(r); Cudd_RecursiveDeref(manager,q); Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(r); - return(r); + cuddDeref(r); + return(r); } /* None of the above cases; (n < numT and n < numE) and either of @@ -372,41 +402,41 @@ cuddSplitSetRecur( ** required minterms the constant branch. */ if (Cudd_IsConstant(Nv) && !Cudd_IsConstant(Nnv)) { - q = selectMintermsFromUniverse(manager,varSeen,n); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - result = cuddBddAndRecur(manager,v,q); - if (result == NULL) { + q = selectMintermsFromUniverse(manager,varSeen,n); + if (q == NULL) { + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(q); + result = cuddBddAndRecur(manager,v,q); + if (result == NULL) { + Cudd_RecursiveDeref(manager,q); + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(result); Cudd_RecursiveDeref(manager,q); Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(result); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(result); - return(result); + cuddDeref(result); + return(result); } else if (!Cudd_IsConstant(Nv) && Cudd_IsConstant(Nnv)) { - q = selectMintermsFromUniverse(manager,varSeen,n); - if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(q); - result = cuddBddAndRecur(manager,Cudd_Not(v),q); - if (result == NULL) { + q = selectMintermsFromUniverse(manager,varSeen,n); + if (q == NULL) { + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(q); + result = cuddBddAndRecur(manager,Cudd_Not(v),q); + if (result == NULL) { + Cudd_RecursiveDeref(manager,q); + Cudd_RecursiveDeref(manager,v); + return(NULL); + } + cuddRef(result); Cudd_RecursiveDeref(manager,q); Cudd_RecursiveDeref(manager,v); - return(NULL); - } - cuddRef(result); - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - cuddDeref(result); - return(result); + cuddDeref(result); + return(result); } /* Both Nv and Nnv are not constants. So choose the one which @@ -414,29 +444,29 @@ cuddSplitSetRecur( */ positive = 0; if (numT < numE) { - q = cuddSplitSetRecur(manager,mtable,varSeen, - Nv,n,max,index+1); - positive = 1; + q = cuddSplitSetRecur(manager,mtable,varSeen, + Nv,n,max,index+1); + positive = 1; } else { - q = cuddSplitSetRecur(manager,mtable,varSeen, - Nnv,n,max,index+1); + q = cuddSplitSetRecur(manager,mtable,varSeen, + Nnv,n,max,index+1); } if (q == NULL) { - Cudd_RecursiveDeref(manager,v); - return(NULL); + Cudd_RecursiveDeref(manager,v); + return(NULL); } cuddRef(q); if (positive) { - result = cuddBddAndRecur(manager,v,q); + result = cuddBddAndRecur(manager,v,q); } else { - result = cuddBddAndRecur(manager,Cudd_Not(v),q); + result = cuddBddAndRecur(manager,Cudd_Not(v),q); } if (result == NULL) { - Cudd_RecursiveDeref(manager,q); - Cudd_RecursiveDeref(manager,v); - return(NULL); + Cudd_RecursiveDeref(manager,q); + Cudd_RecursiveDeref(manager,v); + return(NULL); } cuddRef(result); Cudd_RecursiveDeref(manager,q); @@ -485,22 +515,22 @@ selectMintermsFromUniverse( ** cuddSplitSetRecur. */ for (i = size-1; i >= 0; i--) { - if(varSeen[i] == 0) - numVars++; + if(varSeen[i] == 0) + numVars++; } vars = ABC_ALLOC(DdNode *, numVars); if (!vars) { - manager->errorCode = CUDD_MEMORY_OUT; - return(NULL); + manager->errorCode = CUDD_MEMORY_OUT; + return(NULL); } j = 0; for (i = size-1; i >= 0; i--) { - if(varSeen[i] == 0) { - vars[j] = cuddUniqueInter(manager,manager->perm[i],one,zero); - cuddRef(vars[j]); - j++; - } + if(varSeen[i] == 0) { + vars[j] = cuddUniqueInter(manager,manager->perm[i],one,zero); + cuddRef(vars[j]); + j++; + } } /* Compute a function which has n minterms and depends on at most @@ -508,10 +538,10 @@ selectMintermsFromUniverse( */ result = mintermsFromUniverse(manager,vars,numVars,n, 0); if (result) - cuddRef(result); + cuddRef(result); for (i = 0; i < numVars; i++) - Cudd_RecursiveDeref(manager,vars[i]); + Cudd_RecursiveDeref(manager,vars[i]); ABC_FREE(vars); return(result); @@ -548,37 +578,37 @@ mintermsFromUniverse( max2 = max / 2.0; if (n == max) - return(one); + return(one); if (n == 0.0) - return(zero); + return(zero); /* if n == 2^(numVars-1), return a single variable */ if (n == max2) - return vars[index]; + return vars[index]; else if (n > max2) { - /* When n > 2^(numVars-1), a single variable vars[index] - ** contains 2^(numVars-1) minterms. The rest are extracted - ** from a constant with 1 less variable. - */ - q = mintermsFromUniverse(manager,vars,numVars-1,(n-max2),index+1); - if (q == NULL) - return(NULL); - cuddRef(q); - result = cuddBddIteRecur(manager,vars[index],one,q); + /* When n > 2^(numVars-1), a single variable vars[index] + ** contains 2^(numVars-1) minterms. The rest are extracted + ** from a constant with 1 less variable. + */ + q = mintermsFromUniverse(manager,vars,numVars-1,(n-max2),index+1); + if (q == NULL) + return(NULL); + cuddRef(q); + result = cuddBddIteRecur(manager,vars[index],one,q); } else { - /* When n < 2^(numVars-1), a literal of variable vars[index] - ** is selected. The required n minterms are extracted from a - ** constant with 1 less variable. - */ - q = mintermsFromUniverse(manager,vars,numVars-1,n,index+1); - if (q == NULL) - return(NULL); - cuddRef(q); - result = cuddBddAndRecur(manager,vars[index],q); + /* When n < 2^(numVars-1), a literal of variable vars[index] + ** is selected. The required n minterms are extracted from a + ** constant with 1 less variable. + */ + q = mintermsFromUniverse(manager,vars,numVars-1,n,index+1); + if (q == NULL) + return(NULL); + cuddRef(q); + result = cuddBddAndRecur(manager,vars[index],q); } if (result == NULL) { - Cudd_RecursiveDeref(manager,q); - return(NULL); + Cudd_RecursiveDeref(manager,q); + return(NULL); } cuddRef(result); Cudd_RecursiveDeref(manager,q); @@ -616,47 +646,49 @@ bddAnnotateMintermCount( statLine(manager); N = Cudd_Regular(node); if (cuddIsConstant(N)) { - if (node == DD_ONE(manager)) { - return(max); - } else { - return(0.0); - } + if (node == DD_ONE(manager)) { + return(max); + } else { + return(0.0); + } } - if (st_lookup(table,(char *)node,(char **)&dummy)) { - return(*dummy); - } + if (st_lookup(table, (const char *)node, (char **)&dummy)) { + return(*dummy); + } Nv = cuddT(N); Nnv = cuddE(N); if (N != node) { - Nv = Cudd_Not(Nv); - Nnv = Cudd_Not(Nnv); + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); } /* Recur on the two branches. */ min_v = bddAnnotateMintermCount(manager,Nv,max,table) / 2.0; if (min_v == (double)CUDD_OUT_OF_MEM) - return ((double)CUDD_OUT_OF_MEM); + return ((double)CUDD_OUT_OF_MEM); min_nv = bddAnnotateMintermCount(manager,Nnv,max,table) / 2.0; if (min_nv == (double)CUDD_OUT_OF_MEM) - return ((double)CUDD_OUT_OF_MEM); + return ((double)CUDD_OUT_OF_MEM); min_N = min_v + min_nv; pmin = ABC_ALLOC(double,1); if (pmin == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return((double)CUDD_OUT_OF_MEM); + manager->errorCode = CUDD_MEMORY_OUT; + return((double)CUDD_OUT_OF_MEM); } *pmin = min_N; if (st_insert(table,(char *)node, (char *)pmin) == ST_OUT_OF_MEM) { - ABC_FREE(pmin); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(pmin); + return((double)CUDD_OUT_OF_MEM); } return(min_N); } /* end of bddAnnotateMintermCount */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddSubsetHB.c b/src/bdd/cudd/cuddSubsetHB.c index 86ed380f..68902b09 100644 --- a/src/bdd/cudd/cuddSubsetHB.c +++ b/src/bdd/cudd/cuddSubsetHB.c @@ -5,39 +5,66 @@ PackageName [cudd] Synopsis [Procedure to subset the given BDD by choosing the heavier - branches] + branches.] Description [External procedures provided by this module: <ul> - <li> Cudd_SubsetHeavyBranch() - <li> Cudd_SupersetHeavyBranch() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddSubsetHeavyBranch() - </ul> - Static procedures included in this module: - <ul> - <li> ResizeCountMintermPages(); - <li> ResizeNodeDataPages() - <li> ResizeCountNodePages() - <li> SubsetCountMintermAux() - <li> SubsetCountMinterm() - <li> SubsetCountNodesAux() - <li> SubsetCountNodes() - <li> BuildSubsetBdd() - </ul> - ] + <li> Cudd_SubsetHeavyBranch() + <li> Cudd_SupersetHeavyBranch() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddSubsetHeavyBranch() + </ul> + Static procedures included in this module: + <ul> + <li> ResizeCountMintermPages(); + <li> ResizeNodeDataPages() + <li> ResizeCountNodePages() + <li> SubsetCountMintermAux() + <li> SubsetCountMinterm() + <li> SubsetCountNodesAux() + <li> SubsetCountNodes() + <li> BuildSubsetBdd() + </ul> + ] SeeAlso [cuddSubsetSP.c] Author [Kavita Ravi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no - warranty about the suitability of this software for any - purpose. It is presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -52,12 +79,13 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ -#define DEFAULT_PAGE_SIZE 2048 -#define DEFAULT_NODE_DATA_PAGE_SIZE 1024 +#define DEFAULT_PAGE_SIZE 2048 +#define DEFAULT_NODE_DATA_PAGE_SIZE 1024 #define INITIAL_PAGES 128 @@ -89,38 +117,38 @@ typedef struct NodeData NodeData_t; /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddSubsetHB.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddSubsetHB.c,v 1.37 2009/02/20 02:14:58 fabio Exp $"; #endif static int memOut; #ifdef DEBUG -static int num_calls; +static int num_calls; #endif -static DdNode *zero, *one; /* constant functions */ -static double **mintermPages; /* pointers to the pages */ -static int **nodePages; /* pointers to the pages */ -static int **lightNodePages; /* pointers to the pages */ -static double *currentMintermPage; /* pointer to the current - page */ -static double max; /* to store the 2^n value of the number - * of variables */ - -static int *currentNodePage; /* pointer to the current - page */ -static int *currentLightNodePage; /* pointer to the - * current page */ -static int pageIndex; /* index to next element */ -static int page; /* index to current page */ -static int pageSize = DEFAULT_PAGE_SIZE; /* page size */ +static DdNode *zero, *one; /* constant functions */ +static double **mintermPages; /* pointers to the pages */ +static int **nodePages; /* pointers to the pages */ +static int **lightNodePages; /* pointers to the pages */ +static double *currentMintermPage; /* pointer to the current + page */ +static double max; /* to store the 2^n value of the number + * of variables */ + +static int *currentNodePage; /* pointer to the current + page */ +static int *currentLightNodePage; /* pointer to the + * current page */ +static int pageIndex; /* index to next element */ +static int page; /* index to current page */ +static int pageSize = DEFAULT_PAGE_SIZE; /* page size */ static int maxPages; /* number of page pointers */ -static NodeData_t *currentNodeDataPage; /* pointer to the current - page */ -static int nodeDataPage; /* index to next element */ -static int nodeDataPageIndex; /* index to next element */ -static NodeData_t **nodeDataPages; /* index to current page */ -static int nodeDataPageSize = DEFAULT_NODE_DATA_PAGE_SIZE; +static NodeData_t *currentNodeDataPage; /* pointer to the current + page */ +static int nodeDataPage; /* index to next element */ +static int nodeDataPageIndex; /* index to next element */ +static NodeData_t **nodeDataPages; /* index to current page */ +static int nodeDataPageSize = DEFAULT_NODE_DATA_PAGE_SIZE; /* page size */ static int maxNodeDataPages; /* number of page pointers */ @@ -135,15 +163,15 @@ static int maxNodeDataPages; /* number of page pointers */ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void ResizeNodeDataPages ARGS(()); -static void ResizeCountMintermPages ARGS(()); -static void ResizeCountNodePages ARGS(()); -static double SubsetCountMintermAux ARGS((DdNode *node, double max, st_table *table)); -static st_table * SubsetCountMinterm ARGS((DdNode *node, int nvars)); -static int SubsetCountNodesAux ARGS((DdNode *node, st_table *table, double max)); -static int SubsetCountNodes ARGS((DdNode *node, st_table *table, int nvars)); -static void StoreNodes ARGS((st_table *storeTable, DdManager *dd, DdNode *node)); -static DdNode * BuildSubsetBdd ARGS((DdManager *dd, DdNode *node, int *size, st_table *visitedTable, int threshold, st_table *storeTable, st_table *approxTable)); +static void ResizeNodeDataPages (void); +static void ResizeCountMintermPages (void); +static void ResizeCountNodePages (void); +static double SubsetCountMintermAux (DdNode *node, double max, st_table *table); +static st_table * SubsetCountMinterm (DdNode *node, int nvars); +static int SubsetCountNodesAux (DdNode *node, st_table *table, double max); +static int SubsetCountNodes (DdNode *node, st_table *table, int nvars); +static void StoreNodes (st_table *storeTable, DdManager *dd, DdNode *node); +static DdNode * BuildSubsetBdd (DdManager *dd, DdNode *node, int *size, st_table *visitedTable, int threshold, st_table *storeTable, st_table *approxTable); /**AutomaticEnd***************************************************************/ @@ -188,8 +216,8 @@ Cudd_SubsetHeavyBranch( memOut = 0; do { - dd->reordered = 0; - subset = cuddSubsetHeavyBranch(dd, f, numVars, threshold); + dd->reordered = 0; + subset = cuddSubsetHeavyBranch(dd, f, numVars, threshold); } while ((dd->reordered == 1) && (!memOut)); return(subset); @@ -236,15 +264,15 @@ Cudd_SupersetHeavyBranch( { DdNode *subset, *g; - g = Cudd_Not(f); + g = Cudd_Not(f); memOut = 0; do { - dd->reordered = 0; - subset = cuddSubsetHeavyBranch(dd, g, numVars, threshold); + dd->reordered = 0; + subset = cuddSubsetHeavyBranch(dd, g, numVars, threshold); } while ((dd->reordered == 1) && (!memOut)); - + return(Cudd_NotCond(subset, (subset != NULL))); - + } /* end of Cudd_SupersetHeavyBranch */ @@ -286,18 +314,17 @@ cuddSubsetHeavyBranch( int numNodes; NodeData_t *currNodeQual; DdNode *subset; - double minN; st_table *storeTable, *approxTable; char *key, *value; st_generator *stGen; - + if (f == NULL) { - fprintf(dd->err, "Cannot subset, nil object\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); + fprintf(dd->err, "Cannot subset, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); } - one = Cudd_ReadOne(dd); + one = Cudd_ReadOne(dd); zero = Cudd_Not(one); /* If user does not know numVars value, set it to the maximum @@ -306,12 +333,12 @@ cuddSubsetHeavyBranch( * log gives. */ if (numVars == 0) { - /* set default value */ - numVars = DBL_MAX_EXP - 1; + /* set default value */ + numVars = DBL_MAX_EXP - 1; } if (Cudd_IsConstant(f)) { - return(f); + return(f); } max = pow(2.0, (double)numVars); @@ -320,29 +347,27 @@ cuddSubsetHeavyBranch( stored in a st_table */ visitedTable = SubsetCountMinterm(f, numVars); if ((visitedTable == NULL) || memOut) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } numNodes = SubsetCountNodes(f, visitedTable, numVars); if (memOut) { - (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + (void) fprintf(dd->err, "Out-of-memory; Cannot subset\n"); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } - if (st_lookup(visitedTable, (char *)f, (char **)&currNodeQual)) { - minN = *(((NodeData_t *)currNodeQual)->mintermPointer); - } else { - fprintf(dd->err, - "Something is wrong, ought to be node quality table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; + if (st_lookup(visitedTable, (const char *)f, (char **)&currNodeQual) == 0) { + fprintf(dd->err, + "Something is wrong, ought to be node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; } size = ABC_ALLOC(int, 1); if (size == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } *size = numNodes; @@ -354,53 +379,53 @@ cuddSubsetHeavyBranch( /* insert the constant */ cuddRef(one); if (st_insert(storeTable, (char *)Cudd_ReadOne(dd), NIL(char)) == - ST_OUT_OF_MEM) { - fprintf(dd->out, "Something wrong, st_table insert failed\n"); + ST_OUT_OF_MEM) { + fprintf(dd->out, "Something wrong, st_table insert failed\n"); } /* table to store approximations of nodes */ approxTable = st_init_table(st_ptrcmp, st_ptrhash); subset = (DdNode *)BuildSubsetBdd(dd, f, size, visitedTable, threshold, - storeTable, approxTable); + storeTable, approxTable); if (subset != NULL) { - cuddRef(subset); + cuddRef(subset); } stGen = st_init_gen(approxTable); if (stGen == NULL) { - st_free_table(approxTable); - return(NULL); + st_free_table(approxTable); + return(NULL); } while(st_gen(stGen, (const char **)&key, (char **)&value)) { - Cudd_RecursiveDeref(dd, (DdNode *)value); + Cudd_RecursiveDeref(dd, (DdNode *)value); } st_free_gen(stGen); stGen = NULL; st_free_table(approxTable); stGen = st_init_gen(storeTable); if (stGen == NULL) { - st_free_table(storeTable); - return(NULL); + st_free_table(storeTable); + return(NULL); } while(st_gen(stGen, (const char **)&key, (char **)&value)) { - Cudd_RecursiveDeref(dd, (DdNode *)key); + Cudd_RecursiveDeref(dd, (DdNode *)key); } st_free_gen(stGen); stGen = NULL; st_free_table(storeTable); for (i = 0; i <= page; i++) { - ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages[i]); } ABC_FREE(mintermPages); for (i = 0; i <= page; i++) { - ABC_FREE(nodePages[i]); + ABC_FREE(nodePages[i]); } ABC_FREE(nodePages); for (i = 0; i <= page; i++) { - ABC_FREE(lightNodePages[i]); + ABC_FREE(lightNodePages[i]); } ABC_FREE(lightNodePages); for (i = 0; i <= nodeDataPage; i++) { - ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages[i]); } ABC_FREE(nodeDataPages); st_free_table(visitedTable); @@ -413,9 +438,9 @@ cuddSubsetHeavyBranch( if (subset != NULL) { #ifdef DD_DEBUG if (!Cudd_bddLeq(dd, subset, f)) { - fprintf(dd->err, "Wrong subset\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + fprintf(dd->err, "Wrong subset\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } #endif cuddDeref(subset); @@ -446,8 +471,7 @@ cuddSubsetHeavyBranch( ******************************************************************************/ static void -ResizeNodeDataPages( - ) +ResizeNodeDataPages(void) { int i; NodeData_t **newNodeDataPages; @@ -458,30 +482,30 @@ ResizeNodeDataPages( * INITIAL_PAGES */ if (nodeDataPage == maxNodeDataPages) { - newNodeDataPages = ABC_ALLOC(NodeData_t *,maxNodeDataPages + INITIAL_PAGES); - if (newNodeDataPages == NULL) { - for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - memOut = 1; - return; - } else { - for (i = 0; i < maxNodeDataPages; i++) { - newNodeDataPages[i] = nodeDataPages[i]; + newNodeDataPages = ABC_ALLOC(NodeData_t *,maxNodeDataPages + INITIAL_PAGES); + if (newNodeDataPages == NULL) { + for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + memOut = 1; + return; + } else { + for (i = 0; i < maxNodeDataPages; i++) { + newNodeDataPages[i] = nodeDataPages[i]; + } + /* Increase total page count */ + maxNodeDataPages += INITIAL_PAGES; + ABC_FREE(nodeDataPages); + nodeDataPages = newNodeDataPages; } - /* Increase total page count */ - maxNodeDataPages += INITIAL_PAGES; - ABC_FREE(nodeDataPages); - nodeDataPages = newNodeDataPages; - } } /* Allocate a new page */ currentNodeDataPage = nodeDataPages[nodeDataPage] = - ABC_ALLOC(NodeData_t ,nodeDataPageSize); + ABC_ALLOC(NodeData_t ,nodeDataPageSize); if (currentNodeDataPage == NULL) { - for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - memOut = 1; - return; + for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + memOut = 1; + return; } /* reset page index */ nodeDataPageIndex = 0; @@ -499,15 +523,14 @@ ResizeNodeDataPages( counts. The procedure moves the counter to the next page when the end of the page is reached and allocates new pages when necessary.] - SideEffects [Changes the size of minterm pages, page, page index, maximum + SideEffects [Changes the size of minterm pages, page, page index, maximum number of pages freeing stuff in case of memory out. ] SeeAlso [] ******************************************************************************/ static void -ResizeCountMintermPages( - ) +ResizeCountMintermPages(void) { int i; double **newMintermPages; @@ -518,29 +541,29 @@ ResizeCountMintermPages( * INITIAL_PAGES */ if (page == maxPages) { - newMintermPages = ABC_ALLOC(double *,maxPages + INITIAL_PAGES); - if (newMintermPages == NULL) { - for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - memOut = 1; - return; - } else { - for (i = 0; i < maxPages; i++) { - newMintermPages[i] = mintermPages[i]; + newMintermPages = ABC_ALLOC(double *,maxPages + INITIAL_PAGES); + if (newMintermPages == NULL) { + for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newMintermPages[i] = mintermPages[i]; + } + /* Increase total page count */ + maxPages += INITIAL_PAGES; + ABC_FREE(mintermPages); + mintermPages = newMintermPages; } - /* Increase total page count */ - maxPages += INITIAL_PAGES; - ABC_FREE(mintermPages); - mintermPages = newMintermPages; - } } /* Allocate a new page */ currentMintermPage = mintermPages[page] = ABC_ALLOC(double,pageSize); if (currentMintermPage == NULL) { - for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - memOut = 1; - return; + for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + memOut = 1; + return; } /* reset page index */ pageIndex = 0; @@ -564,8 +587,7 @@ ResizeCountMintermPages( ******************************************************************************/ static void -ResizeCountNodePages( - ) +ResizeCountNodePages(void) { int i; int **newNodePages; @@ -577,59 +599,59 @@ ResizeCountNodePages( * by INITIAL_PAGES. */ if (page == maxPages) { - newNodePages = ABC_ALLOC(int *,maxPages + INITIAL_PAGES); - if (newNodePages == NULL) { - for (i = 0; i < page; i++) ABC_FREE(nodePages[i]); - ABC_FREE(nodePages); - for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); - ABC_FREE(lightNodePages); - memOut = 1; - return; - } else { - for (i = 0; i < maxPages; i++) { - newNodePages[i] = nodePages[i]; + newNodePages = ABC_ALLOC(int *,maxPages + INITIAL_PAGES); + if (newNodePages == NULL) { + for (i = 0; i < page; i++) ABC_FREE(nodePages[i]); + ABC_FREE(nodePages); + for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); + ABC_FREE(lightNodePages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newNodePages[i] = nodePages[i]; + } + ABC_FREE(nodePages); + nodePages = newNodePages; } - ABC_FREE(nodePages); - nodePages = newNodePages; - } - newNodePages = ABC_ALLOC(int *,maxPages + INITIAL_PAGES); - if (newNodePages == NULL) { + newNodePages = ABC_ALLOC(int *,maxPages + INITIAL_PAGES); + if (newNodePages == NULL) { + for (i = 0; i < page; i++) ABC_FREE(nodePages[i]); + ABC_FREE(nodePages); + for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); + ABC_FREE(lightNodePages); + memOut = 1; + return; + } else { + for (i = 0; i < maxPages; i++) { + newNodePages[i] = lightNodePages[i]; + } + ABC_FREE(lightNodePages); + lightNodePages = newNodePages; + } + /* Increase total page count */ + maxPages += INITIAL_PAGES; + } + /* Allocate a new page */ + currentNodePage = nodePages[page] = ABC_ALLOC(int,pageSize); + if (currentNodePage == NULL) { for (i = 0; i < page; i++) ABC_FREE(nodePages[i]); ABC_FREE(nodePages); for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); ABC_FREE(lightNodePages); memOut = 1; return; - } else { - for (i = 0; i < maxPages; i++) { - newNodePages[i] = lightNodePages[i]; - } - ABC_FREE(lightNodePages); - lightNodePages = newNodePages; - } - /* Increase total page count */ - maxPages += INITIAL_PAGES; - } - /* Allocate a new page */ - currentNodePage = nodePages[page] = ABC_ALLOC(int,pageSize); - if (currentNodePage == NULL) { - for (i = 0; i < page; i++) ABC_FREE(nodePages[i]); - ABC_FREE(nodePages); - for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); - ABC_FREE(lightNodePages); - memOut = 1; - return; } /* Allocate a new page */ currentLightNodePage = lightNodePages[page] = ABC_ALLOC(int,pageSize); if (currentLightNodePage == NULL) { - for (i = 0; i <= page; i++) ABC_FREE(nodePages[i]); - ABC_FREE(nodePages); - for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); - ABC_FREE(lightNodePages); - memOut = 1; - return; + for (i = 0; i <= page; i++) ABC_FREE(nodePages[i]); + ABC_FREE(nodePages); + for (i = 0; i < page; i++) ABC_FREE(lightNodePages[i]); + ABC_FREE(lightNodePages); + memOut = 1; + return; } /* reset page index */ pageIndex = 0; @@ -661,9 +683,9 @@ SubsetCountMintermAux( st_table * table /* visitedTable table */) { - DdNode *N,*Nv,*Nnv; /* nodes to store cofactors */ - double min,*pmin; /* minterm count */ - double min1, min2; /* minterm count */ + DdNode *N,*Nv,*Nnv; /* nodes to store cofactors */ + double min,*pmin; /* minterm count */ + double min1, min2; /* minterm count */ NodeData_t *dummy; NodeData_t *newEntry; int i; @@ -674,79 +696,79 @@ SubsetCountMintermAux( /* Constant case */ if (Cudd_IsConstant(node)) { - if (node == zero) { - return(0.0); - } else { - return(max); - } + if (node == zero) { + return(0.0); + } else { + return(max); + } } else { - /* check if entry for this node exists */ - if (st_lookup(table,(char *)node, (char **)&dummy)) { - min = *(dummy->mintermPointer); - return(min); - } - - /* Make the node regular to extract cofactors */ - N = Cudd_Regular(node); - - /* store the cofactors */ - Nv = Cudd_T(N); - Nnv = Cudd_E(N); - - Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); - Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); - - min1 = SubsetCountMintermAux(Nv, max,table)/2.0; - if (memOut) return(0.0); - min2 = SubsetCountMintermAux(Nnv,max,table)/2.0; - if (memOut) return(0.0); - min = (min1+min2); - - /* if page index is at the bottom, then create a new page */ - if (pageIndex == pageSize) ResizeCountMintermPages(); - if (memOut) { - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - st_free_table(table); - return(0.0); - } - - /* point to the correct location in the page */ - pmin = currentMintermPage+pageIndex; - pageIndex++; + /* check if entry for this node exists */ + if (st_lookup(table, (const char *)node, (char **)&dummy)) { + min = *(dummy->mintermPointer); + return(min); + } - /* store the minterm count of this node in the page */ - *pmin = min; + /* Make the node regular to extract cofactors */ + N = Cudd_Regular(node); + + /* store the cofactors */ + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + min1 = SubsetCountMintermAux(Nv, max,table)/2.0; + if (memOut) return(0.0); + min2 = SubsetCountMintermAux(Nnv,max,table)/2.0; + if (memOut) return(0.0); + min = (min1+min2); + + /* if page index is at the bottom, then create a new page */ + if (pageIndex == pageSize) ResizeCountMintermPages(); + if (memOut) { + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + st_free_table(table); + return(0.0); + } - /* Note I allocate the struct here. Freeing taken care of later */ - if (nodeDataPageIndex == nodeDataPageSize) ResizeNodeDataPages(); - if (memOut) { - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - st_free_table(table); - return(0.0); - } + /* point to the correct location in the page */ + pmin = currentMintermPage+pageIndex; + pageIndex++; - newEntry = currentNodeDataPage + nodeDataPageIndex; - nodeDataPageIndex++; + /* store the minterm count of this node in the page */ + *pmin = min; - /* points to the correct location in the page */ - newEntry->mintermPointer = pmin; - /* initialize this field of the Node Quality structure */ - newEntry->nodesPointer = NULL; + /* Note I allocate the struct here. Freeing taken care of later */ + if (nodeDataPageIndex == nodeDataPageSize) ResizeNodeDataPages(); + if (memOut) { + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + st_free_table(table); + return(0.0); + } - /* insert entry for the node in the table */ - if (st_insert(table,(char *)node, (char *)newEntry) == ST_OUT_OF_MEM) { - memOut = 1; - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - st_free_table(table); - return(0.0); - } - return(min); + newEntry = currentNodeDataPage + nodeDataPageIndex; + nodeDataPageIndex++; + + /* points to the correct location in the page */ + newEntry->mintermPointer = pmin; + /* initialize this field of the Node Quality structure */ + newEntry->nodesPointer = NULL; + + /* insert entry for the node in the table */ + if (st_insert(table,(char *)node, (char *)newEntry) == ST_OUT_OF_MEM) { + memOut = 1; + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + st_free_table(table); + return(0.0); + } + return(min); } } /* end of SubsetCountMintermAux */ @@ -771,7 +793,6 @@ SubsetCountMinterm( int nvars /* number of variables node depends on */) { st_table *table; - double num; int i; @@ -780,44 +801,44 @@ SubsetCountMinterm( #endif max = pow(2.0,(double) nvars); - table = st_init_table(st_ptrcmp, st_ptrhash);; + table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) goto OUT_OF_MEM; maxPages = INITIAL_PAGES; mintermPages = ABC_ALLOC(double *,maxPages); if (mintermPages == NULL) { - st_free_table(table); - goto OUT_OF_MEM; + st_free_table(table); + goto OUT_OF_MEM; } page = 0; currentMintermPage = ABC_ALLOC(double,pageSize); mintermPages[page] = currentMintermPage; if (currentMintermPage == NULL) { - ABC_FREE(mintermPages); - st_free_table(table); - goto OUT_OF_MEM; + ABC_FREE(mintermPages); + st_free_table(table); + goto OUT_OF_MEM; } pageIndex = 0; maxNodeDataPages = INITIAL_PAGES; nodeDataPages = ABC_ALLOC(NodeData_t *, maxNodeDataPages); if (nodeDataPages == NULL) { - for (i = 0; i <= page ; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - st_free_table(table); - goto OUT_OF_MEM; + for (i = 0; i <= page ; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + st_free_table(table); + goto OUT_OF_MEM; } nodeDataPage = 0; currentNodeDataPage = ABC_ALLOC(NodeData_t ,nodeDataPageSize); nodeDataPages[nodeDataPage] = currentNodeDataPage; if (currentNodeDataPage == NULL) { - for (i = 0; i <= page ; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - ABC_FREE(nodeDataPages); - st_free_table(table); - goto OUT_OF_MEM; + for (i = 0; i <= page ; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + ABC_FREE(nodeDataPages); + st_free_table(table); + goto OUT_OF_MEM; } nodeDataPageIndex = 0; - num = SubsetCountMintermAux(node,max,table); + (void) SubsetCountMintermAux(node,max,table); if (memOut) goto OUT_OF_MEM; return(table); @@ -860,94 +881,94 @@ SubsetCountNodesAux( int *pmin, *pminBar, *val; if ((node == NULL) || Cudd_IsConstant(node)) - return(0); + return(0); /* if this node has been processed do nothing */ - if (st_lookup(table, (char *)node, (char **)&dummyN) == 1) { - val = dummyN->nodesPointer; - if (val != NULL) - return(0); + if (st_lookup(table, (const char *)node, (char **)&dummyN) == 1) { + val = dummyN->nodesPointer; + if (val != NULL) + return(0); } else { - return(0); + return(0); } N = Cudd_Regular(node); Nv = Cudd_T(N); Nnv = Cudd_E(N); - + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); /* find the minterm counts for the THEN and ELSE branches */ if (Cudd_IsConstant(Nv)) { - if (Nv == zero) { - minNv = 0.0; - } else { - minNv = max; - } + if (Nv == zero) { + minNv = 0.0; + } else { + minNv = max; + } } else { - if (st_lookup(table, (char *)Nv, (char **)&dummyNv) == 1) - minNv = *(dummyNv->mintermPointer); - else { - return(0); - } + if (st_lookup(table, (const char *)Nv, (char **)&dummyNv) == 1) + minNv = *(dummyNv->mintermPointer); + else { + return(0); + } } if (Cudd_IsConstant(Nnv)) { - if (Nnv == zero) { - minNnv = 0.0; - } else { - minNnv = max; - } + if (Nnv == zero) { + minNnv = 0.0; + } else { + minNnv = max; + } } else { - if (st_lookup(table, (char *)Nnv, (char **)&dummyNnv) == 1) { - minNnv = *(dummyNnv->mintermPointer); - } - else { - return(0); - } + if (st_lookup(table, (const char *)Nnv, (char **)&dummyNnv) == 1) { + minNnv = *(dummyNnv->mintermPointer); + } + else { + return(0); + } } /* recur based on which has larger minterm, */ if (minNv >= minNnv) { - tval = SubsetCountNodesAux(Nv, table, max); - if (memOut) return(0); - eval = SubsetCountNodesAux(Nnv, table, max); - if (memOut) return(0); - - /* store the node count of the lighter child. */ - if (pageIndex == pageSize) ResizeCountNodePages(); - if (memOut) { - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - st_free_table(table); - return(0); - } - pmin = currentLightNodePage + pageIndex; - *pmin = eval; /* Here the ELSE child is lighter */ - dummyN->lightChildNodesPointer = pmin; + tval = SubsetCountNodesAux(Nv, table, max); + if (memOut) return(0); + eval = SubsetCountNodesAux(Nnv, table, max); + if (memOut) return(0); + + /* store the node count of the lighter child. */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pmin = currentLightNodePage + pageIndex; + *pmin = eval; /* Here the ELSE child is lighter */ + dummyN->lightChildNodesPointer = pmin; } else { - eval = SubsetCountNodesAux(Nnv, table, max); - if (memOut) return(0); - tval = SubsetCountNodesAux(Nv, table, max); - if (memOut) return(0); - - /* store the node count of the lighter child. */ - if (pageIndex == pageSize) ResizeCountNodePages(); - if (memOut) { - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - st_free_table(table); - return(0); - } - pmin = currentLightNodePage + pageIndex; - *pmin = tval; /* Here the THEN child is lighter */ - dummyN->lightChildNodesPointer = pmin; + eval = SubsetCountNodesAux(Nnv, table, max); + if (memOut) return(0); + tval = SubsetCountNodesAux(Nv, table, max); + if (memOut) return(0); + + /* store the node count of the lighter child. */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pmin = currentLightNodePage + pageIndex; + *pmin = tval; /* Here the THEN child is lighter */ + dummyN->lightChildNodesPointer = pmin; } /* updating the page index for node count storage. */ @@ -962,36 +983,36 @@ SubsetCountNodesAux( branch. Its complement will be reached later on a lighter branch. Hence the complement has zero node count. */ - if (st_lookup(table, (char *)Cudd_Not(node), (char **)&dummyNBar) == 1) { - if (pageIndex == pageSize) ResizeCountNodePages(); - if (memOut) { - for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - st_free_table(table); - return(0); - } - pminBar = currentLightNodePage + pageIndex; - *pminBar = 0; - dummyNBar->lightChildNodesPointer = pminBar; - /* The lighter child has less nodes than the parent. - * So if parent 0 then lighter child zero - */ - if (pageIndex == pageSize) ResizeCountNodePages(); - if (memOut) { - for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - st_free_table(table); - return(0); - } - pminBar = currentNodePage + pageIndex; - *pminBar = 0; - dummyNBar->nodesPointer = pminBar ; /* maybe should point to zero */ + if (st_lookup(table, (const char *)Cudd_Not(node), (char **)&dummyNBar) == 1) { + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pminBar = currentLightNodePage + pageIndex; + *pminBar = 0; + dummyNBar->lightChildNodesPointer = pminBar; + /* The lighter child has less nodes than the parent. + * So if parent 0 then lighter child zero + */ + if (pageIndex == pageSize) ResizeCountNodePages(); + if (memOut) { + for (i = 0; i < page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i < nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + st_free_table(table); + return(0); + } + pminBar = currentNodePage + pageIndex; + *pminBar = 0; + dummyNBar->nodesPointer = pminBar ; /* maybe should point to zero */ - pageIndex++; + pageIndex++; } return(*pmin); } /*end of SubsetCountNodesAux */ @@ -1017,7 +1038,7 @@ SubsetCountNodes( st_table * table /* node quality table */, int nvars /* number of variables node depends on */) { - int num; + int num; int i; #ifdef DEBUG @@ -1028,41 +1049,41 @@ SubsetCountNodes( maxPages = INITIAL_PAGES; nodePages = ABC_ALLOC(int *,maxPages); if (nodePages == NULL) { - goto OUT_OF_MEM; + goto OUT_OF_MEM; } lightNodePages = ABC_ALLOC(int *,maxPages); if (lightNodePages == NULL) { - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - ABC_FREE(nodePages); - goto OUT_OF_MEM; + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + ABC_FREE(nodePages); + goto OUT_OF_MEM; } page = 0; currentNodePage = nodePages[page] = ABC_ALLOC(int,pageSize); if (currentNodePage == NULL) { - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - ABC_FREE(lightNodePages); - ABC_FREE(nodePages); - goto OUT_OF_MEM; + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + ABC_FREE(lightNodePages); + ABC_FREE(nodePages); + goto OUT_OF_MEM; } currentLightNodePage = lightNodePages[page] = ABC_ALLOC(int,pageSize); if (currentLightNodePage == NULL) { - for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); - ABC_FREE(mintermPages); - for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); - ABC_FREE(nodeDataPages); - ABC_FREE(currentNodePage); - ABC_FREE(lightNodePages); - ABC_FREE(nodePages); - goto OUT_OF_MEM; + for (i = 0; i <= page; i++) ABC_FREE(mintermPages[i]); + ABC_FREE(mintermPages); + for (i = 0; i <= nodeDataPage; i++) ABC_FREE(nodeDataPages[i]); + ABC_FREE(nodeDataPages); + ABC_FREE(currentNodePage); + ABC_FREE(lightNodePages); + ABC_FREE(nodePages); + goto OUT_OF_MEM; } pageIndex = 0; @@ -1094,18 +1115,17 @@ StoreNodes( DdManager * dd, DdNode * node) { - char *dummy; DdNode *N, *Nt, *Ne; if (Cudd_IsConstant(dd)) { - return; + return; } N = Cudd_Regular(node); - if (st_lookup(storeTable, (char *)N, (char **)&dummy)) { - return; + if (st_lookup(storeTable, (char *)N, NIL(char *))) { + return; } cuddRef(N); if (st_insert(storeTable, (char *)N, NIL(char)) == ST_OUT_OF_MEM) { - fprintf(dd->err,"Something wrong, st_table insert failed\n"); + fprintf(dd->err,"Something wrong, st_table insert failed\n"); } Nt = Cudd_T(N); @@ -1120,7 +1140,7 @@ StoreNodes( /**Function******************************************************************** - Synopsis [Builds the subset BDD using the heavy branch method.] + Synopsis [Builds the subset BDD using the heavy branch method.] Description [The procedure carries out the building of the subset BDD starting at the root. Using the three different counts labelling each node, @@ -1166,12 +1186,12 @@ BuildSubsetBdd( } if (Cudd_IsConstant(node)) - return(node); + return(node); /* Look up minterm count for this node. */ - if (!st_lookup(visitedTable, (char *)node, (char **)&currNodeQual)) { - fprintf(dd->err, - "Something is wrong, ought to be in node quality table\n"); + if (!st_lookup(visitedTable, (const char *)node, (char **)&currNodeQual)) { + fprintf(dd->err, + "Something is wrong, ought to be in node quality table\n"); } /* Get children. */ @@ -1185,37 +1205,36 @@ BuildSubsetBdd( if (!Cudd_IsConstant(Nv)) { /* find out minterms and nodes contributed by then child */ - if (!st_lookup(visitedTable, (char *)Nv, - (char **)&currNodeQualT)) { - fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + if (!st_lookup(visitedTable, (const char *)Nv, (char **)&currNodeQualT)) { + fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + else { + minNv = *(((NodeData_t *)currNodeQualT)->mintermPointer); } - else { - minNv = *(((NodeData_t *)currNodeQualT)->mintermPointer); - } } else { - if (Nv == zero) { - minNv = 0; - } else { - minNv = max; - } + if (Nv == zero) { + minNv = 0; + } else { + minNv = max; + } } if (!Cudd_IsConstant(Nnv)) { /* find out minterms and nodes contributed by else child */ - if (!st_lookup(visitedTable, (char *)Nnv, (char **)&currNodeQualE)) { - fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } else { - minNnv = *(((NodeData_t *)currNodeQualE)->mintermPointer); - } - } else { - if (Nnv == zero) { - minNnv = 0; + if (!st_lookup(visitedTable, (const char *)Nnv, (char **)&currNodeQualE)) { + fprintf(dd->out,"Something wrong, couldnt find nodes in node quality table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } else { + minNnv = *(((NodeData_t *)currNodeQualE)->mintermPointer); + } } else { - minNnv = max; - } + if (Nnv == zero) { + minNnv = 0; + } else { + minNnv = max; + } } /* keep track of size of subset by subtracting the number of @@ -1223,57 +1242,57 @@ BuildSubsetBdd( */ *size = (*(size)) - (int)*(currNodeQual->lightChildNodesPointer); if (minNv >= minNnv) { /*SubsetCountNodesAux procedure takes - the Then branch in case of a tie */ + the Then branch in case of a tie */ /* recur with the Then branch */ - ThenBranch = (DdNode *)BuildSubsetBdd(dd, Nv, size, - visitedTable, threshold, storeTable, approxTable); - if (ThenBranch == NULL) { - return(NULL); - } - cuddRef(ThenBranch); - /* The Else branch is either a node that already exists in the - * subset, or one whose approximation has been computed, or - * Zero. - */ - if (st_lookup(storeTable, (char *)Cudd_Regular(Nnv), (char **)&dummy)) { - ElseBranch = Nnv; - cuddRef(ElseBranch); - } else { - if (st_lookup(approxTable, (char *)Nnv, (char **)&dummy)) { - ElseBranch = (DdNode *)dummy; - cuddRef(ElseBranch); - } else { - ElseBranch = zero; - cuddRef(ElseBranch); - } - } - + ThenBranch = (DdNode *)BuildSubsetBdd(dd, Nv, size, + visitedTable, threshold, storeTable, approxTable); + if (ThenBranch == NULL) { + return(NULL); + } + cuddRef(ThenBranch); + /* The Else branch is either a node that already exists in the + * subset, or one whose approximation has been computed, or + * Zero. + */ + if (st_lookup(storeTable, (char *)Cudd_Regular(Nnv), &dummy)) { + ElseBranch = Nnv; + cuddRef(ElseBranch); + } else { + if (st_lookup(approxTable, (char *)Nnv, &dummy)) { + ElseBranch = (DdNode *)dummy; + cuddRef(ElseBranch); + } else { + ElseBranch = zero; + cuddRef(ElseBranch); + } + } + } else { /* recur with the Else branch */ ElseBranch = (DdNode *)BuildSubsetBdd(dd, Nnv, size, - visitedTable, threshold, storeTable, approxTable); - if (ElseBranch == NULL) { - return(NULL); - } - cuddRef(ElseBranch); - /* The Then branch is either a node that already exists in the - * subset, or one whose approximation has been computed, or - * Zero. - */ - if (st_lookup(storeTable, (char *)Cudd_Regular(Nv), (char **)&dummy)) { - ThenBranch = Nv; - cuddRef(ThenBranch); - } else { - if (st_lookup(approxTable, (char *)Nv, (char **)&dummy)) { - ThenBranch = (DdNode *)dummy; - cuddRef(ThenBranch); - } else { - ThenBranch = zero; - cuddRef(ThenBranch); - } - } + visitedTable, threshold, storeTable, approxTable); + if (ElseBranch == NULL) { + return(NULL); + } + cuddRef(ElseBranch); + /* The Then branch is either a node that already exists in the + * subset, or one whose approximation has been computed, or + * Zero. + */ + if (st_lookup(storeTable, (char *)Cudd_Regular(Nv), &dummy)) { + ThenBranch = Nv; + cuddRef(ThenBranch); + } else { + if (st_lookup(approxTable, (char *)Nv, &dummy)) { + ThenBranch = (DdNode *)dummy; + cuddRef(ThenBranch); + } else { + ThenBranch = zero; + cuddRef(ThenBranch); + } + } } /* construct the Bdd with the top variable and the two children */ @@ -1288,29 +1307,31 @@ BuildSubsetBdd( Cudd_RecursiveDeref(dd, ThenBranch); Cudd_RecursiveDeref(dd, ElseBranch); - + if (neW == NULL) - return(NULL); + return(NULL); else { /* store this node in the store table */ - if (!st_lookup(storeTable, (char *)Cudd_Regular(neW), (char **)&dummy)) { - cuddRef(neW); - st_insert(storeTable, (char *)Cudd_Regular(neW), (char *)NIL(char)); - + if (!st_lookup(storeTable, (char *)Cudd_Regular(neW), &dummy)) { + cuddRef(neW); + if (!st_insert(storeTable, (char *)Cudd_Regular(neW), NIL(char))) + return (NULL); } - /* store the approximation for this node */ - if (N != Cudd_Regular(neW)) { - if (st_lookup(approxTable, (char *)node, (char **)&dummy)) { - fprintf(dd->err, "This node should not be in the approximated table\n"); - } else { - cuddRef(neW); - st_insert(approxTable, (char *)node, (char *)neW); + /* store the approximation for this node */ + if (N != Cudd_Regular(neW)) { + if (st_lookup(approxTable, (char *)node, &dummy)) { + fprintf(dd->err, "This node should not be in the approximated table\n"); + } else { + cuddRef(neW); + if (!st_insert(approxTable, (char *)node, (char *)neW)) + return(NULL); + } } - } cuddDeref(neW); return(neW); } } /* end of BuildSubsetBdd */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddSubsetSP.c b/src/bdd/cudd/cuddSubsetSP.c index d336187b..cddc58ed 100644 --- a/src/bdd/cudd/cuddSubsetSP.c +++ b/src/bdd/cudd/cuddSubsetSP.c @@ -9,35 +9,62 @@ Description [External procedures included in this module: - <ul> - <li> Cudd_SubsetShortPaths() - <li> Cudd_SupersetShortPaths() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddSubsetShortPaths() - </ul> - Static procedures included in this module: - <ul> - <li> BuildSubsetBdd() - <li> CreatePathTable() - <li> AssessPathLength() - <li> CreateTopDist() - <li> CreateBotDist() - <li> ResizeNodeDistPages() - <li> ResizeQueuePages() - <li> stPathTableDdFree() - </ul> - ] + <ul> + <li> Cudd_SubsetShortPaths() + <li> Cudd_SupersetShortPaths() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddSubsetShortPaths() + </ul> + Static procedures included in this module: + <ul> + <li> BuildSubsetBdd() + <li> CreatePathTable() + <li> AssessPathLength() + <li> CreateTopDist() + <li> CreateBotDist() + <li> ResizeNodeDistPages() + <li> ResizeQueuePages() + <li> stPathTableDdFree() + </ul> + ] SeeAlso [cuddSubsetHB.c] Author [Kavita Ravi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -47,25 +74,26 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ #define DEFAULT_PAGE_SIZE 2048 /* page size to store the BFS queue element type */ #define DEFAULT_NODE_DIST_PAGE_SIZE 2048 /* page sizesto store NodeDist_t type */ -#define MAXSHORTINT ((DdHalfWord) ~0) /* constant defined to store - * maximum distance of a node - * from the root or the - * constant - */ +#define MAXSHORTINT ((DdHalfWord) ~0) /* constant defined to store + * maximum distance of a node + * from the root or the + * constant + */ #define INITIAL_PAGES 128 /* number of initial pages for the - * queue/NodeDist_t type */ + * queue/NodeDist_t type */ /*---------------------------------------------------------------------------*/ /* Stucture declarations */ /*---------------------------------------------------------------------------*/ -/* structure created to store subset results for each node and distances with +/* structure created to store subset results for each node and distances with * odd and even parity of the node from the root and sink. Main data structure * in this procedure. */ @@ -98,7 +126,7 @@ typedef struct NodeDist NodeDist_t; /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddSubsetSP.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddSubsetSP.c,v 1.34 2009/02/19 16:23:19 fabio Exp $"; #endif #ifdef DD_DEBUG @@ -108,21 +136,21 @@ static int thishit; #endif -static int memOut; /* flag to indicate out of memory */ +static int memOut; /* flag to indicate out of memory */ static DdNode *zero, *one; /* constant functions */ static NodeDist_t **nodeDistPages; /* pointers to the pages */ -static int nodeDistPageIndex; /* index to next element */ -static int nodeDistPage; /* index to current page */ -static int nodeDistPageSize = DEFAULT_NODE_DIST_PAGE_SIZE; /* page size */ -static int maxNodeDistPages; /* number of page pointers */ +static int nodeDistPageIndex; /* index to next element */ +static int nodeDistPage; /* index to current page */ +static int nodeDistPageSize = DEFAULT_NODE_DIST_PAGE_SIZE; /* page size */ +static int maxNodeDistPages; /* number of page pointers */ static NodeDist_t *currentNodeDistPage; /* current page */ static DdNode ***queuePages; /* pointers to the pages */ -static int queuePageIndex; /* index to next element */ -static int queuePage; /* index to current page */ -static int queuePageSize = DEFAULT_PAGE_SIZE; /* page size */ -static int maxQueuePages; /* number of page pointers */ +static int queuePageIndex; /* index to next element */ +static int queuePage; /* index to current page */ +static int queuePageSize = DEFAULT_PAGE_SIZE; /* page size */ +static int maxQueuePages; /* number of page pointers */ static DdNode **currentQueuePage; /* current page */ @@ -130,23 +158,30 @@ static DdNode **currentQueuePage; /* current page */ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif + /**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void ResizeNodeDistPages ARGS(()); -static void ResizeQueuePages ARGS(()); -static void CreateTopDist ARGS((st_table *pathTable, int parentPage, int parentQueueIndex, int topLen, DdNode **childPage, int childQueueIndex, int numParents, FILE *fp)); -static int CreateBotDist ARGS((DdNode *node, st_table *pathTable, unsigned int *pathLengthArray, FILE *fp)); -static st_table * CreatePathTable ARGS((DdNode *node, unsigned int *pathLengthArray, FILE *fp)); -static unsigned int AssessPathLength ARGS((unsigned int *pathLengthArray, int threshold, int numVars, unsigned int *excess, FILE *fp)); -static DdNode * BuildSubsetBdd ARGS((DdManager *dd, st_table *pathTable, DdNode *node, struct AssortedInfo *info, st_table *subsetNodeTable)); -static enum st_retval stPathTableDdFree ARGS((char *key, char *value, char *arg)); +static void ResizeNodeDistPages (void); +static void ResizeQueuePages (void); +static void CreateTopDist (st_table *pathTable, int parentPage, int parentQueueIndex, int topLen, DdNode **childPage, int childQueueIndex, int numParents, FILE *fp); +static int CreateBotDist (DdNode *node, st_table *pathTable, unsigned int *pathLengthArray, FILE *fp); +static st_table * CreatePathTable (DdNode *node, unsigned int *pathLengthArray, FILE *fp); +static unsigned int AssessPathLength (unsigned int *pathLengthArray, int threshold, int numVars, unsigned int *excess, FILE *fp); +static DdNode * BuildSubsetBdd (DdManager *dd, st_table *pathTable, DdNode *node, struct AssortedInfo *info, st_table *subsetNodeTable); +static enum st_retval stPathTableDdFree (char *key, char *value, char *arg); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of Exported functions */ @@ -193,8 +228,8 @@ Cudd_SubsetShortPaths( memOut = 0; do { - dd->reordered = 0; - subset = cuddSubsetShortPaths(dd, f, numVars, threshold, hardlimit); + dd->reordered = 0; + subset = cuddSubsetShortPaths(dd, f, numVars, threshold, hardlimit); } while((dd->reordered ==1) && (!memOut)); return(subset); @@ -246,8 +281,8 @@ Cudd_SupersetShortPaths( g = Cudd_Not(f); memOut = 0; do { - dd->reordered = 0; - subset = cuddSubsetShortPaths(dd, g, numVars, threshold, hardlimit); + dd->reordered = 0; + subset = cuddSubsetShortPaths(dd, g, numVars, threshold, hardlimit); } while((dd->reordered ==1) && (!memOut)); return(Cudd_NotCond(subset, (subset != NULL))); @@ -291,7 +326,7 @@ cuddSubsetShortPaths( unsigned int *pathLengthArray; unsigned int maxpath, oddLen, evenLen, pathLength, *excess; int i; - NodeDist_t *nodeStat; + NodeDist_t *nodeStat; struct AssortedInfo *info; st_table *subsetNodeTable; @@ -302,17 +337,17 @@ cuddSubsetShortPaths( /* set default value */ numVars = Cudd_ReadSize(dd); } - + if (threshold > numVars) { - threshold = threshold - numVars; + threshold = threshold - numVars; } if (f == NULL) { - fprintf(dd->err, "Cannot partition, nil object\n"); - dd->errorCode = CUDD_INVALID_ARG; - return(NULL); + fprintf(dd->err, "Cannot partition, nil object\n"); + dd->errorCode = CUDD_INVALID_ARG; + return(NULL); } if (Cudd_IsConstant(f)) - return (f); + return (f); pathLengthArray = ABC_ALLOC(unsigned int, numVars+1); for (i = 0; i < numVars+1; i++) pathLengthArray[i] = 0; @@ -325,101 +360,103 @@ cuddSubsetShortPaths( pathTable = CreatePathTable(f, pathLengthArray, dd->err); if ((pathTable == NULL) || (memOut)) { - if (pathTable != NULL) - st_free_table(pathTable); - ABC_FREE(pathLengthArray); - return (NIL(DdNode)); + if (pathTable != NULL) + st_free_table(pathTable); + ABC_FREE(pathLengthArray); + return (NIL(DdNode)); } excess = ABC_ALLOC(unsigned int, 1); *excess = 0; maxpath = AssessPathLength(pathLengthArray, threshold, numVars, excess, - dd->err); + dd->err); if (maxpath != (unsigned) (numVars + 1)) { - info = ABC_ALLOC(struct AssortedInfo, 1); - info->maxpath = maxpath; - info->findShortestPath = 0; - info->thresholdReached = *excess; - info->maxpathTable = st_init_table(st_ptrcmp, st_ptrhash); - info->threshold = threshold; + info = ABC_ALLOC(struct AssortedInfo, 1); + info->maxpath = maxpath; + info->findShortestPath = 0; + info->thresholdReached = *excess; + info->maxpathTable = st_init_table(st_ptrcmp, st_ptrhash); + info->threshold = threshold; #ifdef DD_DEBUG - (void) fprintf(dd->out, "Path length array\n"); - for (i = 0; i < (numVars+1); i++) { - if (pathLengthArray[i]) - (void) fprintf(dd->out, "%d ",i); - } - (void) fprintf(dd->out, "\n"); - for (i = 0; i < (numVars+1); i++) { - if (pathLengthArray[i]) - (void) fprintf(dd->out, "%d ",pathLengthArray[i]); - } - (void) fprintf(dd->out, "\n"); - (void) fprintf(dd->out, "Maxpath = %d, Thresholdreached = %d\n", - maxpath, info->thresholdReached); + (void) fprintf(dd->out, "Path length array\n"); + for (i = 0; i < (numVars+1); i++) { + if (pathLengthArray[i]) + (void) fprintf(dd->out, "%d ",i); + } + (void) fprintf(dd->out, "\n"); + for (i = 0; i < (numVars+1); i++) { + if (pathLengthArray[i]) + (void) fprintf(dd->out, "%d ",pathLengthArray[i]); + } + (void) fprintf(dd->out, "\n"); + (void) fprintf(dd->out, "Maxpath = %d, Thresholdreached = %d\n", + maxpath, info->thresholdReached); #endif - N = Cudd_Regular(f); - if (!st_lookup(pathTable, (char *)N, (char **)&nodeStat)) { - fprintf(dd->err, "Something wrong, root node must be in table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } else { - if ((nodeStat->oddTopDist != MAXSHORTINT) && - (nodeStat->oddBotDist != MAXSHORTINT)) - oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); - else - oddLen = MAXSHORTINT; - - if ((nodeStat->evenTopDist != MAXSHORTINT) && - (nodeStat->evenBotDist != MAXSHORTINT)) - evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); - else - evenLen = MAXSHORTINT; - - pathLength = (oddLen <= evenLen) ? oddLen : evenLen; - if (pathLength > maxpath) { - (void) fprintf(dd->err, "All computations are bogus, since root has path length greater than max path length within threshold %d, %d\n", maxpath, pathLength); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + N = Cudd_Regular(f); + if (!st_lookup(pathTable, (const char *)N, (char **)&nodeStat)) { + fprintf(dd->err, "Something wrong, root node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + ABC_FREE(excess); + ABC_FREE(info); + return(NULL); + } else { + if ((nodeStat->oddTopDist != MAXSHORTINT) && + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + else + oddLen = MAXSHORTINT; + + if ((nodeStat->evenTopDist != MAXSHORTINT) && + (nodeStat->evenBotDist != MAXSHORTINT)) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + else + evenLen = MAXSHORTINT; + + pathLength = (oddLen <= evenLen) ? oddLen : evenLen; + if (pathLength > maxpath) { + (void) fprintf(dd->err, "All computations are bogus, since root has path length greater than max path length within threshold %u, %u\n", maxpath, pathLength); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } } - } #ifdef DD_DEBUG - numCalls = 0; - hits = 0; - thishit = 0; + numCalls = 0; + hits = 0; + thishit = 0; #endif - /* initialize a table to store computed nodes */ - if (hardlimit) { - subsetNodeTable = st_init_table(st_ptrcmp, st_ptrhash); - } else { - subsetNodeTable = NIL(st_table); - } - subset = BuildSubsetBdd(dd, pathTable, f, info, subsetNodeTable); - if (subset != NULL) { - cuddRef(subset); - } - /* record the number of times a computed result for a node is hit */ + /* initialize a table to store computed nodes */ + if (hardlimit) { + subsetNodeTable = st_init_table(st_ptrcmp, st_ptrhash); + } else { + subsetNodeTable = NIL(st_table); + } + subset = BuildSubsetBdd(dd, pathTable, f, info, subsetNodeTable); + if (subset != NULL) { + cuddRef(subset); + } + /* record the number of times a computed result for a node is hit */ #ifdef DD_DEBUG - (void) fprintf(dd->out, "Hits = %d, New==Node = %d, NumCalls = %d\n", - hits, thishit, numCalls); + (void) fprintf(dd->out, "Hits = %d, New==Node = %d, NumCalls = %d\n", + hits, thishit, numCalls); #endif - if (subsetNodeTable != NIL(st_table)) { - st_free_table(subsetNodeTable); - } - st_free_table(info->maxpathTable); - st_foreach(pathTable, (ST_PFSR)stPathTableDdFree, (char *)dd); + if (subsetNodeTable != NIL(st_table)) { + st_free_table(subsetNodeTable); + } + st_free_table(info->maxpathTable); + st_foreach(pathTable, stPathTableDdFree, (char *)dd); - ABC_FREE(info); + ABC_FREE(info); } else {/* if threshold larger than size of dd */ - subset = f; - cuddRef(subset); + subset = f; + cuddRef(subset); } ABC_FREE(excess); st_free_table(pathTable); @@ -430,21 +467,21 @@ cuddSubsetShortPaths( #ifdef DD_DEBUG /* check containment of subset in f */ if (subset != NULL) { - DdNode *check; - check = Cudd_bddIteConstant(dd, subset, f, one); - if (check != one) { - (void) fprintf(dd->err, "Wrong partition\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } + DdNode *check; + check = Cudd_bddIteConstant(dd, subset, f, one); + if (check != one) { + (void) fprintf(dd->err, "Wrong partition\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } } #endif if (subset != NULL) { - cuddDeref(subset); - return(subset); + cuddDeref(subset); + return(subset); } else { - return(NULL); + return(NULL); } } /* end of cuddSubsetShortPaths */ @@ -465,15 +502,14 @@ cuddSubsetShortPaths( next page when the end of the page is reached and allocates new pages when necessary. ] - SideEffects [Changes the size of pages, page, page index, maximum + SideEffects [Changes the size of pages, page, page index, maximum number of pages freeing stuff in case of memory out. ] SeeAlso [] ******************************************************************************/ static void -ResizeNodeDistPages( - ) +ResizeNodeDistPages(void) { int i; NodeDist_t **newNodeDistPages; @@ -482,34 +518,34 @@ ResizeNodeDistPages( nodeDistPage++; /* If the current page index is larger than the number of pages - * allocated, allocate a new page array. Page numbers are incremented by + * allocated, allocate a new page array. Page numbers are incremented by * INITIAL_PAGES */ if (nodeDistPage == maxNodeDistPages) { - newNodeDistPages = ABC_ALLOC(NodeDist_t *,maxNodeDistPages + INITIAL_PAGES); - if (newNodeDistPages == NULL) { - for (i = 0; i < nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - memOut = 1; - return; - } else { - for (i = 0; i < maxNodeDistPages; i++) { - newNodeDistPages[i] = nodeDistPages[i]; + newNodeDistPages = ABC_ALLOC(NodeDist_t *,maxNodeDistPages + INITIAL_PAGES); + if (newNodeDistPages == NULL) { + for (i = 0; i < nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + memOut = 1; + return; + } else { + for (i = 0; i < maxNodeDistPages; i++) { + newNodeDistPages[i] = nodeDistPages[i]; + } + /* Increase total page count */ + maxNodeDistPages += INITIAL_PAGES; + ABC_FREE(nodeDistPages); + nodeDistPages = newNodeDistPages; } - /* Increase total page count */ - maxNodeDistPages += INITIAL_PAGES; - ABC_FREE(nodeDistPages); - nodeDistPages = newNodeDistPages; - } } /* Allocate a new page */ currentNodeDistPage = nodeDistPages[nodeDistPage] = ABC_ALLOC(NodeDist_t, - nodeDistPageSize); + nodeDistPageSize); if (currentNodeDistPage == NULL) { - for (i = 0; i < nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - memOut = 1; - return; + for (i = 0; i < nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + memOut = 1; + return; } /* reset page index */ nodeDistPageIndex = 0; @@ -520,56 +556,55 @@ ResizeNodeDistPages( /**Function******************************************************************** - Synopsis [Resize the number of pages allocated to store nodes in the BFS + Synopsis [Resize the number of pages allocated to store nodes in the BFS traversal of the Bdd .] - Description [Resize the number of pages allocated to store nodes in the BFS + Description [Resize the number of pages allocated to store nodes in the BFS traversal of the Bdd. The procedure moves the counter to the next page when the end of the page is reached and allocates new pages when necessary.] - SideEffects [Changes the size of pages, page, page index, maximum + SideEffects [Changes the size of pages, page, page index, maximum number of pages freeing stuff in case of memory out. ] SeeAlso [] ******************************************************************************/ static void -ResizeQueuePages( - ) +ResizeQueuePages(void) { int i; DdNode ***newQueuePages; queuePage++; /* If the current page index is larger than the number of pages - * allocated, allocate a new page array. Page numbers are incremented by + * allocated, allocate a new page array. Page numbers are incremented by * INITIAL_PAGES */ if (queuePage == maxQueuePages) { - newQueuePages = ABC_ALLOC(DdNode **,maxQueuePages + INITIAL_PAGES); - if (newQueuePages == NULL) { - for (i = 0; i < queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - memOut = 1; - return; - } else { - for (i = 0; i < maxQueuePages; i++) { - newQueuePages[i] = queuePages[i]; + newQueuePages = ABC_ALLOC(DdNode **,maxQueuePages + INITIAL_PAGES); + if (newQueuePages == NULL) { + for (i = 0; i < queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + memOut = 1; + return; + } else { + for (i = 0; i < maxQueuePages; i++) { + newQueuePages[i] = queuePages[i]; + } + /* Increase total page count */ + maxQueuePages += INITIAL_PAGES; + ABC_FREE(queuePages); + queuePages = newQueuePages; } - /* Increase total page count */ - maxQueuePages += INITIAL_PAGES; - ABC_FREE(queuePages); - queuePages = newQueuePages; - } } /* Allocate a new page */ currentQueuePage = queuePages[queuePage] = ABC_ALLOC(DdNode *,queuePageSize); if (currentQueuePage == NULL) { - for (i = 0; i < queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - memOut = 1; - return; + for (i = 0; i < queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + memOut = 1; + return; } /* reset page index */ queuePageIndex = 0; @@ -619,145 +654,145 @@ CreateTopDist( /* set queue index to the next available entry for addition */ /* set queue page to page of addition */ if ((queuePages[parentPage] == childPage) && (parentQueueIndex == - childQueueIndex)) { - fprintf(fp, "Should not happen that they are equal\n"); + childQueueIndex)) { + fprintf(fp, "Should not happen that they are equal\n"); } assert(queuePageIndex == childQueueIndex); assert(currentQueuePage == childPage); #endif /* number children added to queue is initialized , needed for - * numParents in the next call + * numParents in the next call */ childrenCount = 0; /* process all the nodes in this level */ while (numParents) { - numParents--; - if (parentQueueIndex == queuePageSize) { - parentPage++; - parentQueueIndex = 0; - } - /* a parent to process */ - node = *(queuePages[parentPage] + parentQueueIndex); - parentQueueIndex++; - /* get its children */ - N = Cudd_Regular(node); - Nv = Cudd_T(N); - Nnv = Cudd_E(N); - - Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); - Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); - - processingDone = 2; - while (processingDone) { - /* processing the THEN and the ELSE children, the THEN - * child first - */ - if (processingDone == 2) { - child = Nv; - } else { - child = Nnv; + numParents--; + if (parentQueueIndex == queuePageSize) { + parentPage++; + parentQueueIndex = 0; } - - regChild = Cudd_Regular(child); - /* dont process if the child is a constant */ - if (!Cudd_IsConstant(child)) { - /* check is already visited, if not add a new entry in - * the path Table - */ - if (!st_lookup(pathTable, (char *)regChild, (char **)&nodeStat)) { - /* if not in table, has never been visited */ - /* create entry for table */ - if (nodeDistPageIndex == nodeDistPageSize) - ResizeNodeDistPages(); - if (memOut) { - for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - st_free_table(pathTable); - return; - } - /* New entry for child in path Table is created here */ - nodeStat = currentNodeDistPage + nodeDistPageIndex; - nodeDistPageIndex++; - - /* Initialize fields of the node data */ - nodeStat->oddTopDist = MAXSHORTINT; - nodeStat->evenTopDist = MAXSHORTINT; - nodeStat->evenBotDist = MAXSHORTINT; - nodeStat->oddBotDist = MAXSHORTINT; - nodeStat->regResult = NULL; - nodeStat->compResult = NULL; - /* update the table entry element, the distance keeps - * track of the parity of the path from the root + /* a parent to process */ + node = *(queuePages[parentPage] + parentQueueIndex); + parentQueueIndex++; + /* get its children */ + N = Cudd_Regular(node); + Nv = Cudd_T(N); + Nnv = Cudd_E(N); + + Nv = Cudd_NotCond(Nv, Cudd_IsComplement(node)); + Nnv = Cudd_NotCond(Nnv, Cudd_IsComplement(node)); + + processingDone = 2; + while (processingDone) { + /* processing the THEN and the ELSE children, the THEN + * child first */ - if (Cudd_IsComplement(child)) { - nodeStat->oddTopDist = (DdHalfWord) topLen + 1; + if (processingDone == 2) { + child = Nv; } else { - nodeStat->evenTopDist = (DdHalfWord) topLen + 1; + child = Nnv; } - /* insert entry element for child in the table */ - if (st_insert(pathTable, (char *)regChild, - (char *)nodeStat) == ST_OUT_OF_MEM) { - memOut = 1; - for (i = 0; i <= nodeDistPage; i++) - ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - st_free_table(pathTable); - return; - } - - /* Create list element for this child to process its children. - * If this node has been processed already, then it appears - * in the path table and hence is never added to the list - * again. - */ - - if (queuePageIndex == queuePageSize) ResizeQueuePages(); - if (memOut) { - for (i = 0; i <= nodeDistPage; i++) - ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - st_free_table(pathTable); - return; - } - *(currentQueuePage + queuePageIndex) = child; - queuePageIndex++; - - childrenCount++; - } else { - /* if not been met in a path with this parity before */ - /* put in list */ - if (((Cudd_IsComplement(child)) && (nodeStat->oddTopDist == - MAXSHORTINT)) || ((!Cudd_IsComplement(child)) && - (nodeStat->evenTopDist == MAXSHORTINT))) { - - if (queuePageIndex == queuePageSize) ResizeQueuePages(); - if (memOut) { - for (i = 0; i <= nodeDistPage; i++) - ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - st_free_table(pathTable); - return; - - } - *(currentQueuePage + queuePageIndex) = child; - queuePageIndex++; - - /* update the distance with the appropriate parity */ - if (Cudd_IsComplement(child)) { - nodeStat->oddTopDist = (DdHalfWord) topLen + 1; - } else { - nodeStat->evenTopDist = (DdHalfWord) topLen + 1; - } - childrenCount++; - } - - } /* end of else (not found in st_table) */ - } /*end of if Not constant child */ - processingDone--; - } /*end of while processing Nv, Nnv */ + regChild = Cudd_Regular(child); + /* dont process if the child is a constant */ + if (!Cudd_IsConstant(child)) { + /* check is already visited, if not add a new entry in + * the path Table + */ + if (!st_lookup(pathTable, (const char *)regChild, (char **)&nodeStat)) { + /* if not in table, has never been visited */ + /* create entry for table */ + if (nodeDistPageIndex == nodeDistPageSize) + ResizeNodeDistPages(); + if (memOut) { + for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + st_free_table(pathTable); + return; + } + /* New entry for child in path Table is created here */ + nodeStat = currentNodeDistPage + nodeDistPageIndex; + nodeDistPageIndex++; + + /* Initialize fields of the node data */ + nodeStat->oddTopDist = MAXSHORTINT; + nodeStat->evenTopDist = MAXSHORTINT; + nodeStat->evenBotDist = MAXSHORTINT; + nodeStat->oddBotDist = MAXSHORTINT; + nodeStat->regResult = NULL; + nodeStat->compResult = NULL; + /* update the table entry element, the distance keeps + * track of the parity of the path from the root + */ + if (Cudd_IsComplement(child)) { + nodeStat->oddTopDist = (DdHalfWord) topLen + 1; + } else { + nodeStat->evenTopDist = (DdHalfWord) topLen + 1; + } + + /* insert entry element for child in the table */ + if (st_insert(pathTable, (char *)regChild, + (char *)nodeStat) == ST_OUT_OF_MEM) { + memOut = 1; + for (i = 0; i <= nodeDistPage; i++) + ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + st_free_table(pathTable); + return; + } + + /* Create list element for this child to process its children. + * If this node has been processed already, then it appears + * in the path table and hence is never added to the list + * again. + */ + + if (queuePageIndex == queuePageSize) ResizeQueuePages(); + if (memOut) { + for (i = 0; i <= nodeDistPage; i++) + ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + st_free_table(pathTable); + return; + } + *(currentQueuePage + queuePageIndex) = child; + queuePageIndex++; + + childrenCount++; + } else { + /* if not been met in a path with this parity before */ + /* put in list */ + if (((Cudd_IsComplement(child)) && (nodeStat->oddTopDist == + MAXSHORTINT)) || ((!Cudd_IsComplement(child)) && + (nodeStat->evenTopDist == MAXSHORTINT))) { + + if (queuePageIndex == queuePageSize) ResizeQueuePages(); + if (memOut) { + for (i = 0; i <= nodeDistPage; i++) + ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + st_free_table(pathTable); + return; + + } + *(currentQueuePage + queuePageIndex) = child; + queuePageIndex++; + + /* update the distance with the appropriate parity */ + if (Cudd_IsComplement(child)) { + nodeStat->oddTopDist = (DdHalfWord) topLen + 1; + } else { + nodeStat->evenTopDist = (DdHalfWord) topLen + 1; + } + childrenCount++; + } + + } /* end of else (not found in st_table) */ + } /*end of if Not constant child */ + processingDone--; + } /*end of while processing Nv, Nnv */ } /*end of while numParents */ #ifdef DD_DEBUG @@ -766,11 +801,11 @@ CreateTopDist( #endif if (childrenCount != 0) { - topLen++; - childPage = currentQueuePage; - childQueueIndex = queuePageIndex; - CreateTopDist(pathTable, parentPage, parentQueueIndex, topLen, - childPage, childQueueIndex, childrenCount, fp); + topLen++; + childPage = currentQueuePage; + childQueueIndex = queuePageIndex; + CreateTopDist(pathTable, parentPage, parentQueueIndex, topLen, + childPage, childQueueIndex, childrenCount, fp); } return; @@ -813,29 +848,29 @@ CreateBotDist( int processingDone; if (Cudd_IsConstant(node)) - return(1); + return(1); N = Cudd_Regular(node); /* each node has one table entry */ /* update as you go down the min dist of each node from the root in each (odd and even) parity */ - if (!st_lookup(pathTable, (char *)N, (char **)&nodeStat)) { - fprintf(fp, "Something wrong, the entry doesn't exist\n"); - return(0); + if (!st_lookup(pathTable, (const char *)N, (char **)&nodeStat)) { + fprintf(fp, "Something wrong, the entry doesn't exist\n"); + return(0); } /* compute length of odd parity distances */ if ((nodeStat->oddTopDist != MAXSHORTINT) && - (nodeStat->oddBotDist != MAXSHORTINT)) - oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); else - oddLen = MAXSHORTINT; + oddLen = MAXSHORTINT; /* compute length of even parity distances */ if (!((nodeStat->evenTopDist == MAXSHORTINT) || - (nodeStat->evenBotDist == MAXSHORTINT))) - evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + (nodeStat->evenBotDist == MAXSHORTINT))) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); else - evenLen = MAXSHORTINT; + evenLen = MAXSHORTINT; /* assign pathlength to minimum of the two */ pathLength = (oddLen <= evenLen) ? oddLen : evenLen; @@ -846,116 +881,115 @@ CreateBotDist( /* process each child */ processingDone = 0; while (processingDone != 2) { - if (!processingDone) { - child = Nv; - } else { - child = Nnv; - } - - realChild = Cudd_NotCond(child, Cudd_IsComplement(node)); - regChild = Cudd_Regular(child); - if (Cudd_IsConstant(realChild)) { - /* Found a minterm; count parity and shortest distance - ** from the constant. - */ - if (Cudd_IsComplement(child)) - nodeStat->oddBotDist = 1; - else - nodeStat->evenBotDist = 1; - } else { - /* If node not in table, recur. */ - if (!st_lookup(pathTable, (char *) regChild, - (char **)&nodeStatChild)) { - fprintf(fp, "Something wrong, node in table should have been created in top dist proc.\n"); - return(0); + if (!processingDone) { + child = Nv; + } else { + child = Nnv; } - if (nodeStatChild->oddBotDist == MAXSHORTINT) { - if (nodeStatChild->evenBotDist == MAXSHORTINT) { - if (!CreateBotDist(realChild, pathTable, pathLengthArray, fp)) - return(0); + realChild = Cudd_NotCond(child, Cudd_IsComplement(node)); + regChild = Cudd_Regular(child); + if (Cudd_IsConstant(realChild)) { + /* Found a minterm; count parity and shortest distance + ** from the constant. + */ + if (Cudd_IsComplement(child)) + nodeStat->oddBotDist = 1; + else + nodeStat->evenBotDist = 1; } else { - fprintf(fp, "Something wrong, both bot nodeStats should be there\n"); - return(0); - } - } + /* If node not in table, recur. */ + if (!st_lookup(pathTable, (const char *)regChild, (char **)&nodeStatChild)) { + fprintf(fp, "Something wrong, node in table should have been created in top dist proc.\n"); + return(0); + } + + if (nodeStatChild->oddBotDist == MAXSHORTINT) { + if (nodeStatChild->evenBotDist == MAXSHORTINT) { + if (!CreateBotDist(realChild, pathTable, pathLengthArray, fp)) + return(0); + } else { + fprintf(fp, "Something wrong, both bot nodeStats should be there\n"); + return(0); + } + } - /* Update shortest distance from the constant depending on - ** parity. */ - - if (Cudd_IsComplement(child)) { - /* If parity on the edge then add 1 to even distance - ** of child to get odd parity distance and add 1 to - ** odd distance of child to get even parity - ** distance. Change distance of current node only if - ** the calculated distance is less than existing - ** distance. */ - if (nodeStatChild->oddBotDist != MAXSHORTINT) - botDist = nodeStatChild->oddBotDist + 1; - else - botDist = MAXSHORTINT; - if (nodeStat->evenBotDist > botDist ) - nodeStat->evenBotDist = botDist; - - if (nodeStatChild->evenBotDist != MAXSHORTINT) - botDist = nodeStatChild->evenBotDist + 1; - else - botDist = MAXSHORTINT; - if (nodeStat->oddBotDist > botDist) - nodeStat->oddBotDist = botDist; + /* Update shortest distance from the constant depending on + ** parity. */ - } else { - /* If parity on the edge then add 1 to even distance - ** of child to get even parity distance and add 1 to - ** odd distance of child to get odd parity distance. - ** Change distance of current node only if the - ** calculated distance is lesser than existing - ** distance. */ - if (nodeStatChild->evenBotDist != MAXSHORTINT) - botDist = nodeStatChild->evenBotDist + 1; - else - botDist = MAXSHORTINT; - if (nodeStat->evenBotDist > botDist) - nodeStat->evenBotDist = botDist; - - if (nodeStatChild->oddBotDist != MAXSHORTINT) - botDist = nodeStatChild->oddBotDist + 1; - else - botDist = MAXSHORTINT; - if (nodeStat->oddBotDist > botDist) - nodeStat->oddBotDist = botDist; - } - } /* end of else (if not constant child ) */ - processingDone++; + if (Cudd_IsComplement(child)) { + /* If parity on the edge then add 1 to even distance + ** of child to get odd parity distance and add 1 to + ** odd distance of child to get even parity + ** distance. Change distance of current node only if + ** the calculated distance is less than existing + ** distance. */ + if (nodeStatChild->oddBotDist != MAXSHORTINT) + botDist = nodeStatChild->oddBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->evenBotDist > botDist ) + nodeStat->evenBotDist = botDist; + + if (nodeStatChild->evenBotDist != MAXSHORTINT) + botDist = nodeStatChild->evenBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->oddBotDist > botDist) + nodeStat->oddBotDist = botDist; + + } else { + /* If parity on the edge then add 1 to even distance + ** of child to get even parity distance and add 1 to + ** odd distance of child to get odd parity distance. + ** Change distance of current node only if the + ** calculated distance is lesser than existing + ** distance. */ + if (nodeStatChild->evenBotDist != MAXSHORTINT) + botDist = nodeStatChild->evenBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->evenBotDist > botDist) + nodeStat->evenBotDist = botDist; + + if (nodeStatChild->oddBotDist != MAXSHORTINT) + botDist = nodeStatChild->oddBotDist + 1; + else + botDist = MAXSHORTINT; + if (nodeStat->oddBotDist > botDist) + nodeStat->oddBotDist = botDist; + } + } /* end of else (if not constant child ) */ + processingDone++; } /* end of while processing Nv, Nnv */ /* Compute shortest path length on the fly. */ if ((nodeStat->oddTopDist != MAXSHORTINT) && - (nodeStat->oddBotDist != MAXSHORTINT)) - oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); + (nodeStat->oddBotDist != MAXSHORTINT)) + oddLen = (nodeStat->oddTopDist + nodeStat->oddBotDist); else - oddLen = MAXSHORTINT; + oddLen = MAXSHORTINT; if ((nodeStat->evenTopDist != MAXSHORTINT) && - (nodeStat->evenBotDist != MAXSHORTINT)) - evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); + (nodeStat->evenBotDist != MAXSHORTINT)) + evenLen = (nodeStat->evenTopDist +nodeStat->evenBotDist); else - evenLen = MAXSHORTINT; + evenLen = MAXSHORTINT; /* Update path length array that has number of nodes of a particular ** path length. */ if (oddLen < pathLength ) { - if (pathLength != MAXSHORTINT) - pathLengthArray[pathLength]--; - if (oddLen != MAXSHORTINT) - pathLengthArray[oddLen]++; - pathLength = oddLen; + if (pathLength != MAXSHORTINT) + pathLengthArray[pathLength]--; + if (oddLen != MAXSHORTINT) + pathLengthArray[oddLen]++; + pathLength = oddLen; } if (evenLen < pathLength ) { - if (pathLength != MAXSHORTINT) - pathLengthArray[pathLength]--; - if (evenLen != MAXSHORTINT) - pathLengthArray[evenLen]++; + if (pathLength != MAXSHORTINT) + pathLengthArray[pathLength]--; + if (evenLen != MAXSHORTINT) + pathLengthArray[evenLen]++; } return(1); @@ -999,21 +1033,21 @@ CreatePathTable( int childQueueIndex, parentQueueIndex; /* Creating path Table for storing data about nodes */ - pathTable = st_init_table(st_ptrcmp, st_ptrhash);; + pathTable = st_init_table(st_ptrcmp,st_ptrhash); /* initializing pages for info about each node */ maxNodeDistPages = INITIAL_PAGES; nodeDistPages = ABC_ALLOC(NodeDist_t *, maxNodeDistPages); if (nodeDistPages == NULL) { - goto OUT_OF_MEM; + goto OUT_OF_MEM; } nodeDistPage = 0; currentNodeDistPage = nodeDistPages[nodeDistPage] = - ABC_ALLOC(NodeDist_t, nodeDistPageSize); + ABC_ALLOC(NodeDist_t, nodeDistPageSize); if (currentNodeDistPage == NULL) { - for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - goto OUT_OF_MEM; + for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + goto OUT_OF_MEM; } nodeDistPageIndex = 0; @@ -1021,14 +1055,14 @@ CreatePathTable( maxQueuePages = INITIAL_PAGES; queuePages = ABC_ALLOC(DdNode **, maxQueuePages); if (queuePages == NULL) { - goto OUT_OF_MEM; + goto OUT_OF_MEM; } queuePage = 0; currentQueuePage = queuePages[queuePage] = ABC_ALLOC(DdNode *, queuePageSize); if (currentQueuePage == NULL) { - for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - goto OUT_OF_MEM; + for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + goto OUT_OF_MEM; } queuePageIndex = 0; @@ -1045,12 +1079,12 @@ CreatePathTable( if (nodeDistPageIndex == nodeDistPageSize) ResizeNodeDistPages(); if (memOut) { - for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - st_free_table(pathTable); - goto OUT_OF_MEM; + for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + st_free_table(pathTable); + goto OUT_OF_MEM; } nodeStat = currentNodeDistPage + nodeDistPageIndex; @@ -1065,22 +1099,22 @@ CreatePathTable( insertValue = st_insert(pathTable, (char *)N, (char *)nodeStat); if (insertValue == ST_OUT_OF_MEM) { - memOut = 1; - for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); - ABC_FREE(nodeDistPages); - for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); - ABC_FREE(queuePages); - st_free_table(pathTable); - goto OUT_OF_MEM; + memOut = 1; + for (i = 0; i <= nodeDistPage; i++) ABC_FREE(nodeDistPages[i]); + ABC_FREE(nodeDistPages); + for (i = 0; i <= queuePage; i++) ABC_FREE(queuePages[i]); + ABC_FREE(queuePages); + st_free_table(pathTable); + goto OUT_OF_MEM; } else if (insertValue == 1) { - fprintf(fp, "Something wrong, the entry exists but didnt show up in st_lookup\n"); - return(NULL); + fprintf(fp, "Something wrong, the entry exists but didnt show up in st_lookup\n"); + return(NULL); } if (Cudd_IsComplement(node)) { - nodeStat->oddTopDist = 0; + nodeStat->oddTopDist = 0; } else { - nodeStat->evenTopDist = 0; + nodeStat->evenTopDist = 0; } numParents = 1; /* call the function that counts the distance of each node from the @@ -1090,10 +1124,10 @@ CreatePathTable( numCalls = 0; #endif CreateTopDist(pathTable, parentPage, parentQueueIndex, (int) topLen, - childPage, childQueueIndex, numParents, fp); + childPage, childQueueIndex, numParents, fp); if (memOut) { - fprintf(fp, "Out of Memory and cant count path lengths\n"); - goto OUT_OF_MEM; + fprintf(fp, "Out of Memory and cant count path lengths\n"); + goto OUT_OF_MEM; } #ifdef DD_DEBUG @@ -1151,24 +1185,24 @@ AssessPathLength( * below zero */ while ((i < (unsigned) numVars+1) && (temp > 0)) { - if (pathLengthArray[i] > 0) { - maxpath = i; - temp = temp - pathLengthArray[i]; - } - i++; + if (pathLengthArray[i] > 0) { + maxpath = i; + temp = temp - pathLengthArray[i]; + } + i++; } /* if all nodes of max path are needed */ if (temp >= 0) { - maxpath++; /* now maxpath becomes the next maxppath or max number - of variables */ - *excess = 0; + maxpath++; /* now maxpath becomes the next maxppath or max number + of variables */ + *excess = 0; } else { /* normal case when subset required is less than size of - original BDD */ - *excess = temp + pathLengthArray[maxpath]; + original BDD */ + *excess = temp + pathLengthArray[maxpath]; } if (maxpath == 0) { - fprintf(fp, "Path Length array seems to be all zeroes, check\n"); + fprintf(fp, "Path Length array seems to be all zeroes, check\n"); } return(maxpath); @@ -1227,14 +1261,12 @@ BuildSubsetBdd( { DdNode *N, *Nv, *Nnv; DdNode *ThenBranch, *ElseBranch, *childBranch; - DdNode *child, *regChild; - DdNode *regNnv = NULL, *regNv = NULL; // Suppress "might be used uninitialized" + DdNode *child, *regChild, *regNnv, *regNv; NodeDist_t *nodeStatNv, *nodeStat, *nodeStatNnv; DdNode *neW, *topv, *regNew; char *entry; unsigned int topid; - unsigned int childPathLength, oddLen, evenLen; - unsigned int NnvPathLength = -1, NvPathLength = -1; // Suppress "might be used uninitialized" + unsigned int childPathLength, oddLen, evenLen, NnvPathLength, NvPathLength; unsigned int NvBotDist, NnvBotDist; int tiebreakChild; int processingDone, thenDone, elseDone; @@ -1244,14 +1276,14 @@ BuildSubsetBdd( numCalls++; #endif if (Cudd_IsConstant(node)) - return(node); + return(node); N = Cudd_Regular(node); /* Find node in table. */ - if (!st_lookup(pathTable, (char *)N, (char **)&nodeStat)) { - (void) fprintf(dd->err, "Something wrong, node must be in table \n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); + if (!st_lookup(pathTable, (const char *)N, (char **)&nodeStat)) { + (void) fprintf(dd->err, "Something wrong, node must be in table \n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); } /* If the node in the table has been visited, then return the corresponding ** Dd. Since a node can become a subset of itself, its @@ -1263,22 +1295,22 @@ BuildSubsetBdd( /* If this node is reached with an odd parity, get odd parity results. */ if (Cudd_IsComplement(node)) { - if (nodeStat->compResult != NULL) { + if (nodeStat->compResult != NULL) { #ifdef DD_DEBUG - hits++; + hits++; #endif - return(nodeStat->compResult); - } + return(nodeStat->compResult); + } } else { - /* if this node is reached with an even parity, get even parity - * results - */ - if (nodeStat->regResult != NULL) { + /* if this node is reached with an even parity, get even parity + * results + */ + if (nodeStat->regResult != NULL) { #ifdef DD_DEBUG - hits++; + hits++; #endif - return(nodeStat->regResult); - } + return(nodeStat->regResult); + } } @@ -1299,220 +1331,220 @@ BuildSubsetBdd( ElseBranch = NULL; /* if then child constant, branch is the child */ if (Cudd_IsConstant(Nv)) { - /*shortest path found */ - if ((Nv == DD_ONE(dd)) && (info->findShortestPath)) { - info->findShortestPath = 0; - } + /*shortest path found */ + if ((Nv == DD_ONE(dd)) && (info->findShortestPath)) { + info->findShortestPath = 0; + } - ThenBranch = Nv; - cuddRef(ThenBranch); - if (ThenBranch == NULL) { - return(NULL); - } + ThenBranch = Nv; + cuddRef(ThenBranch); + if (ThenBranch == NULL) { + return(NULL); + } - thenDone++; - processingDone++; - NvBotDist = MAXSHORTINT; + thenDone++; + processingDone++; + NvBotDist = MAXSHORTINT; } else { - /* Derive regular child for table lookup. */ - regNv = Cudd_Regular(Nv); - /* Get node data for shortest path length. */ - if (!st_lookup(pathTable, (char *)regNv, (char **)&nodeStatNv) ) { - (void) fprintf(dd->err, "Something wrong, node must be in table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } - /* Derive shortest path length for child. */ - if ((nodeStatNv->oddTopDist != MAXSHORTINT) && - (nodeStatNv->oddBotDist != MAXSHORTINT)) { - oddLen = (nodeStatNv->oddTopDist + nodeStatNv->oddBotDist); - } else { - oddLen = MAXSHORTINT; - } + /* Derive regular child for table lookup. */ + regNv = Cudd_Regular(Nv); + /* Get node data for shortest path length. */ + if (!st_lookup(pathTable, (const char *)regNv, (char **)&nodeStatNv) ) { + (void) fprintf(dd->err, "Something wrong, node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* Derive shortest path length for child. */ + if ((nodeStatNv->oddTopDist != MAXSHORTINT) && + (nodeStatNv->oddBotDist != MAXSHORTINT)) { + oddLen = (nodeStatNv->oddTopDist + nodeStatNv->oddBotDist); + } else { + oddLen = MAXSHORTINT; + } - if ((nodeStatNv->evenTopDist != MAXSHORTINT) && - (nodeStatNv->evenBotDist != MAXSHORTINT)) { - evenLen = (nodeStatNv->evenTopDist +nodeStatNv->evenBotDist); - } else { - evenLen = MAXSHORTINT; - } + if ((nodeStatNv->evenTopDist != MAXSHORTINT) && + (nodeStatNv->evenBotDist != MAXSHORTINT)) { + evenLen = (nodeStatNv->evenTopDist +nodeStatNv->evenBotDist); + } else { + evenLen = MAXSHORTINT; + } - NvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; - NvBotDist = (oddLen <= evenLen) ? nodeStatNv->oddBotDist: - nodeStatNv->evenBotDist; + NvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; + NvBotDist = (oddLen <= evenLen) ? nodeStatNv->oddBotDist: + nodeStatNv->evenBotDist; } /* if else child constant, branch is the child */ if (Cudd_IsConstant(Nnv)) { - /*shortest path found */ - if ((Nnv == DD_ONE(dd)) && (info->findShortestPath)) { - info->findShortestPath = 0; - } + /*shortest path found */ + if ((Nnv == DD_ONE(dd)) && (info->findShortestPath)) { + info->findShortestPath = 0; + } - ElseBranch = Nnv; - cuddRef(ElseBranch); - if (ElseBranch == NULL) { - return(NULL); - } + ElseBranch = Nnv; + cuddRef(ElseBranch); + if (ElseBranch == NULL) { + return(NULL); + } - elseDone++; - processingDone++; - NnvBotDist = MAXSHORTINT; - } else { - /* Derive regular child for table lookup. */ - regNnv = Cudd_Regular(Nnv); - /* Get node data for shortest path length. */ - if (!st_lookup(pathTable, (char *)regNnv, (char **)&nodeStatNnv) ) { - (void) fprintf(dd->err, "Something wrong, node must be in table\n"); - dd->errorCode = CUDD_INTERNAL_ERROR; - return(NULL); - } - /* Derive shortest path length for child. */ - if ((nodeStatNnv->oddTopDist != MAXSHORTINT) && - (nodeStatNnv->oddBotDist != MAXSHORTINT)) { - oddLen = (nodeStatNnv->oddTopDist + nodeStatNnv->oddBotDist); + elseDone++; + processingDone++; + NnvBotDist = MAXSHORTINT; } else { - oddLen = MAXSHORTINT; - } + /* Derive regular child for table lookup. */ + regNnv = Cudd_Regular(Nnv); + /* Get node data for shortest path length. */ + if (!st_lookup(pathTable, (const char *)regNnv, (char **)&nodeStatNnv) ) { + (void) fprintf(dd->err, "Something wrong, node must be in table\n"); + dd->errorCode = CUDD_INTERNAL_ERROR; + return(NULL); + } + /* Derive shortest path length for child. */ + if ((nodeStatNnv->oddTopDist != MAXSHORTINT) && + (nodeStatNnv->oddBotDist != MAXSHORTINT)) { + oddLen = (nodeStatNnv->oddTopDist + nodeStatNnv->oddBotDist); + } else { + oddLen = MAXSHORTINT; + } - if ((nodeStatNnv->evenTopDist != MAXSHORTINT) && - (nodeStatNnv->evenBotDist != MAXSHORTINT)) { - evenLen = (nodeStatNnv->evenTopDist +nodeStatNnv->evenBotDist); - } else { - evenLen = MAXSHORTINT; - } + if ((nodeStatNnv->evenTopDist != MAXSHORTINT) && + (nodeStatNnv->evenBotDist != MAXSHORTINT)) { + evenLen = (nodeStatNnv->evenTopDist +nodeStatNnv->evenBotDist); + } else { + evenLen = MAXSHORTINT; + } - NnvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; - NnvBotDist = (oddLen <= evenLen) ? nodeStatNnv->oddBotDist : - nodeStatNnv->evenBotDist; + NnvPathLength = (oddLen <= evenLen) ? oddLen : evenLen; + NnvBotDist = (oddLen <= evenLen) ? nodeStatNnv->oddBotDist : + nodeStatNnv->evenBotDist; } tiebreakChild = (NvBotDist <= NnvBotDist) ? 1 : 0; /* while both children not processed */ while (processingDone != 2) { - if (!processingDone) { - /* if no child processed */ - /* pick the child with shortest path length and record which one - * picked - */ - if ((NvPathLength < NnvPathLength) || - ((NvPathLength == NnvPathLength) && (tiebreakChild == 1))) { - child = Nv; - regChild = regNv; - thenDone = 1; - childPathLength = NvPathLength; - } else { - child = Nnv; - regChild = regNnv; - elseDone = 1; - childPathLength = NnvPathLength; - } /* then path length less than else path length */ - } else { - /* if one child processed, process the other */ - if (thenDone) { - child = Nnv; - regChild = regNnv; - elseDone = 1; - childPathLength = NnvPathLength; + if (!processingDone) { + /* if no child processed */ + /* pick the child with shortest path length and record which one + * picked + */ + if ((NvPathLength < NnvPathLength) || + ((NvPathLength == NnvPathLength) && (tiebreakChild == 1))) { + child = Nv; + regChild = regNv; + thenDone = 1; + childPathLength = NvPathLength; + } else { + child = Nnv; + regChild = regNnv; + elseDone = 1; + childPathLength = NnvPathLength; + } /* then path length less than else path length */ } else { - child = Nv; - regChild = regNv; - thenDone = 1; - childPathLength = NvPathLength; - } /* end of else pick the Then child if ELSE child processed */ - } /* end of else one child has been processed */ - - /* ignore (replace with constant 0) all nodes which lie on paths larger - * than the maximum length of the path required - */ - if (childPathLength > info->maxpath) { - /* record nodes visited */ - childBranch = zero; - } else { - if (childPathLength < info->maxpath) { - if (info->findShortestPath) { - info->findShortestPath = 0; - } - childBranch = BuildSubsetBdd(dd, pathTable, child, info, - subsetNodeTable); - - } else { /* Case: path length of node = maxpath */ - /* If the node labeled with maxpath is found in the - ** maxpathTable, use it to build the subset BDD. */ - if (st_lookup(info->maxpathTable, (char *)regChild, - (char **)&entry)) { - /* When a node that is already been chosen is hit, - ** the quest for a complete path is over. */ - if (info->findShortestPath) { - info->findShortestPath = 0; - } - childBranch = BuildSubsetBdd(dd, pathTable, child, info, - subsetNodeTable); + /* if one child processed, process the other */ + if (thenDone) { + child = Nnv; + regChild = regNnv; + elseDone = 1; + childPathLength = NnvPathLength; + } else { + child = Nv; + regChild = regNv; + thenDone = 1; + childPathLength = NvPathLength; + } /* end of else pick the Then child if ELSE child processed */ + } /* end of else one child has been processed */ + + /* ignore (replace with constant 0) all nodes which lie on paths larger + * than the maximum length of the path required + */ + if (childPathLength > info->maxpath) { + /* record nodes visited */ + childBranch = zero; } else { - /* If node is not found in the maxpathTable and - ** the threshold has been reached, then if the - ** path needs to be completed, continue. Else - ** replace the node with a zero. */ - if (info->thresholdReached <= 0) { - if (info->findShortestPath) { - if (st_insert(info->maxpathTable, (char *)regChild, - (char *)NIL(char)) == ST_OUT_OF_MEM) { - memOut = 1; - (void) fprintf(dd->err, "OUT of memory\n"); - info->thresholdReached = 0; - childBranch = zero; - } else { - info->thresholdReached--; - childBranch = BuildSubsetBdd(dd, pathTable, - child, info,subsetNodeTable); + if (childPathLength < info->maxpath) { + if (info->findShortestPath) { + info->findShortestPath = 0; } - } else { /* not find shortest path, we dont need this - node */ - childBranch = zero; + childBranch = BuildSubsetBdd(dd, pathTable, child, info, + subsetNodeTable); + + } else { /* Case: path length of node = maxpath */ + /* If the node labeled with maxpath is found in the + ** maxpathTable, use it to build the subset BDD. */ + if (st_lookup(info->maxpathTable, (char *)regChild, + (char **)&entry)) { + /* When a node that is already been chosen is hit, + ** the quest for a complete path is over. */ + if (info->findShortestPath) { + info->findShortestPath = 0; + } + childBranch = BuildSubsetBdd(dd, pathTable, child, info, + subsetNodeTable); + } else { + /* If node is not found in the maxpathTable and + ** the threshold has been reached, then if the + ** path needs to be completed, continue. Else + ** replace the node with a zero. */ + if (info->thresholdReached <= 0) { + if (info->findShortestPath) { + if (st_insert(info->maxpathTable, (char *)regChild, + (char *)NIL(char)) == ST_OUT_OF_MEM) { + memOut = 1; + (void) fprintf(dd->err, "OUT of memory\n"); + info->thresholdReached = 0; + childBranch = zero; + } else { + info->thresholdReached--; + childBranch = BuildSubsetBdd(dd, pathTable, + child, info,subsetNodeTable); + } + } else { /* not find shortest path, we dont need this + node */ + childBranch = zero; + } + } else { /* Threshold hasn't been reached, + ** need the node. */ + if (st_insert(info->maxpathTable, (char *)regChild, + (char *)NIL(char)) == ST_OUT_OF_MEM) { + memOut = 1; + (void) fprintf(dd->err, "OUT of memory\n"); + info->thresholdReached = 0; + childBranch = zero; + } else { + info->thresholdReached--; + if (info->thresholdReached <= 0) { + info->findShortestPath = 1; + } + childBranch = BuildSubsetBdd(dd, pathTable, + child, info, subsetNodeTable); + + } /* end of st_insert successful */ + } /* end of threshold hasnt been reached yet */ + } /* end of else node not found in maxpath table */ + } /* end of if (path length of node = maxpath) */ + } /* end if !(childPathLength > maxpath) */ + if (childBranch == NULL) { + /* deref other stuff incase reordering has taken place */ + if (ThenBranch != NULL) { + Cudd_RecursiveDeref(dd, ThenBranch); + ThenBranch = NULL; } - } else { /* Threshold hasn't been reached, - ** need the node. */ - if (st_insert(info->maxpathTable, (char *)regChild, - (char *)NIL(char)) == ST_OUT_OF_MEM) { - memOut = 1; - (void) fprintf(dd->err, "OUT of memory\n"); - info->thresholdReached = 0; - childBranch = zero; - } else { - info->thresholdReached--; - if (info->thresholdReached <= 0) { - info->findShortestPath = 1; - } - childBranch = BuildSubsetBdd(dd, pathTable, - child, info, subsetNodeTable); - - } /* end of st_insert successful */ - } /* end of threshold hasnt been reached yet */ - } /* end of else node not found in maxpath table */ - } /* end of if (path length of node = maxpath) */ - } /* end if !(childPathLength > maxpath) */ - if (childBranch == NULL) { - /* deref other stuff incase reordering has taken place */ - if (ThenBranch != NULL) { - Cudd_RecursiveDeref(dd, ThenBranch); - ThenBranch = NULL; - } - if (ElseBranch != NULL) { - Cudd_RecursiveDeref(dd, ElseBranch); - ElseBranch = NULL; + if (ElseBranch != NULL) { + Cudd_RecursiveDeref(dd, ElseBranch); + ElseBranch = NULL; + } + return(NULL); } - return(NULL); - } - cuddRef(childBranch); + cuddRef(childBranch); - if (child == Nv) { - ThenBranch = childBranch; - } else { - ElseBranch = childBranch; - } - processingDone++; + if (child == Nv) { + ThenBranch = childBranch; + } else { + ElseBranch = childBranch; + } + processingDone++; - } /*end of while processing Nv, Nnv */ + } /*end of while processing Nv, Nnv */ info->findShortestPath = 0; topid = Cudd_NodeReadIndex(N); @@ -1520,7 +1552,7 @@ BuildSubsetBdd( cuddRef(topv); neW = cuddBddIteRecur(dd, topv, ThenBranch, ElseBranch); if (neW != NULL) { - cuddRef(neW); + cuddRef(neW); } Cudd_RecursiveDeref(dd, topv); Cudd_RecursiveDeref(dd, ThenBranch); @@ -1529,76 +1561,76 @@ BuildSubsetBdd( /* Hard Limit of threshold has been imposed */ if (subsetNodeTable != NIL(st_table)) { - /* check if a new node is created */ - regNew = Cudd_Regular(neW); - /* subset node table keeps all new nodes that have been created to keep - * a running count of how many nodes have been built in the subset. - */ - if (!st_lookup(subsetNodeTable, (char *)regNew, (char **)&entry)) { - if (!Cudd_IsConstant(regNew)) { - if (st_insert(subsetNodeTable, (char *)regNew, - (char *)NULL) == ST_OUT_OF_MEM) { - (void) fprintf(dd->err, "Out of memory\n"); - return (NULL); - } - if (st_count(subsetNodeTable) > info->threshold) { - info->thresholdReached = 0; - } + /* check if a new node is created */ + regNew = Cudd_Regular(neW); + /* subset node table keeps all new nodes that have been created to keep + * a running count of how many nodes have been built in the subset. + */ + if (!st_lookup(subsetNodeTable, (char *)regNew, (char **)&entry)) { + if (!Cudd_IsConstant(regNew)) { + if (st_insert(subsetNodeTable, (char *)regNew, + (char *)NULL) == ST_OUT_OF_MEM) { + (void) fprintf(dd->err, "Out of memory\n"); + return (NULL); + } + if (st_count(subsetNodeTable) > info->threshold) { + info->thresholdReached = 0; + } + } } } - } if (neW == NULL) { - return(NULL); + return(NULL); } else { - /*store computed result in regular form*/ - if (Cudd_IsComplement(node)) { - nodeStat->compResult = neW; - cuddRef(nodeStat->compResult); - /* if the new node is the same as the corresponding node in the - * original bdd then its complement need not be computed as it - * cannot be larger than the node itself - */ - if (neW == node) { + /*store computed result in regular form*/ + if (Cudd_IsComplement(node)) { + nodeStat->compResult = neW; + cuddRef(nodeStat->compResult); + /* if the new node is the same as the corresponding node in the + * original bdd then its complement need not be computed as it + * cannot be larger than the node itself + */ + if (neW == node) { #ifdef DD_DEBUG - thishit++; + thishit++; #endif - /* if a result for the node has already been computed, then - * it can only be smaller than teh node itself. hence store - * the node result in order not to break recombination - */ - if (nodeStat->regResult != NULL) { - Cudd_RecursiveDeref(dd, nodeStat->regResult); - } - nodeStat->regResult = Cudd_Not(neW); - cuddRef(nodeStat->regResult); - } + /* if a result for the node has already been computed, then + * it can only be smaller than teh node itself. hence store + * the node result in order not to break recombination + */ + if (nodeStat->regResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->regResult); + } + nodeStat->regResult = Cudd_Not(neW); + cuddRef(nodeStat->regResult); + } - } else { - nodeStat->regResult = neW; - cuddRef(nodeStat->regResult); - if (neW == node) { + } else { + nodeStat->regResult = neW; + cuddRef(nodeStat->regResult); + if (neW == node) { #ifdef DD_DEBUG - thishit++; + thishit++; #endif - if (nodeStat->compResult != NULL) { - Cudd_RecursiveDeref(dd, nodeStat->compResult); - } - nodeStat->compResult = Cudd_Not(neW); - cuddRef(nodeStat->compResult); + if (nodeStat->compResult != NULL) { + Cudd_RecursiveDeref(dd, nodeStat->compResult); + } + nodeStat->compResult = Cudd_Not(neW); + cuddRef(nodeStat->compResult); + } } - } - cuddDeref(neW); - return(neW); + cuddDeref(neW); + return(neW); } /* end of else i.e. Subset != NULL */ } /* end of BuildSubsetBdd */ /**Function******************************************************************** - Synopsis [Procedure to free the result dds stored in the NodeDist pages.] + Synopsis [Procedure to free te result dds stored in the NodeDist pages.] Description [None] @@ -1619,13 +1651,15 @@ stPathTableDdFree( nodeStat = (NodeDist_t *)value; dd = (DdManager *)arg; if (nodeStat->regResult != NULL) { - Cudd_RecursiveDeref(dd, nodeStat->regResult); + Cudd_RecursiveDeref(dd, nodeStat->regResult); } if (nodeStat->compResult != NULL) { - Cudd_RecursiveDeref(dd, nodeStat->compResult); + Cudd_RecursiveDeref(dd, nodeStat->compResult); } return(ST_CONTINUE); } /* end of stPathTableFree */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddSymmetry.c b/src/bdd/cudd/cuddSymmetry.c index 535ba978..a7ef7845 100644 --- a/src/bdd/cudd/cuddSymmetry.c +++ b/src/bdd/cudd/cuddSymmetry.c @@ -7,34 +7,61 @@ Synopsis [Functions for symmetry-based variable reordering.] Description [External procedures included in this file: - <ul> - <li> Cudd_SymmProfile() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddSymmCheck() - <li> cuddSymmSifting() - <li> cuddSymmSiftingConv() - </ul> - Static procedures included in this module: - <ul> - <li> ddSymmUniqueCompare() - <li> ddSymmSiftingAux() - <li> ddSymmSiftingConvAux() - <li> ddSymmSiftingUp() - <li> ddSymmSiftingDown() - <li> ddSymmGroupMove() - <li> ddSymmGroupMoveBackward() - <li> ddSymmSiftingBackward() - <li> ddSymmSummary() - </ul>] + <ul> + <li> Cudd_SymmProfile() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddSymmCheck() + <li> cuddSymmSifting() + <li> cuddSymmSiftingConv() + </ul> + Static procedures included in this module: + <ul> + <li> ddSymmUniqueCompare() + <li> ddSymmSiftingAux() + <li> ddSymmSiftingConvAux() + <li> ddSymmSiftingUp() + <li> ddSymmSiftingDown() + <li> ddSymmGroupMove() + <li> ddSymmGroupMoveBackward() + <li> ddSymmSiftingBackward() + <li> ddSymmSummary() + </ul>] Author [Shipra Panda, Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -44,6 +71,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -63,14 +91,14 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddSymmetry.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddSymmetry.c,v 1.26 2009/02/19 16:23:54 fabio Exp $"; #endif -static int *entry; +static int *entry; -extern int ddTotalNumberSwapping; +extern int ddTotalNumberSwapping; #ifdef DD_STATS -extern int ddTotalNISwaps; +extern int ddTotalNISwaps; #endif /*---------------------------------------------------------------------------*/ @@ -83,15 +111,15 @@ extern int ddTotalNISwaps; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int ddSymmUniqueCompare ARGS((int *ptrX, int *ptrY)); -static int ddSymmSiftingAux ARGS((DdManager *table, int x, int xLow, int xHigh)); -static int ddSymmSiftingConvAux ARGS((DdManager *table, int x, int xLow, int xHigh)); -static Move * ddSymmSiftingUp ARGS((DdManager *table, int y, int xLow)); -static Move * ddSymmSiftingDown ARGS((DdManager *table, int x, int xHigh)); -static int ddSymmGroupMove ARGS((DdManager *table, int x, int y, Move **moves)); -static int ddSymmGroupMoveBackward ARGS((DdManager *table, int x, int y)); -static int ddSymmSiftingBackward ARGS((DdManager *table, Move *moves, int size)); -static void ddSymmSummary ARGS((DdManager *table, int lower, int upper, int *symvars, int *symgroups)); +static int ddSymmUniqueCompare (int *ptrX, int *ptrY); +static int ddSymmSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static int ddSymmSiftingConvAux (DdManager *table, int x, int xLow, int xHigh); +static Move * ddSymmSiftingUp (DdManager *table, int y, int xLow); +static Move * ddSymmSiftingDown (DdManager *table, int x, int xHigh); +static int ddSymmGroupMove (DdManager *table, int x, int y, Move **moves); +static int ddSymmGroupMoveBackward (DdManager *table, int x, int y); +static int ddSymmSiftingBackward (DdManager *table, Move *moves, int size); +static void ddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups); /**AutomaticEnd***************************************************************/ @@ -121,22 +149,22 @@ Cudd_SymmProfile( int TotalSymmGroups = 0; for (i = lower; i <= upper; i++) { - if (table->subtables[i].next != (unsigned) i) { - x = i; - (void) fprintf(table->out,"Group:"); - do { - (void) fprintf(table->out," %d",table->invperm[x]); - TotalSymm++; - gbot = x; - x = table->subtables[x].next; - } while (x != i); - TotalSymmGroups++; + if (table->subtables[i].next != (unsigned) i) { + x = i; + (void) fprintf(table->out,"Group:"); + do { + (void) fprintf(table->out," %d",table->invperm[x]); + TotalSymm++; + gbot = x; + x = table->subtables[x].next; + } while (x != i); + TotalSymmGroups++; #ifdef DD_DEBUG - assert(table->subtables[gbot].next == (unsigned) i); + assert(table->subtables[gbot].next == (unsigned) i); #endif - i = gbot; - (void) fprintf(table->out,"\n"); - } + i = gbot; + (void) fprintf(table->out,"\n"); + } } (void) fprintf(table->out,"Total Symmetric = %d\n",TotalSymm); (void) fprintf(table->out,"Total Groups = %d\n",TotalSymmGroups); @@ -167,11 +195,11 @@ cuddSymmCheck( int y) { DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10; - int comple; /* f0 is complemented */ - int xsymmy; /* x and y may be positively symmetric */ - int xsymmyp; /* x and y may be negatively symmetric */ - int arccount; /* number of arcs from layer x to layer y */ - int TotalRefCount; /* total reference count of layer y minus 1 */ + int comple; /* f0 is complemented */ + int xsymmy; /* x and y may be positively symmetric */ + int xsymmyp; /* x and y may be negatively symmetric */ + int arccount; /* number of arcs from layer x to layer y */ + int TotalRefCount; /* total reference count of layer y minus 1 */ int yindex; int i; DdNodePtr *list; @@ -188,12 +216,12 @@ cuddSymmCheck( ** function, it has one arc coming from a layer different from x. */ if (table->subtables[x].keys == 1) { - return(0); + return(0); } yindex = table->invperm[y]; if (table->subtables[y].keys == 1) { - if (table->vars[yindex]->ref == 1) - return(0); + if (table->vars[yindex]->ref == 1) + return(0); } xsymmy = xsymmyp = 1; @@ -201,45 +229,45 @@ cuddSymmCheck( slots = table->subtables[x].slots; list = table->subtables[x].nodelist; for (i = 0; i < slots; i++) { - f = list[i]; - while (f != sentinel) { - /* Find f1, f0, f11, f10, f01, f00. */ - f1 = cuddT(f); - f0 = Cudd_Regular(cuddE(f)); - comple = Cudd_IsComplement(cuddE(f)); - if ((int) f1->index == yindex) { - arccount++; - f11 = cuddT(f1); f10 = cuddE(f1); - } else { - if ((int) f0->index != yindex) { - /* If f is an isolated projection function it is - ** allowed to bypass layer y. - */ - if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) - return(0); /* f bypasses layer y */ - } - f11 = f10 = f1; - } - if ((int) f0->index == yindex) { - arccount++; - f01 = cuddT(f0); f00 = cuddE(f0); - } else { - f01 = f00 = f0; - } - if (comple) { - f01 = Cudd_Not(f01); - f00 = Cudd_Not(f00); - } - - if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) { - xsymmy &= f01 == f10; - xsymmyp &= f11 == f00; - if ((xsymmy == 0) && (xsymmyp == 0)) - return(0); - } - - f = f->next; - } /* while */ + f = list[i]; + while (f != sentinel) { + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + f0 = Cudd_Regular(cuddE(f)); + comple = Cudd_IsComplement(cuddE(f)); + if ((int) f1->index == yindex) { + arccount++; + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + if ((int) f0->index != yindex) { + /* If f is an isolated projection function it is + ** allowed to bypass layer y. + */ + if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) + return(0); /* f bypasses layer y */ + } + f11 = f10 = f1; + } + if ((int) f0->index == yindex) { + arccount++; + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = f00 = f0; + } + if (comple) { + f01 = Cudd_Not(f01); + f00 = Cudd_Not(f00); + } + + if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) { + xsymmy &= f01 == f10; + xsymmyp &= f11 == f00; + if ((xsymmy == 0) && (xsymmyp == 0)) + return(0); + } + + f = f->next; + } /* while */ } /* for */ /* Calculate the total reference counts of y */ @@ -247,19 +275,19 @@ cuddSymmCheck( slots = table->subtables[y].slots; list = table->subtables[y].nodelist; for (i = 0; i < slots; i++) { - f = list[i]; - while (f != sentinel) { - TotalRefCount += f->ref; - f = f->next; - } + f = list[i]; + while (f != sentinel) { + TotalRefCount += f->ref; + f = f->next; + } } #if defined(DD_DEBUG) && defined(DD_VERBOSE) if (arccount == TotalRefCount) { - xindex = table->invperm[x]; - (void) fprintf(table->out, - "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", - xindex,yindex,x,y); + xindex = table->invperm[x]; + (void) fprintf(table->out, + "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); } #endif @@ -294,18 +322,17 @@ int cuddSymmSifting( DdManager * table, int lower, - int upper, - int TimeStop) + int upper) { - int i; - int *var; - int size; - int x; - int result; - int symvars; - int symgroups; + int i; + int *var; + int size; + int x; + int result; + int symvars; + int symgroups; #ifdef DD_STATS - int previousSize; + int previousSize; #endif size = table->size; @@ -314,53 +341,54 @@ cuddSymmSifting( var = NULL; entry = ABC_ALLOC(int,size); if (entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddSymmSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingOutOfMem; } var = ABC_ALLOC(int,size); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddSymmSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingOutOfMem; } for (i = 0; i < size; i++) { - x = table->perm[i]; - entry[i] = table->subtables[x].keys; - var[i] = i; + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; } - qsort((void *)var,size,sizeof(int),(int (*)(const void *, const void *))ddSymmUniqueCompare); + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); /* Initialize the symmetry of each subtable to itself. */ for (i = lower; i <= upper; i++) { - table->subtables[i].next = i; + table->subtables[i].next = i; } for (i = 0; i < ddMin(table->siftMaxVar,size); i++) { - if (ddTotalNumberSwapping >= table->siftMaxSwap) - break; - if ( TimeStop && TimeStop < clock() ) - break; - x = table->perm[var[i]]; + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + // enable timeout during variable reodering - alanmi 2/13/11 + if ( table->TimeStop && table->TimeStop < clock() ) + break; + x = table->perm[var[i]]; #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - if (x < lower || x > upper) continue; - if (table->subtables[x].next == (unsigned) x) { - result = ddSymmSiftingAux(table,x,lower,upper); - if (!result) goto ddSymmSiftingOutOfMem; + if (x < lower || x > upper) continue; + if (table->subtables[x].next == (unsigned) x) { + result = ddSymmSiftingAux(table,x,lower,upper); + if (!result) goto ddSymmSiftingOutOfMem; #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + - table->isolated) { - (void) fprintf(table->out,"+"); /* should never happen */ - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } + } } ABC_FREE(var); @@ -370,9 +398,9 @@ cuddSymmSifting( #ifdef DD_STATS (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n", - symvars); + symvars); (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups", - symgroups); + symgroups); #endif return(1+symvars); @@ -416,17 +444,17 @@ cuddSymmSiftingConv( int lower, int upper) { - int i; - int *var; - int size; - int x; - int result; - int symvars; - int symgroups; - int classes; - int initialSize; + int i; + int *var; + int size; + int x; + int result; + int symvars; + int symgroups; + int classes; + int initialSize; #ifdef DD_STATS - int previousSize; + int previousSize; #endif initialSize = table->keys - table->isolated; @@ -437,111 +465,111 @@ cuddSymmSiftingConv( var = NULL; entry = ABC_ALLOC(int,size); if (entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddSymmSiftingConvOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingConvOutOfMem; } var = ABC_ALLOC(int,size); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto ddSymmSiftingConvOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto ddSymmSiftingConvOutOfMem; } for (i = 0; i < size; i++) { - x = table->perm[i]; - entry[i] = table->subtables[x].keys; - var[i] = i; + x = table->perm[i]; + entry[i] = table->subtables[x].keys; + var[i] = i; } - qsort((void *)var,size,sizeof(int),(int (*)(const void *, const void *))ddSymmUniqueCompare); + qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); /* Initialize the symmetry of each subtable to itself ** for first pass of converging symmetric sifting. */ for (i = lower; i <= upper; i++) { - table->subtables[i].next = i; + table->subtables[i].next = i; } for (i = 0; i < ddMin(table->siftMaxVar, table->size); i++) { - if (ddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->perm[var[i]]; - if (x < lower || x > upper) continue; - /* Only sift if not in symmetry group already. */ - if (table->subtables[x].next == (unsigned) x) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->perm[var[i]]; + if (x < lower || x > upper) continue; + /* Only sift if not in symmetry group already. */ + if (table->subtables[x].next == (unsigned) x) { #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - result = ddSymmSiftingAux(table,x,lower,upper); - if (!result) goto ddSymmSiftingConvOutOfMem; + result = ddSymmSiftingAux(table,x,lower,upper); + if (!result) goto ddSymmSiftingConvOutOfMem; #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + - table->isolated) { - (void) fprintf(table->out,"+"); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } + } } /* Sifting now until convergence. */ while ((unsigned) initialSize > table->keys - table->isolated) { - initialSize = table->keys - table->isolated; + initialSize = table->keys - table->isolated; #ifdef DD_STATS - (void) fprintf(table->out,"\n"); + (void) fprintf(table->out,"\n"); #endif /* Here we consider only one representative for each symmetry class. */ - for (x = lower, classes = 0; x <= upper; x++, classes++) { - while ((unsigned) x < table->subtables[x].next) { - x = table->subtables[x].next; + for (x = lower, classes = 0; x <= upper; x++, classes++) { + while ((unsigned) x < table->subtables[x].next) { + x = table->subtables[x].next; + } + /* Here x is the largest index in a group. + ** Groups consist of adjacent variables. + ** Hence, the next increment of x will move it to a new group. + */ + i = table->invperm[x]; + entry[i] = table->subtables[x].keys; + var[classes] = i; } - /* Here x is the largest index in a group. - ** Groups consist of adjacent variables. - ** Hence, the next increment of x will move it to a new group. - */ - i = table->invperm[x]; - entry[i] = table->subtables[x].keys; - var[classes] = i; - } - qsort((void *)var,classes,sizeof(int),(int (*)(const void *, const void *))ddSymmUniqueCompare); + qsort((void *)var,classes,sizeof(int),(DD_QSFP)ddSymmUniqueCompare); - /* Now sift. */ - for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { - if (ddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->perm[var[i]]; - if ((unsigned) x >= table->subtables[x].next) { + /* Now sift. */ + for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { + if (ddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->perm[var[i]]; + if ((unsigned) x >= table->subtables[x].next) { #ifdef DD_STATS - previousSize = table->keys - table->isolated; + previousSize = table->keys - table->isolated; #endif - result = ddSymmSiftingConvAux(table,x,lower,upper); - if (!result ) goto ddSymmSiftingConvOutOfMem; + result = ddSymmSiftingConvAux(table,x,lower,upper); + if (!result ) goto ddSymmSiftingConvOutOfMem; #ifdef DD_STATS - if (table->keys < (unsigned) previousSize + table->isolated) { - (void) fprintf(table->out,"-"); - } else if (table->keys > (unsigned) previousSize + - table->isolated) { - (void) fprintf(table->out,"+"); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keys < (unsigned) previousSize + table->isolated) { + (void) fprintf(table->out,"-"); + } else if (table->keys > (unsigned) previousSize + + table->isolated) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } - } /* for */ + } + } /* for */ } ddSymmSummary(table, lower, upper, &symvars, &symgroups); #ifdef DD_STATS (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n", - symvars); + symvars); (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups", - symgroups); + symgroups); #endif ABC_FREE(var); @@ -583,7 +611,7 @@ ddSymmUniqueCompare( { #if 0 if (entry[*ptrY] == entry[*ptrX]) { - return((*ptrX) - (*ptrY)); + return((*ptrX) - (*ptrY)); } #endif return(entry[*ptrY] - entry[*ptrX]); @@ -612,12 +640,12 @@ ddSymmSiftingAux( int xHigh) { Move *move; - Move *moveUp; /* list of up moves */ - Move *moveDown; /* list of down moves */ - int initialSize; - int result; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; int i; - int topbot; /* index to either top or bottom of symmetry group */ + int topbot; /* index to either top or bottom of symmetry group */ int initGroupSize, finalGroupSize; @@ -632,259 +660,259 @@ ddSymmSiftingAux( moveUp = NULL; if ((x - xLow) > (xHigh - x)) { - /* Will go down first, unless x == xHigh: - ** Look for consecutive symmetries above x. - */ - for (i = x; i > xLow; i--) { - if (!cuddSymmCheck(table,i-1,i)) - break; - topbot = table->subtables[i-1].next; /* find top of i-1's group */ - table->subtables[i-1].next = i; - table->subtables[x].next = topbot; /* x is bottom of group so its */ - /* next is top of i-1's group */ - i = topbot + 1; /* add 1 for i--; new i is top of symm group */ - } + /* Will go down first, unless x == xHigh: + ** Look for consecutive symmetries above x. + */ + for (i = x; i > xLow; i--) { + if (!cuddSymmCheck(table,i-1,i)) + break; + topbot = table->subtables[i-1].next; /* find top of i-1's group */ + table->subtables[i-1].next = i; + table->subtables[x].next = topbot; /* x is bottom of group so its */ + /* next is top of i-1's group */ + i = topbot + 1; /* add 1 for i--; new i is top of symm group */ + } } else { - /* Will go up first unless x == xlow: - ** Look for consecutive symmetries below x. - */ - for (i = x; i < xHigh; i++) { - if (!cuddSymmCheck(table,i,i+1)) - break; - /* find bottom of i+1's symm group */ - topbot = i + 1; - while ((unsigned) topbot < table->subtables[topbot].next) { - topbot = table->subtables[topbot].next; + /* Will go up first unless x == xlow: + ** Look for consecutive symmetries below x. + */ + for (i = x; i < xHigh; i++) { + if (!cuddSymmCheck(table,i,i+1)) + break; + /* find bottom of i+1's symm group */ + topbot = i + 1; + while ((unsigned) topbot < table->subtables[topbot].next) { + topbot = table->subtables[topbot].next; + } + table->subtables[topbot].next = table->subtables[i].next; + table->subtables[i].next = i + 1; + i = topbot - 1; /* subtract 1 for i++; new i is bottom of group */ } - table->subtables[topbot].next = table->subtables[i].next; - table->subtables[i].next = i + 1; - i = topbot - 1; /* subtract 1 for i++; new i is bottom of group */ - } } /* Now x may be in the middle of a symmetry group. ** Find bottom of x's symm group. */ while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; + x = table->subtables[x].next; if (x == xLow) { /* Sift down */ #ifdef DD_DEBUG - /* x must be a singleton */ - assert((unsigned) x == table->subtables[x].next); + /* x must be a singleton */ + assert((unsigned) x == table->subtables[x].next); #endif - if (x == xHigh) return(1); /* just one variable */ + if (x == xHigh) return(1); /* just one variable */ - initGroupSize = 1; + initGroupSize = 1; - moveDown = ddSymmSiftingDown(table,x,xHigh); - /* after this point x --> xHigh, unless early term */ - if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; - if (moveDown == NULL) return(1); + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* after this point x --> xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + if (moveDown == NULL) return(1); - x = moveDown->y; - /* Find bottom of x's group */ - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; - } + x = moveDown->y; + /* Find bottom of x's group */ + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } #ifdef DD_DEBUG - /* x should be the top of the symmetry group and i the bottom */ - assert((unsigned) i >= table->subtables[i].next); - assert((unsigned) x == table->subtables[i].next); + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); #endif - finalGroupSize = i - x + 1; + finalGroupSize = i - x + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetry groups detected, return to best position */ - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } else { - initialSize = table->keys - table->isolated; - moveUp = ddSymmSiftingUp(table,x,xLow); - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } - if (!result) goto ddSymmSiftingAuxOutOfMem; + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ - /* Find top of x's symm group */ - i = x; /* bottom */ - x = table->subtables[x].next; /* top */ + /* Find top of x's symm group */ + i = x; /* bottom */ + x = table->subtables[x].next; /* top */ - if (x == xLow) return(1); /* just one big group */ + if (x == xLow) return(1); /* just one big group */ - initGroupSize = i - x + 1; + initGroupSize = i - x + 1; - moveUp = ddSymmSiftingUp(table,x,xLow); - /* after this point x --> xLow, unless early term */ - if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; - if (moveUp == NULL) return(1); + moveUp = ddSymmSiftingUp(table,x,xLow); + /* after this point x --> xLow, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + if (moveUp == NULL) return(1); - x = moveUp->x; - /* Find top of x's group */ - i = table->subtables[x].next; + x = moveUp->x; + /* Find top of x's group */ + i = table->subtables[x].next; #ifdef DD_DEBUG - /* x should be the bottom of the symmetry group and i the top */ - assert((unsigned) x >= table->subtables[x].next); - assert((unsigned) i == table->subtables[x].next); + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); #endif - finalGroupSize = x - i + 1; + finalGroupSize = x - i + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetry groups detected, return to best position */ - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } else { - initialSize = table->keys - table->isolated; - moveDown = ddSymmSiftingDown(table,x,xHigh); - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } - if (!result) goto ddSymmSiftingAuxOutOfMem; + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) goto ddSymmSiftingAuxOutOfMem; } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ - moveDown = ddSymmSiftingDown(table,x,xHigh); - /* at this point x == xHigh, unless early term */ - if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; - - if (moveDown != NULL) { - x = moveDown->y; /* x is top here */ - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; - } - } else { - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; /* x is top here */ + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + x = table->subtables[i].next; } - x = table->subtables[i].next; - } #ifdef DD_DEBUG /* x should be the top of the symmetry group and i the bottom */ - assert((unsigned) i >= table->subtables[i].next); - assert((unsigned) x == table->subtables[i].next); + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); #endif - initGroupSize = i - x + 1; + initGroupSize = i - x + 1; - moveUp = ddSymmSiftingUp(table,x,xLow); - if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + moveUp = ddSymmSiftingUp(table,x,xLow); + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; - if (moveUp != NULL) { - x = moveUp->x; - i = table->subtables[x].next; - } else { - i = x; - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - } + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } #ifdef DD_DEBUG - /* x should be the bottom of the symmetry group and i the top */ - assert((unsigned) x >= table->subtables[x].next); - assert((unsigned) i == table->subtables[x].next); + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); #endif - finalGroupSize = x - i + 1; + finalGroupSize = x - i + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetry groups detected, return to best position */ - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } else { - while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); } - initialSize = table->keys - table->isolated; - moveDown = ddSymmSiftingDown(table,x,xHigh); - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } - if (!result) goto ddSymmSiftingAuxOutOfMem; + if (!result) goto ddSymmSiftingAuxOutOfMem; } else { /* moving up first: shorter */ /* Find top of x's symmetry group */ - x = table->subtables[x].next; + x = table->subtables[x].next; - moveUp = ddSymmSiftingUp(table,x,xLow); - /* at this point x == xHigh, unless early term */ - if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xHigh, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem; - if (moveUp != NULL) { - x = moveUp->x; - i = table->subtables[x].next; - } else { - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - i = table->subtables[x].next; - } + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = table->subtables[x].next; + } #ifdef DD_DEBUG /* x is bottom of the symmetry group and i is top */ - assert((unsigned) x >= table->subtables[x].next); - assert((unsigned) i == table->subtables[x].next); + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); #endif - initGroupSize = x - i + 1; - - moveDown = ddSymmSiftingDown(table,x,xHigh); - if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + initGroupSize = x - i + 1; - if (moveDown != NULL) { - x = moveDown->y; - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; + moveDown = ddSymmSiftingDown(table,x,xHigh); + if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + x = table->subtables[x].next; } - } else { - i = x; - x = table->subtables[x].next; - } #ifdef DD_DEBUG - /* x should be the top of the symmetry group and i the bottom */ - assert((unsigned) i >= table->subtables[i].next); - assert((unsigned) x == table->subtables[i].next); + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); #endif - finalGroupSize = i - x + 1; + finalGroupSize = i - x + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetries detected, go back to best position */ - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } else { - while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); } - initialSize = table->keys - table->isolated; - moveUp = ddSymmSiftingUp(table,x,xLow); - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } - if (!result) goto ddSymmSiftingAuxOutOfMem; + if (!result) goto ddSymmSiftingAuxOutOfMem; } while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(1); ddSymmSiftingAuxOutOfMem: if (moveDown != MV_OOM) { - while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; - } + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } } if (moveUp != MV_OOM) { - while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; - } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } } return(0); @@ -914,10 +942,10 @@ ddSymmSiftingConvAux( int xHigh) { Move *move; - Move *moveUp; /* list of up moves */ - Move *moveDown; /* list of down moves */ - int initialSize; - int result; + Move *moveUp; /* list of up moves */ + Move *moveDown; /* list of down moves */ + int initialSize; + int result; int i; int initGroupSize, finalGroupSize; @@ -929,148 +957,148 @@ ddSymmSiftingConvAux( if (x == xLow) { /* Sift down */ #ifdef DD_DEBUG - /* x is bottom of symmetry group */ - assert((unsigned) x >= table->subtables[x].next); + /* x is bottom of symmetry group */ + assert((unsigned) x >= table->subtables[x].next); #endif i = table->subtables[x].next; - initGroupSize = x - i + 1; + initGroupSize = x - i + 1; - moveDown = ddSymmSiftingDown(table,x,xHigh); - /* at this point x == xHigh, unless early term */ - if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; - if (moveDown == NULL) return(1); + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + if (moveDown == NULL) return(1); - x = moveDown->y; - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; - } + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } #ifdef DD_DEBUG - /* x should be the top of the symmetric group and i the bottom */ - assert((unsigned) i >= table->subtables[i].next); - assert((unsigned) x == table->subtables[i].next); + /* x should be the top of the symmetric group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); #endif - finalGroupSize = i - x + 1; + finalGroupSize = i - x + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetries detected, go back to best position */ - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } else { - initialSize = table->keys - table->isolated; - moveUp = ddSymmSiftingUp(table,x,xLow); - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } - if (!result) goto ddSymmSiftingConvAuxOutOfMem; + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } + if (!result) goto ddSymmSiftingConvAuxOutOfMem; } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */ - /* Find top of x's symm group */ - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - i = x; /* bottom */ - x = table->subtables[x].next; /* top */ + /* Find top of x's symm group */ + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = x; /* bottom */ + x = table->subtables[x].next; /* top */ - if (x == xLow) return(1); + if (x == xLow) return(1); - initGroupSize = i - x + 1; + initGroupSize = i - x + 1; - moveUp = ddSymmSiftingUp(table,x,xLow); - /* at this point x == xLow, unless early term */ - if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; - if (moveUp == NULL) return(1); + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xLow, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + if (moveUp == NULL) return(1); - x = moveUp->x; - i = table->subtables[x].next; + x = moveUp->x; + i = table->subtables[x].next; #ifdef DD_DEBUG - /* x should be the bottom of the symmetry group and i the top */ - assert((unsigned) x >= table->subtables[x].next); - assert((unsigned) i == table->subtables[x].next); + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); #endif - finalGroupSize = x - i + 1; + finalGroupSize = x - i + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetry groups detected, return to best position */ - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } else { - initialSize = table->keys - table->isolated; - moveDown = ddSymmSiftingDown(table,x,xHigh); - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } - if (!result) - goto ddSymmSiftingConvAuxOutOfMem; + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } + if (!result) + goto ddSymmSiftingConvAuxOutOfMem; } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ - moveDown = ddSymmSiftingDown(table,x,xHigh); - /* at this point x == xHigh, unless early term */ - if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; - - if (moveDown != NULL) { - x = moveDown->y; - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; + moveDown = ddSymmSiftingDown(table,x,xHigh); + /* at this point x == xHigh, unless early term */ + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + i = x; + x = table->subtables[x].next; } - } else { - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - i = x; - x = table->subtables[x].next; - } #ifdef DD_DEBUG /* x should be the top of the symmetry group and i the bottom */ - assert((unsigned) i >= table->subtables[i].next); - assert((unsigned) x == table->subtables[i].next); + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); #endif - initGroupSize = i - x + 1; + initGroupSize = i - x + 1; - moveUp = ddSymmSiftingUp(table,x,xLow); - if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + moveUp = ddSymmSiftingUp(table,x,xLow); + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; - if (moveUp != NULL) { - x = moveUp->x; - i = table->subtables[x].next; - } else { - i = x; - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - } + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } #ifdef DD_DEBUG - /* x should be the bottom of the symmetry group and i the top */ - assert((unsigned) x >= table->subtables[x].next); - assert((unsigned) i == table->subtables[x].next); + /* x should be the bottom of the symmetry group and i the top */ + assert((unsigned) x >= table->subtables[x].next); + assert((unsigned) i == table->subtables[x].next); #endif - finalGroupSize = x - i + 1; + finalGroupSize = x - i + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetry groups detected, return to best position */ - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } else { - while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + if (initGroupSize == finalGroupSize) { + /* No new symmetry groups detected, return to best position */ + result = ddSymmSiftingBackward(table,moveUp,initialSize); + } else { + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } + initialSize = table->keys - table->isolated; + moveDown = ddSymmSiftingDown(table,x,xHigh); + result = ddSymmSiftingBackward(table,moveDown,initialSize); } - initialSize = table->keys - table->isolated; - moveDown = ddSymmSiftingDown(table,x,xHigh); - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } - if (!result) goto ddSymmSiftingConvAuxOutOfMem; + if (!result) goto ddSymmSiftingConvAuxOutOfMem; } else { /* moving up first: shorter */ - /* Find top of x's symmetry group */ - x = table->subtables[x].next; + /* Find top of x's symmetry group */ + x = table->subtables[x].next; - moveUp = ddSymmSiftingUp(table,x,xLow); - /* at this point x == xHigh, unless early term */ - if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + moveUp = ddSymmSiftingUp(table,x,xLow); + /* at this point x == xHigh, unless early term */ + if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; - if (moveUp != NULL) { - x = moveUp->x; - i = table->subtables[x].next; - } else { - i = x; - while ((unsigned) x < table->subtables[x].next) - x = table->subtables[x].next; - } + if (moveUp != NULL) { + x = moveUp->x; + i = table->subtables[x].next; + } else { + i = x; + while ((unsigned) x < table->subtables[x].next) + x = table->subtables[x].next; + } #ifdef DD_DEBUG /* x is bottom of the symmetry group and i is top */ assert((unsigned) x >= table->subtables[x].next); @@ -1078,69 +1106,69 @@ ddSymmSiftingConvAux( #endif initGroupSize = x - i + 1; - moveDown = ddSymmSiftingDown(table,x,xHigh); - if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; - - if (moveDown != NULL) { - x = moveDown->y; - i = x; - while ((unsigned) i < table->subtables[i].next) { - i = table->subtables[i].next; + moveDown = ddSymmSiftingDown(table,x,xHigh); + if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem; + + if (moveDown != NULL) { + x = moveDown->y; + i = x; + while ((unsigned) i < table->subtables[i].next) { + i = table->subtables[i].next; + } + } else { + i = x; + x = table->subtables[x].next; } - } else { - i = x; - x = table->subtables[x].next; - } #ifdef DD_DEBUG - /* x should be the top of the symmetry group and i the bottom */ - assert((unsigned) i >= table->subtables[i].next); - assert((unsigned) x == table->subtables[i].next); + /* x should be the top of the symmetry group and i the bottom */ + assert((unsigned) i >= table->subtables[i].next); + assert((unsigned) x == table->subtables[i].next); #endif - finalGroupSize = i - x + 1; + finalGroupSize = i - x + 1; - if (initGroupSize == finalGroupSize) { - /* No new symmetries detected, go back to best position */ - result = ddSymmSiftingBackward(table,moveDown,initialSize); - } else { - while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + if (initGroupSize == finalGroupSize) { + /* No new symmetries detected, go back to best position */ + result = ddSymmSiftingBackward(table,moveDown,initialSize); + } else { + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } + initialSize = table->keys - table->isolated; + moveUp = ddSymmSiftingUp(table,x,xLow); + result = ddSymmSiftingBackward(table,moveUp,initialSize); } - initialSize = table->keys - table->isolated; - moveUp = ddSymmSiftingUp(table,x,xLow); - result = ddSymmSiftingBackward(table,moveUp,initialSize); - } - if (!result) goto ddSymmSiftingConvAuxOutOfMem; + if (!result) goto ddSymmSiftingConvAuxOutOfMem; } while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(1); ddSymmSiftingConvAuxOutOfMem: if (moveDown != MV_OOM) { - while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *) moveDown); - moveDown = move; - } + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } } if (moveUp != MV_OOM) { - while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *) moveUp); - moveUp = move; - } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } } return(0); @@ -1171,8 +1199,8 @@ ddSymmSiftingUp( { Move *moves; Move *move; - int x; - int size; + int x; + int size; int i; int gxtop,gybot; int limitSize; @@ -1180,7 +1208,7 @@ ddSymmSiftingUp( int zindex; int z; int isolated; - int L; /* lower bound on DD size */ + int L; /* lower bound on DD size */ #ifdef DD_DEBUG int checkL; #endif @@ -1198,92 +1226,92 @@ ddSymmSiftingUp( limitSize = L = table->keys - table->isolated; gybot = y; while ((unsigned) gybot < table->subtables[gybot].next) - gybot = table->subtables[gybot].next; + gybot = table->subtables[gybot].next; for (z = xLow + 1; z <= gybot; z++) { - zindex = table->invperm[z]; - if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - L -= table->subtables[z].keys - isolated; - } + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L -= table->subtables[z].keys - isolated; + } } x = cuddNextLow(table,y); while (x >= xLow && L <= limitSize) { #ifdef DD_DEBUG - gybot = y; - while ((unsigned) gybot < table->subtables[gybot].next) - gybot = table->subtables[gybot].next; - checkL = table->keys - table->isolated; - for (z = xLow + 1; z <= gybot; z++) { - zindex = table->invperm[z]; - if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - checkL -= table->subtables[z].keys - isolated; + gybot = y; + while ((unsigned) gybot < table->subtables[gybot].next) + gybot = table->subtables[gybot].next; + checkL = table->keys - table->isolated; + for (z = xLow + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + checkL -= table->subtables[z].keys - isolated; + } } - } - assert(L == checkL); + assert(L == checkL); #endif - gxtop = table->subtables[x].next; - if (cuddSymmCheck(table,x,y)) { - /* Symmetry found, attach symm groups */ - table->subtables[x].next = y; - i = table->subtables[y].next; - while (table->subtables[i].next != (unsigned) y) - i = table->subtables[i].next; - table->subtables[i].next = gxtop; - } else if (table->subtables[x].next == (unsigned) x && - table->subtables[y].next == (unsigned) y) { - /* x and y have self symmetry */ - xindex = table->invperm[x]; - size = cuddSwapInPlace(table,x,y); + gxtop = table->subtables[x].next; + if (cuddSymmCheck(table,x,y)) { + /* Symmetry found, attach symm groups */ + table->subtables[x].next = y; + i = table->subtables[y].next; + while (table->subtables[i].next != (unsigned) y) + i = table->subtables[i].next; + table->subtables[i].next = gxtop; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y have self symmetry */ + xindex = table->invperm[x]; + size = cuddSwapInPlace(table,x,y); #ifdef DD_DEBUG - assert(table->subtables[x].next == (unsigned) x); - assert(table->subtables[y].next == (unsigned) y); + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); #endif - if (size == 0) goto ddSymmSiftingUpOutOfMem; - /* Update the lower bound. */ - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[xindex]->ref == 1; - L += table->subtables[y].keys - isolated; - } - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSymmSiftingUpOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - if ((double) size > (double) limitSize * table->maxGrowth) - return(moves); - if (size < limitSize) limitSize = size; - } else { /* Group move */ - size = ddSymmGroupMove(table,x,y,&moves); - if (size == 0) goto ddSymmSiftingUpOutOfMem; - /* Update the lower bound. */ - z = moves->y; - do { - zindex = table->invperm[z]; - if (cuddTestInteract(table,zindex,yindex)) { - isolated = table->vars[zindex]->ref == 1; - L += table->subtables[z].keys - isolated; + if (size == 0) goto ddSymmSiftingUpOutOfMem; + /* Update the lower bound. */ + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[xindex]->ref == 1; + L += table->subtables[y].keys - isolated; + } + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSymmSiftingUpOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + size = ddSymmGroupMove(table,x,y,&moves); + if (size == 0) goto ddSymmSiftingUpOutOfMem; + /* Update the lower bound. */ + z = moves->y; + do { + zindex = table->invperm[z]; + if (cuddTestInteract(table,zindex,yindex)) { + isolated = table->vars[zindex]->ref == 1; + L += table->subtables[z].keys - isolated; + } + z = table->subtables[z].next; + } while (z != (int) moves->y); + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; } - z = table->subtables[z].next; - } while (z != (int) moves->y); - if ((double) size > (double) limitSize * table->maxGrowth) - return(moves); - if (size < limitSize) limitSize = size; - } - y = gxtop; - x = cuddNextLow(table,y); + y = gxtop; + x = cuddNextLow(table,y); } return(moves); ddSymmSiftingUpOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(MV_OOM); @@ -1313,11 +1341,11 @@ ddSymmSiftingDown( { Move *moves; Move *move; - int y; - int size; + int y; + int size; int limitSize; int gxtop,gybot; - int R; /* upper bound on node decrease */ + int R; /* upper bound on node decrease */ int xindex, yindex; int isolated; int z; @@ -1333,98 +1361,98 @@ ddSymmSiftingDown( limitSize = size = table->keys - table->isolated; R = 0; for (z = xHigh; z > gxtop; z--) { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - R += table->subtables[z].keys - isolated; - } + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } } y = cuddNextHigh(table,x); while (y <= xHigh && size - R < limitSize) { #ifdef DD_DEBUG - gxtop = table->subtables[x].next; - checkR = 0; - for (z = xHigh; z > gxtop; z--) { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - checkR += table->subtables[z].keys - isolated; - } - } - assert(R == checkR); -#endif - gybot = table->subtables[y].next; - while (table->subtables[gybot].next != (unsigned) y) - gybot = table->subtables[gybot].next; - if (cuddSymmCheck(table,x,y)) { - /* Symmetry found, attach symm groups */ gxtop = table->subtables[x].next; - table->subtables[x].next = y; - table->subtables[gybot].next = gxtop; - } else if (table->subtables[x].next == (unsigned) x && - table->subtables[y].next == (unsigned) y) { - /* x and y have self symmetry */ - /* Update upper bound on node decrease. */ - yindex = table->invperm[y]; - if (cuddTestInteract(table,xindex,yindex)) { - isolated = table->vars[yindex]->ref == 1; - R -= table->subtables[y].keys - isolated; + checkR = 0; + for (z = xHigh; z > gxtop; z--) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + checkR += table->subtables[z].keys - isolated; + } } - size = cuddSwapInPlace(table,x,y); + assert(R == checkR); +#endif + gybot = table->subtables[y].next; + while (table->subtables[gybot].next != (unsigned) y) + gybot = table->subtables[gybot].next; + if (cuddSymmCheck(table,x,y)) { + /* Symmetry found, attach symm groups */ + gxtop = table->subtables[x].next; + table->subtables[x].next = y; + table->subtables[gybot].next = gxtop; + } else if (table->subtables[x].next == (unsigned) x && + table->subtables[y].next == (unsigned) y) { + /* x and y have self symmetry */ + /* Update upper bound on node decrease. */ + yindex = table->invperm[y]; + if (cuddTestInteract(table,xindex,yindex)) { + isolated = table->vars[yindex]->ref == 1; + R -= table->subtables[y].keys - isolated; + } + size = cuddSwapInPlace(table,x,y); #ifdef DD_DEBUG - assert(table->subtables[x].next == (unsigned) x); - assert(table->subtables[y].next == (unsigned) y); + assert(table->subtables[x].next == (unsigned) x); + assert(table->subtables[y].next == (unsigned) y); #endif - if (size == 0) goto ddSymmSiftingDownOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) goto ddSymmSiftingDownOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - if ((double) size > (double) limitSize * table->maxGrowth) - return(moves); - if (size < limitSize) limitSize = size; - } else { /* Group move */ - /* Update upper bound on node decrease: first phase. */ - gxtop = table->subtables[x].next; - z = gxtop + 1; - do { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - R -= table->subtables[z].keys - isolated; - } - z++; - } while (z <= gybot); - size = ddSymmGroupMove(table,x,y,&moves); - if (size == 0) goto ddSymmSiftingDownOutOfMem; - if ((double) size > (double) limitSize * table->maxGrowth) - return(moves); - if (size < limitSize) limitSize = size; - /* Update upper bound on node decrease: second phase. */ - gxtop = table->subtables[gybot].next; - for (z = gxtop + 1; z <= gybot; z++) { - zindex = table->invperm[z]; - if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { - isolated = table->vars[zindex]->ref == 1; - R += table->subtables[z].keys - isolated; - } + if (size == 0) goto ddSymmSiftingDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) goto ddSymmSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + } else { /* Group move */ + /* Update upper bound on node decrease: first phase. */ + gxtop = table->subtables[x].next; + z = gxtop + 1; + do { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R -= table->subtables[z].keys - isolated; + } + z++; + } while (z <= gybot); + size = ddSymmGroupMove(table,x,y,&moves); + if (size == 0) goto ddSymmSiftingDownOutOfMem; + if ((double) size > (double) limitSize * table->maxGrowth) + return(moves); + if (size < limitSize) limitSize = size; + /* Update upper bound on node decrease: second phase. */ + gxtop = table->subtables[gybot].next; + for (z = gxtop + 1; z <= gybot; z++) { + zindex = table->invperm[z]; + if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) { + isolated = table->vars[zindex]->ref == 1; + R += table->subtables[z].keys - isolated; + } + } } - } - x = gybot; - y = cuddNextHigh(table,x); + x = gybot; + y = cuddNextHigh(table,x); } return(moves); ddSymmSiftingDownOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(MV_OOM); @@ -1451,13 +1479,13 @@ ddSymmGroupMove( Move ** moves) { Move *move; - int size = 0; // Suppress "might be used uninitialized" + int size; int i,j; int xtop,xbot,xsize,ytop,ybot,ysize,newxtop; - int swapx = 0,swapy = 0; // Suppress "might be used uninitialized" + int swapx,swapy; -#if DD_DEBUG - assert(x < y); /* we assume that x < y */ +#ifdef DD_DEBUG + assert(x < y); /* we assume that x < y */ #endif /* Find top, bottom, and size for the two groups. */ xbot = x; @@ -1465,39 +1493,39 @@ ddSymmGroupMove( xsize = xbot - xtop + 1; ybot = y; while ((unsigned) ybot < table->subtables[ybot].next) - ybot = table->subtables[ybot].next; + ybot = table->subtables[ybot].next; ytop = y; ysize = ybot - ytop + 1; /* Sift the variables of the second group up through the first group. */ for (i = 1; i <= ysize; i++) { for (j = 1; j <= xsize; j++) { - size = cuddSwapInPlace(table,x,y); - if (size == 0) return(0); - swapx = x; swapy = y; - y = x; + size = cuddSwapInPlace(table,x,y); + if (size == 0) return(0); + swapx = x; swapy = y; + y = x; + x = y - 1; + } + y = ytop + i; x = y - 1; } - y = ytop + i; - x = y - 1; - } /* fix symmetries */ y = xtop; /* ytop is now where xtop used to be */ for (i = 0; i < ysize-1 ; i++) { - table->subtables[y].next = y + 1; - y = y + 1; + table->subtables[y].next = y + 1; + y = y + 1; } table->subtables[y].next = xtop; /* y is bottom of its group, join */ - /* its symmetry to top of its group */ + /* its symmetry to top of its group */ x = y + 1; newxtop = x; for (i = 0; i < xsize - 1 ; i++) { - table->subtables[x].next = x + 1; - x = x + 1; + table->subtables[x].next = x + 1; + x = x + 1; } table->subtables[x].next = newxtop; /* x is bottom of its group, join */ - /* its symmetry to top of its group */ + /* its symmetry to top of its group */ /* Store group move */ move = (Move *) cuddDynamicAllocNode(table); if (move == NULL) return(0); @@ -1530,11 +1558,11 @@ ddSymmGroupMoveBackward( int x, int y) { - int size = 0; // Suppress "might be used uninitialized" + int size; int i,j; - int xtop,xbot,xsize,ytop,ybot,ysize,newxtop; + int xtop,xbot,xsize,ytop,ybot,ysize,newxtop; -#if DD_DEBUG +#ifdef DD_DEBUG assert(x < y); /* We assume that x < y */ #endif @@ -1544,38 +1572,38 @@ ddSymmGroupMoveBackward( xsize = xbot - xtop + 1; ybot = y; while ((unsigned) ybot < table->subtables[ybot].next) - ybot = table->subtables[ybot].next; + ybot = table->subtables[ybot].next; ytop = y; ysize = ybot - ytop + 1; /* Sift the variables of the second group up through the first group. */ for (i = 1; i <= ysize; i++) { for (j = 1; j <= xsize; j++) { - size = cuddSwapInPlace(table,x,y); - if (size == 0) return(0); - y = x; - x = cuddNextLow(table,y); - } - y = ytop + i; - x = y - 1; + size = cuddSwapInPlace(table,x,y); + if (size == 0) return(0); + y = x; + x = cuddNextLow(table,y); + } + y = ytop + i; + x = y - 1; } /* Fix symmetries. */ y = xtop; for (i = 0; i < ysize-1 ; i++) { - table->subtables[y].next = y + 1; - y = y + 1; + table->subtables[y].next = y + 1; + y = y + 1; } table->subtables[y].next = xtop; /* y is bottom of its group, join */ - /* its symmetry to top of its group */ + /* its symmetry to top of its group */ x = y + 1; newxtop = x; for (i = 0; i < xsize-1 ; i++) { - table->subtables[x].next = x + 1; - x = x + 1; + table->subtables[x].next = x + 1; + x = x + 1; } table->subtables[x].next = newxtop; /* x is bottom of its group, join */ - /* its symmetry to top of its group */ + /* its symmetry to top of its group */ return(size); @@ -1605,23 +1633,23 @@ ddSymmSiftingBackward( int res; for (move = moves; move != NULL; move = move->next) { - if (move->size < size) { - size = move->size; - } + if (move->size < size) { + size = move->size; + } } for (move = moves; move != NULL; move = move->next) { - if (move->size == size) return(1); - if (table->subtables[move->x].next == move->x && table->subtables[move->y].next == move->y) { - res = cuddSwapInPlace(table,(int)move->x,(int)move->y); + if (move->size == size) return(1); + if (table->subtables[move->x].next == move->x && table->subtables[move->y].next == move->y) { + res = cuddSwapInPlace(table,(int)move->x,(int)move->y); #ifdef DD_DEBUG - assert(table->subtables[move->x].next == move->x); - assert(table->subtables[move->y].next == move->y); + assert(table->subtables[move->x].next == move->x); + assert(table->subtables[move->y].next == move->y); #endif - } else { /* Group move necessary */ - res = ddSymmGroupMoveBackward(table,(int)move->x,(int)move->y); - } - if (!res) return(0); + } else { /* Group move necessary */ + res = ddSymmGroupMoveBackward(table,(int)move->x,(int)move->y); + } + if (!res) return(0); } return(1); @@ -1652,19 +1680,19 @@ ddSymmSummary( int TotalSymmGroups = 0; for (i = lower; i <= upper; i++) { - if (table->subtables[i].next != (unsigned) i) { - TotalSymmGroups++; - x = i; - do { - TotalSymm++; - gbot = x; - x = table->subtables[x].next; - } while (x != i); + if (table->subtables[i].next != (unsigned) i) { + TotalSymmGroups++; + x = i; + do { + TotalSymm++; + gbot = x; + x = table->subtables[x].next; + } while (x != i); #ifdef DD_DEBUG - assert(table->subtables[gbot].next == (unsigned) i); + assert(table->subtables[gbot].next == (unsigned) i); #endif - i = gbot; - } + i = gbot; + } } *symvars = TotalSymm; *symgroups = TotalSymmGroups; @@ -1672,5 +1700,7 @@ ddSymmSummary( return; } /* end of ddSymmSummary */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddTable.c b/src/bdd/cudd/cuddTable.c index 6ec6f6e7..040e4670 100644 --- a/src/bdd/cudd/cuddTable.c +++ b/src/bdd/cudd/cuddTable.c @@ -7,72 +7,99 @@ Synopsis [Unique table management functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_Prime() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddAllocNode() - <li> cuddInitTable() - <li> cuddFreeTable() - <li> cuddGarbageCollect() - <li> cuddGarbageCollectZdd() - <li> cuddZddGetNode() - <li> cuddZddGetNodeIVO() - <li> cuddUniqueInter() - <li> cuddUniqueInterIVO() - <li> cuddUniqueInterZdd() - <li> cuddUniqueConst() - <li> cuddRehash() - <li> cuddShrinkSubtable() - <li> cuddInsertSubtables() - <li> cuddDestroySubtables() - <li> cuddResizeTableZdd() - <li> cuddSlowTableGrowth() - </ul> - Static procedures included in this module: - <ul> - <li> ddRehashZdd() - <li> ddResizeTable() - <li> cuddFindParent() - <li> cuddOrderedInsert() - <li> cuddOrderedThread() - <li> cuddRotateLeft() - <li> cuddRotateRight() - <li> cuddDoRebalance() - <li> cuddCheckCollisionOrdering() - </ul>] + <ul> + <li> Cudd_Prime() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddAllocNode() + <li> cuddInitTable() + <li> cuddFreeTable() + <li> cuddGarbageCollect() + <li> cuddZddGetNode() + <li> cuddZddGetNodeIVO() + <li> cuddUniqueInter() + <li> cuddUniqueInterIVO() + <li> cuddUniqueInterZdd() + <li> cuddUniqueConst() + <li> cuddRehash() + <li> cuddShrinkSubtable() + <li> cuddInsertSubtables() + <li> cuddDestroySubtables() + <li> cuddResizeTableZdd() + <li> cuddSlowTableGrowth() + </ul> + Static procedures included in this module: + <ul> + <li> ddRehashZdd() + <li> ddResizeTable() + <li> cuddFindParent() + <li> cuddOrderedInsert() + <li> cuddOrderedThread() + <li> cuddRotateLeft() + <li> cuddRotateRight() + <li> cuddDoRebalance() + <li> cuddCheckCollisionOrdering() + </ul>] SeeAlso [] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST /* Constants for red/black trees. */ #define DD_STACK_SIZE 128 #define DD_RED 0 #define DD_BLACK 1 #define DD_PAGE_SIZE 8192 #define DD_PAGE_MASK ~(DD_PAGE_SIZE - 1) -#define DD_INSERT_COMPARE(x,y) \ - (((ptruint) (x) & DD_PAGE_MASK) - ((ptruint) (y) & DD_PAGE_MASK)) +#endif #endif /*---------------------------------------------------------------------------*/ @@ -94,7 +121,7 @@ typedef union hack { /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.122 2009/02/19 16:24:28 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -103,7 +130,10 @@ static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.1.1.1 2003/02/24 22:23:53 #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST /* Macros for red/black trees. */ +#define DD_INSERT_COMPARE(x,y) \ + (((ptruint) (x) & DD_PAGE_MASK) - ((ptruint) (y) & DD_PAGE_MASK)) #define DD_COLOR(p) ((p)->index) #define DD_IS_BLACK(p) ((p)->index == DD_BLACK) #define DD_IS_RED(p) ((p)->index == DD_RED) @@ -111,6 +141,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.1.1.1 2003/02/24 22:23:53 #define DD_RIGHT(p) cuddE(p) #define DD_NEXT(p) ((p)->next) #endif +#endif /**AutomaticStart*************************************************************/ @@ -119,20 +150,22 @@ static char rcsid[] DD_UNUSED = "$Id: cuddTable.c,v 1.1.1.1 2003/02/24 22:23:53 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void ddRehashZdd ARGS((DdManager *unique, int i)); -static int ddResizeTable ARGS((DdManager *unique, int index)); -static int cuddFindParent ARGS((DdManager *table, DdNode *node)); -DD_INLINE static void ddFixLimits ARGS((DdManager *unique)); -static void cuddOrderedInsert ARGS((DdNodePtr *root, DdNodePtr node)); -static DdNode * cuddOrderedThread ARGS((DdNode *root, DdNode *list)); -static void cuddRotateLeft ARGS((DdNodePtr *nodeP)); -static void cuddRotateRight ARGS((DdNodePtr *nodeP)); -static void cuddDoRebalance ARGS((DdNodePtr **stack, int stackN)); -static void ddPatchTree ARGS((DdManager *dd, MtrNode *treenode)); +static void ddRehashZdd (DdManager *unique, int i); +static int ddResizeTable (DdManager *unique, int index); +static int cuddFindParent (DdManager *table, DdNode *node); +DD_INLINE static void ddFixLimits (DdManager *unique); +#ifdef DD_RED_BLACK_FREE_LIST +static void cuddOrderedInsert (DdNodePtr *root, DdNodePtr node); +static DdNode * cuddOrderedThread (DdNode *root, DdNode *list); +static void cuddRotateLeft (DdNodePtr *nodeP); +static void cuddRotateRight (DdNodePtr *nodeP); +static void cuddDoRebalance (DdNodePtr **stack, int stackN); +#endif +static void ddPatchTree (DdManager *dd, MtrNode *treenode); #ifdef DD_DEBUG -static int cuddCheckCollisionOrdering ARGS((DdManager *unique, int i, int j)); +static int cuddCheckCollisionOrdering (DdManager *unique, int i, int j); #endif -static void ddReportRefMess ARGS((DdManager *unique, int i, char *caller)); +static void ddReportRefMess (DdManager *unique, int i, const char *caller); /**AutomaticEnd***************************************************************/ @@ -161,18 +194,18 @@ Cudd_Prime( do { p++; if (p&1) { - pn = 1; - i = 3; - while ((unsigned) (i * i) <= p) { - if (p % i == 0) { + pn = 1; + i = 3; + while ((unsigned) (i * i) <= p) { + if (p % i == 0) { + pn = 0; + break; + } + i += 2; + } + } else { pn = 0; - break; - } - i += 2; } - } else { - pn = 0; - } } while (!pn); return(p); @@ -205,87 +238,89 @@ cuddAllocNode( int i; DdNodePtr *mem; DdNode *list, *node; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); - - if (unique->nextFree == NULL) { /* free list is empty */ - /* Check for exceeded limits. */ - if ((unique->keys - unique->dead) + (unique->keysZ - unique->deadZ) > - unique->maxLive) { - unique->errorCode = CUDD_TOO_MANY_NODES; - return(NULL); - } - if (unique->stash == NULL || unique->memused > unique->maxmemhard) { - (void) cuddGarbageCollect(unique,1); - mem = NULL; - } - if (unique->nextFree == NULL) { - if (unique->memused > unique->maxmemhard) { - unique->errorCode = CUDD_MAX_MEM_EXCEEDED; - return(NULL); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; + + if (unique->nextFree == NULL) { /* free list is empty */ + /* Check for exceeded limits. */ + if ((unique->keys - unique->dead) + (unique->keysZ - unique->deadZ) > + unique->maxLive) { + unique->errorCode = CUDD_TOO_MANY_NODES; + return(NULL); } - /* Try to allocate a new block. */ - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); - MMoutOfMemory = saveHandler; - if (mem == NULL) { - /* No more memory: Try collecting garbage. If this succeeds, - ** we end up with mem still NULL, but unique->nextFree != - ** NULL. */ - if (cuddGarbageCollect(unique,1) == 0) { - /* Last resort: Free the memory stashed away, if there - ** any. If this succeeeds, mem != NULL and - ** unique->nextFree still NULL. */ - if (unique->stash != NULL) { - ABC_FREE(unique->stash); - unique->stash = NULL; - /* Inhibit resizing of tables. */ - cuddSlowTableGrowth(unique); - /* Now try again. */ - mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); + if (unique->stash == NULL || unique->memused > unique->maxmemhard) { + (void) cuddGarbageCollect(unique,1); + mem = NULL; + } + if (unique->nextFree == NULL) { + if (unique->memused > unique->maxmemhard) { + unique->errorCode = CUDD_MAX_MEM_EXCEEDED; + return(NULL); } + /* Try to allocate a new block. */ + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); + MMoutOfMemory = saveHandler; if (mem == NULL) { - /* Out of luck. Call the default handler to do - ** whatever it specifies for a failed malloc. - ** If this handler returns, then set error code, - ** print warning, and return. */ - (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); - unique->errorCode = CUDD_MEMORY_OUT; + /* No more memory: Try collecting garbage. If this succeeds, + ** we end up with mem still NULL, but unique->nextFree != + ** NULL. */ + if (cuddGarbageCollect(unique,1) == 0) { + /* Last resort: Free the memory stashed away, if there + ** any. If this succeeeds, mem != NULL and + ** unique->nextFree still NULL. */ + if (unique->stash != NULL) { + ABC_FREE(unique->stash); + unique->stash = NULL; + /* Inhibit resizing of tables. */ + cuddSlowTableGrowth(unique); + /* Now try again. */ + mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); + } + if (mem == NULL) { + /* Out of luck. Call the default handler to do + ** whatever it specifies for a failed malloc. + ** If this handler returns, then set error code, + ** print warning, and return. */ + (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1)); + unique->errorCode = CUDD_MEMORY_OUT; #ifdef DD_VERBOSE - (void) fprintf(unique->err, - "cuddAllocNode: out of memory"); - (void) fprintf(unique->err, "Memory in use = %ld\n", - unique->memused); -#endif - return(NULL); + (void) fprintf(unique->err, + "cuddAllocNode: out of memory"); + (void) fprintf(unique->err, "Memory in use = %lu\n", + unique->memused); +#endif + return(NULL); + } + } + } + if (mem != NULL) { /* successful allocation; slice memory */ + ptruint offset; + unique->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); + mem[0] = (DdNodePtr) unique->memoryList; + unique->memoryList = mem; + + /* Here we rely on the fact that a DdNode is as large + ** as 4 pointers. */ + offset = (ptruint) mem & (sizeof(DdNode) - 1); + mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); + assert(((ptruint) mem & (sizeof(DdNode) - 1)) == 0); + list = (DdNode *) mem; + + i = 1; + do { + list[i - 1].ref = 0; + list[i - 1].next = &list[i]; + } while (++i < DD_MEM_CHUNK); + + list[DD_MEM_CHUNK-1].ref = 0; + list[DD_MEM_CHUNK-1].next = NULL; + + unique->nextFree = &list[0]; } - } - } - if (mem != NULL) { /* successful allocation; slice memory */ - ptruint offset; - unique->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode); - mem[0] = (DdNodePtr) unique->memoryList; - unique->memoryList = mem; - - /* Here we rely on the fact that a DdNode is as large - ** as 4 pointers. */ - offset = (ptruint) mem & (sizeof(DdNode) - 1); - mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); - assert(((ptruint) mem & (sizeof(DdNode) - 1)) == 0); - list = (DdNode *) mem; - - i = 1; - do { - list[i - 1].next = &list[i]; - } while (++i < DD_MEM_CHUNK); - - list[DD_MEM_CHUNK-1].next = NULL; - - unique->nextFree = &list[0]; } } - } unique->allocated++; node = unique->nextFree; unique->nextFree = node->next; @@ -313,15 +348,15 @@ cuddInitTable( unsigned int numSlots /* Initial size of the BDD subtables */, unsigned int looseUpTo /* Limit for fast table growth */) { - DdManager *unique = ABC_ALLOC(DdManager,1); - int i, j; - DdNodePtr *nodelist; - DdNode *sentinel; + DdManager *unique = ABC_ALLOC(DdManager,1); + int i, j; + DdNodePtr *nodelist; + DdNode *sentinel; unsigned int slots; int shift; if (unique == NULL) { - return(NULL); + return(NULL); } sentinel = &(unique->sentinel); sentinel->ref = 0; @@ -332,7 +367,7 @@ cuddInitTable( unique->epsilon = DD_EPSILON; unique->maxGrowth = DD_MAX_REORDER_GROWTH; unique->maxGrowthAlt = 2.0 * DD_MAX_REORDER_GROWTH; - unique->reordCycle = 0; /* do not use alternate threshold */ + unique->reordCycle = 0; /* do not use alternate threshold */ unique->size = numVars; unique->sizeZ = numVarsZ; unique->maxSize = ddMax(DD_DEFAULT_RESIZE, numVars); @@ -341,14 +376,14 @@ cuddInitTable( /* Adjust the requested number of slots to a power of 2. */ slots = 8; while (slots < numSlots) { - slots <<= 1; + slots <<= 1; } unique->initSlots = slots; shift = sizeof(int) * 8 - cuddComputeFloorLog2(slots); unique->slots = (numVars + numVarsZ + 1) * slots; unique->keys = 0; - unique->maxLive = ~0; /* very large number */ + unique->maxLive = ~0; /* very large number */ unique->keysZ = 0; unique->dead = 0; unique->deadZ = 0; @@ -360,39 +395,60 @@ cuddInitTable( unique->reclaimed = 0; unique->subtables = ABC_ALLOC(DdSubtable,unique->maxSize); if (unique->subtables == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique); + return(NULL); } unique->subtableZ = ABC_ALLOC(DdSubtable,unique->maxSizeZ); if (unique->subtableZ == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique); + return(NULL); } unique->perm = ABC_ALLOC(int,unique->maxSize); if (unique->perm == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique); + return(NULL); } unique->invperm = ABC_ALLOC(int,unique->maxSize); if (unique->invperm == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique); + return(NULL); } unique->permZ = ABC_ALLOC(int,unique->maxSizeZ); if (unique->permZ == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique); + return(NULL); } unique->invpermZ = ABC_ALLOC(int,unique->maxSizeZ); if (unique->invpermZ == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique->permZ); + ABC_FREE(unique); + return(NULL); } unique->map = NULL; unique->stack = ABC_ALLOC(DdNodePtr,ddMax(unique->maxSize,unique->maxSizeZ)+1); if (unique->stack == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique->permZ); + ABC_FREE(unique->invpermZ); + ABC_FREE(unique); + return(NULL); } unique->stack[0] = NULL; /* to suppress harmless UMR */ @@ -400,55 +456,85 @@ cuddInitTable( unique->deathRowDepth = 1 << cuddComputeFloorLog2(unique->looseUpTo >> 2); unique->deathRow = ABC_ALLOC(DdNodePtr,unique->deathRowDepth); if (unique->deathRow == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique->permZ); + ABC_FREE(unique->invpermZ); + ABC_FREE(unique->stack); + ABC_FREE(unique); + return(NULL); } for (i = 0; i < unique->deathRowDepth; i++) { - unique->deathRow[i] = NULL; + unique->deathRow[i] = NULL; } unique->nextDead = 0; unique->deadMask = unique->deathRowDepth - 1; #endif for (i = 0; (unsigned) i < numVars; i++) { - unique->subtables[i].slots = slots; - unique->subtables[i].shift = shift; - unique->subtables[i].keys = 0; - unique->subtables[i].dead = 0; - unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; - unique->subtables[i].bindVar = 0; - unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; - unique->subtables[i].pairIndex = 0; - unique->subtables[i].varHandled = 0; - unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; + unique->subtables[i].slots = slots; + unique->subtables[i].shift = shift; + unique->subtables[i].keys = 0; + unique->subtables[i].dead = 0; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[i].bindVar = 0; + unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[i].pairIndex = 0; + unique->subtables[i].varHandled = 0; + unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; - nodelist = unique->subtables[i].nodelist = ABC_ALLOC(DdNodePtr,slots); - if (nodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = sentinel; - } - unique->perm[i] = i; - unique->invperm[i] = i; + nodelist = unique->subtables[i].nodelist = ABC_ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; j < i; j++) { + ABC_FREE(unique->subtables[j].nodelist); + } + ABC_FREE(unique->subtables); + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique->permZ); + ABC_FREE(unique->invpermZ); + ABC_FREE(unique->stack); + ABC_FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = sentinel; + } + unique->perm[i] = i; + unique->invperm[i] = i; } for (i = 0; (unsigned) i < numVarsZ; i++) { - unique->subtableZ[i].slots = slots; - unique->subtableZ[i].shift = shift; - unique->subtableZ[i].keys = 0; - unique->subtableZ[i].dead = 0; - unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; - nodelist = unique->subtableZ[i].nodelist = ABC_ALLOC(DdNodePtr,slots); - if (nodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = NULL; - } - unique->permZ[i] = i; - unique->invpermZ[i] = i; + unique->subtableZ[i].slots = slots; + unique->subtableZ[i].shift = shift; + unique->subtableZ[i].keys = 0; + unique->subtableZ[i].dead = 0; + unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + nodelist = unique->subtableZ[i].nodelist = ABC_ALLOC(DdNodePtr,slots); + if (nodelist == NULL) { + for (j = 0; (unsigned) j < numVars; j++) { + ABC_FREE(unique->subtables[j].nodelist); + } + ABC_FREE(unique->subtables); + for (j = 0; j < i; j++) { + ABC_FREE(unique->subtableZ[j].nodelist); + } + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique->permZ); + ABC_FREE(unique->invpermZ); + ABC_FREE(unique->stack); + ABC_FREE(unique); + return(NULL); + } + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; + } + unique->permZ[i] = i; + unique->invpermZ[i] = i; } unique->constants.slots = slots; unique->constants.shift = shift; @@ -457,30 +543,43 @@ cuddInitTable( unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; nodelist = unique->constants.nodelist = ABC_ALLOC(DdNodePtr,slots); if (nodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(NULL); + for (j = 0; (unsigned) j < numVars; j++) { + ABC_FREE(unique->subtables[j].nodelist); + } + ABC_FREE(unique->subtables); + for (j = 0; (unsigned) j < numVarsZ; j++) { + ABC_FREE(unique->subtableZ[j].nodelist); + } + ABC_FREE(unique->subtableZ); + ABC_FREE(unique->perm); + ABC_FREE(unique->invperm); + ABC_FREE(unique->permZ); + ABC_FREE(unique->invpermZ); + ABC_FREE(unique->stack); + ABC_FREE(unique); + return(NULL); } for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = NULL; + nodelist[j] = NULL; } unique->memoryList = NULL; unique->nextFree = NULL; unique->memused = sizeof(DdManager) + (unique->maxSize + unique->maxSizeZ) - * (sizeof(DdSubtable) + 2 * sizeof(int)) + (numVars + 1) * - slots * sizeof(DdNodePtr) + - (ddMax(unique->maxSize,unique->maxSizeZ) + 1) * sizeof(DdNodePtr); + * (sizeof(DdSubtable) + 2 * sizeof(int)) + (numVars + 1) * + slots * sizeof(DdNodePtr) + + (ddMax(unique->maxSize,unique->maxSizeZ) + 1) * sizeof(DdNodePtr); #ifndef DD_NO_DEATH_ROW unique->memused += unique->deathRowDepth * sizeof(DdNodePtr); #endif /* Initialize fields concerned with automatic dynamic reordering */ unique->reorderings = 0; - unique->autoDyn = 0; /* initially disabled */ - unique->autoDynZ = 0; /* initially disabled */ - unique->realign = 0; /* initially disabled */ - unique->realignZ = 0; /* initially disabled */ + unique->autoDyn = 0; /* initially disabled */ + unique->autoDynZ = 0; /* initially disabled */ + unique->realign = 0; /* initially disabled */ + unique->realignZ = 0; /* initially disabled */ unique->reordered = 0; unique->autoMethod = CUDD_REORDER_SIFT; unique->autoMethodZ = CUDD_REORDER_SIFT; @@ -513,7 +612,7 @@ cuddInitTable( unique->errorCode = CUDD_NO_ERROR; /* Initialize statistical counters. */ - unique->maxmemhard = (long) ((~ (unsigned long) 0) >> 1); + unique->maxmemhard = ~ 0UL; unique->garbageCollections = 0; unique->GCTime = 0; unique->reordTime = 0; @@ -560,18 +659,18 @@ cuddFreeTable( if (unique->univ != NULL) cuddZddFreeUniv(unique); while (memlist != NULL) { - next = (DdNodePtr *) memlist[0]; /* link to next block */ - ABC_FREE(memlist); - memlist = next; + next = (DdNodePtr *) memlist[0]; /* link to next block */ + ABC_FREE(memlist); + memlist = next; } unique->nextFree = NULL; unique->memoryList = NULL; for (i = 0; i < unique->size; i++) { - ABC_FREE(unique->subtables[i].nodelist); + ABC_FREE(unique->subtables[i].nodelist); } for (i = 0; i < unique->sizeZ; i++) { - ABC_FREE(unique->subtableZ[i].nodelist); + ABC_FREE(unique->subtableZ[i].nodelist); } ABC_FREE(unique->constants.nodelist); ABC_FREE(unique->subtables); @@ -591,15 +690,15 @@ cuddFreeTable( if (unique->treeZ != NULL) Mtr_FreeTree(unique->treeZ); if (unique->linear != NULL) ABC_FREE(unique->linear); while (unique->preGCHook != NULL) - Cudd_RemoveHook(unique,unique->preGCHook->f,CUDD_PRE_GC_HOOK); + Cudd_RemoveHook(unique,unique->preGCHook->f,CUDD_PRE_GC_HOOK); while (unique->postGCHook != NULL) - Cudd_RemoveHook(unique,unique->postGCHook->f,CUDD_POST_GC_HOOK); + Cudd_RemoveHook(unique,unique->postGCHook->f,CUDD_POST_GC_HOOK); while (unique->preReorderingHook != NULL) - Cudd_RemoveHook(unique,unique->preReorderingHook->f, - CUDD_PRE_REORDERING_HOOK); + Cudd_RemoveHook(unique,unique->preReorderingHook->f, + CUDD_PRE_REORDERING_HOOK); while (unique->postReorderingHook != NULL) - Cudd_RemoveHook(unique,unique->postReorderingHook->f, - CUDD_POST_REORDERING_HOOK); + Cudd_RemoveHook(unique,unique->postReorderingHook->f, + CUDD_POST_REORDERING_HOOK); ABC_FREE(unique); } /* end of cuddFreeTable */ @@ -607,9 +706,9 @@ cuddFreeTable( /**Function******************************************************************** - Synopsis [Performs garbage collection on a unique table.] + Synopsis [Performs garbage collection on the unique tables.] - Description [Performs garbage collection on a unique table. + Description [Performs garbage collection on the BDD and ZDD unique tables. If clearCache is 0, the cache is not cleared. This should only be specified if the cache has been cleared right before calling cuddGarbageCollect. (As in the case of dynamic reordering.) @@ -617,7 +716,7 @@ cuddFreeTable( SideEffects [None] - SeeAlso [cuddGarbageCollectZdd] + SeeAlso [] ******************************************************************************/ int @@ -625,18 +724,24 @@ cuddGarbageCollect( DdManager * unique, int clearCache) { - DdHook *hook; - DdCache *cache = unique->cache; - DdNode *sentinel = &(unique->sentinel); - DdNodePtr *nodelist; - int i, j, deleted, totalDeleted; - DdCache *c; - DdNode *node,*next; - DdNodePtr *lastP; - int slots; - long localTime; + DdHook *hook; + DdCache *cache = unique->cache; + DdNode *sentinel = &(unique->sentinel); + DdNodePtr *nodelist; + int i, j, deleted, totalDeleted, totalDeletedZ; + DdCache *c; + DdNode *node,*next; + DdNodePtr *lastP; + int slots; + long localTime; #ifndef DD_UNSORTED_FREE_LIST - DdNodePtr tree; +#ifdef DD_RED_BLACK_FREE_LIST + DdNodePtr tree; +#else + DdNodePtr *memListTrav, *nxtNode; + DdNode *downTrav, *sentry; + int k; +#endif #endif #ifndef DD_NO_DEATH_ROW @@ -645,18 +750,18 @@ cuddGarbageCollect( hook = unique->preGCHook; while (hook != NULL) { - int res = (hook->f)(unique,"BDD",NULL); - if (res == 0) return(0); - hook = hook->next; - } - - if (unique->dead == 0) { - hook = unique->postGCHook; - while (hook != NULL) { - int res = (hook->f)(unique,"BDD",NULL); + int res = (hook->f)(unique,"DD",NULL); if (res == 0) return(0); hook = hook->next; } + + if (unique->dead + unique->deadZ == 0) { + hook = unique->postGCHook; + while (hook != NULL) { + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; + } return(0); } @@ -664,14 +769,14 @@ cuddGarbageCollect( ** more aggressively, to reduce the frequency of garbage collection. */ if (clearCache && unique->gcFrac == DD_GC_FRAC_LO && - unique->slots <= unique->looseUpTo && unique->stash != NULL) { - unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots); + unique->slots <= unique->looseUpTo && unique->stash != NULL) { + unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots); #ifdef DD_VERBOSE - (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_HI); - (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_HI); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); #endif - unique->gcFrac = DD_GC_FRAC_HI; - return(0); + unique->gcFrac = DD_GC_FRAC_HI; + return(0); } localTime = util_cpu_time(); @@ -679,115 +784,124 @@ cuddGarbageCollect( unique->garbageCollections++; #ifdef DD_VERBOSE (void) fprintf(unique->err, - "garbage collecting (%d dead out of %d, min %d)...", - unique->dead, unique->keys, unique->minDead); + "garbage collecting (%d dead BDD nodes out of %d, min %d)...", + unique->dead, unique->keys, unique->minDead); + (void) fprintf(unique->err, + " (%d dead ZDD nodes out of %d)...", + unique->deadZ, unique->keysZ); #endif /* Remove references to garbage collected nodes from the cache. */ if (clearCache) { - slots = unique->cacheSlots; - for (i = 0; i < slots; i++) { - c = &cache[i]; - if (c->data != NULL) { - if (cuddClean(c->f)->ref == 0 || - cuddClean(c->g)->ref == 0 || - (((ptruint)c->f & 0x2) && Cudd_Regular(c->h)->ref == 0) || - (c->data != DD_NON_CONSTANT && - Cudd_Regular(c->data)->ref == 0)) { - c->data = NULL; - unique->cachedeletions++; - } + slots = unique->cacheSlots; + for (i = 0; i < slots; i++) { + c = &cache[i]; + if (c->data != NULL) { + if (cuddClean(c->f)->ref == 0 || + cuddClean(c->g)->ref == 0 || + (((ptruint)c->f & 0x2) && Cudd_Regular(c->h)->ref == 0) || + (c->data != DD_NON_CONSTANT && + Cudd_Regular(c->data)->ref == 0)) { + c->data = NULL; + unique->cachedeletions++; + } + } } - } - cuddLocalCacheClearDead(unique); + cuddLocalCacheClearDead(unique); } /* Now return dead nodes to free list. Count them for sanity check. */ totalDeleted = 0; #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST tree = NULL; #endif +#endif for (i = 0; i < unique->size; i++) { - if (unique->subtables[i].dead == 0) continue; - nodelist = unique->subtables[i].nodelist; - - deleted = 0; - slots = unique->subtables[i].slots; - for (j = 0; j < slots; j++) { - lastP = &(nodelist[j]); - node = *lastP; - while (node != sentinel) { - next = node->next; - if (node->ref == 0) { - deleted++; + if (unique->subtables[i].dead == 0) continue; + nodelist = unique->subtables[i].nodelist; + + deleted = 0; + slots = unique->subtables[i].slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != sentinel) { + next = node->next; + if (node->ref == 0) { + deleted++; #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short #endif - cuddOrderedInsert(&tree,node); + cuddOrderedInsert(&tree,node); #ifdef __osf__ #pragma pointer_size restore #endif +#endif #else - cuddDeallocNode(unique,node); + cuddDeallocNode(unique,node); #endif - } else { - *lastP = node; - lastP = &(node->next); + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = sentinel; } - node = next; + if ((unsigned) deleted != unique->subtables[i].dead) { + ddReportRefMess(unique, i, "cuddGarbageCollect"); } - *lastP = sentinel; - } - if ((unsigned) deleted != unique->subtables[i].dead) { - ddReportRefMess(unique, i, "cuddGarbageCollect"); - } - totalDeleted += deleted; - unique->subtables[i].keys -= deleted; - unique->subtables[i].dead = 0; + totalDeleted += deleted; + unique->subtables[i].keys -= deleted; + unique->subtables[i].dead = 0; } if (unique->constants.dead != 0) { - nodelist = unique->constants.nodelist; - deleted = 0; - slots = unique->constants.slots; - for (j = 0; j < slots; j++) { - lastP = &(nodelist[j]); - node = *lastP; - while (node != NULL) { - next = node->next; - if (node->ref == 0) { - deleted++; + nodelist = unique->constants.nodelist; + deleted = 0; + slots = unique->constants.slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != NULL) { + next = node->next; + if (node->ref == 0) { + deleted++; #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short #endif - cuddOrderedInsert(&tree,node); + cuddOrderedInsert(&tree,node); #ifdef __osf__ #pragma pointer_size restore #endif +#endif #else - cuddDeallocNode(unique,node); + cuddDeallocNode(unique,node); #endif - } else { - *lastP = node; - lastP = &(node->next); - } - node = next; + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = NULL; } - *lastP = NULL; - } - if ((unsigned) deleted != unique->constants.dead) { - ddReportRefMess(unique, CUDD_CONST_INDEX, "cuddGarbageCollect"); - } - totalDeleted += deleted; - unique->constants.keys -= deleted; - unique->constants.dead = 0; + if ((unsigned) deleted != unique->constants.dead) { + ddReportRefMess(unique, CUDD_CONST_INDEX, "cuddGarbageCollect"); + } + totalDeleted += deleted; + unique->constants.keys -= deleted; + unique->constants.dead = 0; } if ((unsigned) totalDeleted != unique->dead) { - ddReportRefMess(unique, -1, "cuddGarbageCollect"); + ddReportRefMess(unique, -1, "cuddGarbageCollect"); } unique->keys -= totalDeleted; unique->dead = 0; @@ -795,198 +909,110 @@ cuddGarbageCollect( unique->nodesFreed += (double) totalDeleted; #endif -#ifndef DD_UNSORTED_FREE_LIST - unique->nextFree = cuddOrderedThread(tree,unique->nextFree); -#endif - - unique->GCTime += util_cpu_time() - localTime; - - hook = unique->postGCHook; - while (hook != NULL) { - int res = (hook->f)(unique,"BDD",NULL); - if (res == 0) return(0); - hook = hook->next; - } - -#ifdef DD_VERBOSE - (void) fprintf(unique->err," done\n"); -#endif - - return(totalDeleted); - -} /* end of cuddGarbageCollect */ - - -/**Function******************************************************************** - - Synopsis [Performs garbage collection on a ZDD unique table.] - - Description [Performs garbage collection on a ZDD unique table. - If clearCache is 0, the cache is not cleared. This should only be - specified if the cache has been cleared right before calling - cuddGarbageCollectZdd. (As in the case of dynamic reordering.) - Returns the total number of deleted nodes.] - - SideEffects [None] - - SeeAlso [cuddGarbageCollect] - -******************************************************************************/ -int -cuddGarbageCollectZdd( - DdManager * unique, - int clearCache) -{ - DdHook *hook; - DdCache *cache = unique->cache; - DdNodePtr *nodelist; - int i, j, deleted, totalDeleted; - DdCache *c; - DdNode *node,*next; - DdNodePtr *lastP; - int slots; - long localTime; -#ifndef DD_UNSORTED_FREE_LIST - DdNodePtr tree; -#endif - - hook = unique->preGCHook; - while (hook != NULL) { - int res = (hook->f)(unique,"ZDD",NULL); - if (res == 0) return(0); - hook = hook->next; - } - - if (unique->deadZ == 0) { - hook = unique->postGCHook; - while (hook != NULL) { - int res = (hook->f)(unique,"ZDD",NULL); - if (res == 0) return(0); - hook = hook->next; - } - return(0); - } - - /* If many nodes are being reclaimed, we want to resize the tables - ** more aggressively, to reduce the frequency of garbage collection. - */ - if (clearCache && unique->slots <= unique->looseUpTo) { - unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots); -#ifdef DD_VERBOSE - if (unique->gcFrac == DD_GC_FRAC_LO) { - (void) fprintf(unique->err,"GC fraction = %.2f\t", - DD_GC_FRAC_HI); - (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); - } -#endif - unique->gcFrac = DD_GC_FRAC_HI; - } - - localTime = util_cpu_time(); - - unique->garbageCollections++; -#ifdef DD_VERBOSE - (void) fprintf(unique->err,"garbage collecting (%d dead out of %d)...", - unique->deadZ,unique->keysZ); -#endif - - /* Remove references to garbage collected nodes from the cache. */ - if (clearCache) { - slots = unique->cacheSlots; - for (i = 0; i < slots; i++) { - c = &cache[i]; - if (c->data != NULL) { - if (cuddClean(c->f)->ref == 0 || - cuddClean(c->g)->ref == 0 || - (((ptruint)c->f & 0x2) && Cudd_Regular(c->h)->ref == 0) || - (c->data != DD_NON_CONSTANT && - Cudd_Regular(c->data)->ref == 0)) { - c->data = NULL; - unique->cachedeletions++; - } - } - } - } - - /* Now return dead nodes to free list. Count them for sanity check. */ - totalDeleted = 0; -#ifndef DD_UNSORTED_FREE_LIST - tree = NULL; -#endif + totalDeletedZ = 0; for (i = 0; i < unique->sizeZ; i++) { - if (unique->subtableZ[i].dead == 0) continue; - nodelist = unique->subtableZ[i].nodelist; - - deleted = 0; - slots = unique->subtableZ[i].slots; - for (j = 0; j < slots; j++) { - lastP = &(nodelist[j]); - node = *lastP; - while (node != NULL) { - next = node->next; - if (node->ref == 0) { - deleted++; + if (unique->subtableZ[i].dead == 0) continue; + nodelist = unique->subtableZ[i].nodelist; + + deleted = 0; + slots = unique->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + lastP = &(nodelist[j]); + node = *lastP; + while (node != NULL) { + next = node->next; + if (node->ref == 0) { + deleted++; #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST #ifdef __osf__ #pragma pointer_size save #pragma pointer_size short #endif - cuddOrderedInsert(&tree,node); + cuddOrderedInsert(&tree,node); #ifdef __osf__ #pragma pointer_size restore #endif +#endif #else - cuddDeallocNode(unique,node); + cuddDeallocNode(unique,node); #endif - } else { - *lastP = node; - lastP = &(node->next); - } - node = next; + } else { + *lastP = node; + lastP = &(node->next); + } + node = next; + } + *lastP = NULL; } - *lastP = NULL; - } - if ((unsigned) deleted != unique->subtableZ[i].dead) { - ddReportRefMess(unique, i, "cuddGarbageCollectZdd"); - } - totalDeleted += deleted; - unique->subtableZ[i].keys -= deleted; - unique->subtableZ[i].dead = 0; + if ((unsigned) deleted != unique->subtableZ[i].dead) { + ddReportRefMess(unique, i, "cuddGarbageCollect"); + } + totalDeletedZ += deleted; + unique->subtableZ[i].keys -= deleted; + unique->subtableZ[i].dead = 0; } /* No need to examine the constant table for ZDDs. ** If we did we should be careful not to count whatever dead ** nodes we found there among the dead ZDD nodes. */ - if ((unsigned) totalDeleted != unique->deadZ) { - ddReportRefMess(unique, -1, "cuddGarbageCollectZdd"); + if ((unsigned) totalDeletedZ != unique->deadZ) { + ddReportRefMess(unique, -1, "cuddGarbageCollect"); } - unique->keysZ -= totalDeleted; + unique->keysZ -= totalDeletedZ; unique->deadZ = 0; #ifdef DD_STATS - unique->nodesFreed += (double) totalDeleted; + unique->nodesFreed += (double) totalDeletedZ; #endif + #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST unique->nextFree = cuddOrderedThread(tree,unique->nextFree); +#else + memListTrav = unique->memoryList; + sentry = NULL; + while (memListTrav != NULL) { + ptruint offset; + nxtNode = (DdNodePtr *)memListTrav[0]; + offset = (ptruint) memListTrav & (sizeof(DdNode) - 1); + memListTrav += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); + downTrav = (DdNode *)memListTrav; + k = 0; + do { + if (downTrav[k].ref == 0) { + if (sentry == NULL) { + unique->nextFree = sentry = &downTrav[k]; + } else { + /* First hook sentry->next to the dead node and then + ** reassign sentry to the dead node. */ + sentry = (sentry->next = &downTrav[k]); + } + } + } while (++k < DD_MEM_CHUNK); + memListTrav = nxtNode; + } + sentry->next = NULL; +#endif #endif unique->GCTime += util_cpu_time() - localTime; hook = unique->postGCHook; while (hook != NULL) { - int res = (hook->f)(unique,"ZDD",NULL); - if (res == 0) return(0); - hook = hook->next; + int res = (hook->f)(unique,"DD",NULL); + if (res == 0) return(0); + hook = hook->next; } #ifdef DD_VERBOSE (void) fprintf(unique->err," done\n"); #endif - return(totalDeleted); + return(totalDeleted+totalDeletedZ); -} /* end of cuddGarbageCollectZdd */ +} /* end of cuddGarbageCollect */ /**Function******************************************************************** @@ -1009,10 +1035,10 @@ cuddZddGetNode( DdNode * T, DdNode * E) { - DdNode *node; + DdNode *node; if (T == DD_ZERO(zdd)) - return(E); + return(E); node = cuddUniqueInterZdd(zdd, id, T, E); return(node); @@ -1042,26 +1068,26 @@ cuddZddGetNodeIVO( DdNode * g, DdNode * h) { - DdNode *f, *r, *t; - DdNode *zdd_one = DD_ONE(dd); - DdNode *zdd_zero = DD_ZERO(dd); + DdNode *f, *r, *t; + DdNode *zdd_one = DD_ONE(dd); + DdNode *zdd_zero = DD_ZERO(dd); f = cuddUniqueInterZdd(dd, index, zdd_one, zdd_zero); if (f == NULL) { - return(NULL); + return(NULL); } cuddRef(f); t = cuddZddProduct(dd, f, g); if (t == NULL) { - Cudd_RecursiveDerefZdd(dd, f); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f); + return(NULL); } cuddRef(t); Cudd_RecursiveDerefZdd(dd, f); r = cuddZddUnion(dd, t, h); if (r == NULL) { - Cudd_RecursiveDerefZdd(dd, t); - return(NULL); + Cudd_RecursiveDerefZdd(dd, t); + return(NULL); } cuddRef(r); Cudd_RecursiveDerefZdd(dd, t); @@ -1110,7 +1136,7 @@ cuddUniqueInter( #endif if (index >= unique->size) { - if (!ddResizeTable(unique,index)) return(NULL); + if (!ddResizeTable(unique,index)) return(NULL); } level = unique->perm[index]; @@ -1127,116 +1153,115 @@ cuddUniqueInter( looking = *previousP; while (T < cuddT(looking)) { - previousP = &(looking->next); - looking = *previousP; + previousP = &(looking->next); + looking = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif } while (T == cuddT(looking) && E < cuddE(looking)) { - previousP = &(looking->next); - looking = *previousP; + previousP = &(looking->next); + looking = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif } if (T == cuddT(looking) && E == cuddE(looking)) { - if (looking->ref == 0) { - cuddReclaim(unique,looking); - } - return(looking); + if (looking->ref == 0) { + cuddReclaim(unique,looking); + } + return(looking); } /* countDead is 0 if deads should be counted and ~0 if they should not. */ if (unique->autoDyn && unique->keys - (unique->dead & unique->countDead) >= unique->nextDyn) { #ifdef DD_DEBUG - retval = Cudd_DebugCheck(unique); - if (retval != 0) return(NULL); - retval = Cudd_CheckKeys(unique); - if (retval != 0) return(NULL); + retval = Cudd_DebugCheck(unique); + if (retval != 0) return(NULL); + retval = Cudd_CheckKeys(unique); + if (retval != 0) return(NULL); #endif - retval = Cudd_ReduceHeap(unique,unique->autoMethod,10); /* 10 = whatever */ - if (retval == 0) unique->reordered = 2; + retval = Cudd_ReduceHeap(unique,unique->autoMethod,10); /* 10 = whatever */ + if (retval == 0) unique->reordered = 2; #ifdef DD_DEBUG - retval = Cudd_DebugCheck(unique); - if (retval != 0) unique->reordered = 2; - retval = Cudd_CheckKeys(unique); - if (retval != 0) unique->reordered = 2; + retval = Cudd_DebugCheck(unique); + if (retval != 0) unique->reordered = 2; + retval = Cudd_CheckKeys(unique); + if (retval != 0) unique->reordered = 2; #endif - return(NULL); + return(NULL); } if (subtable->keys > subtable->maxKeys) { if (unique->gcEnabled && - ((unique->dead > unique->minDead) || - ((unique->dead > unique->minDead / 2) && - (subtable->dead > subtable->keys * 0.95)))) { /* too many dead */ - (void) cuddGarbageCollect(unique,1); - } else { - cuddRehash(unique,(int)level); - } - /* Update pointer to insertion point. In the case of rehashing, - ** the slot may have changed. In the case of garbage collection, - ** the predecessor may have been dead. */ - pos = ddHash(T, E, subtable->shift); - nodelist = subtable->nodelist; - previousP = &(nodelist[pos]); - looking = *previousP; - - while (T < cuddT(looking)) { - previousP = &(looking->next); + ((unique->dead > unique->minDead) || + ((unique->dead > unique->minDead / 2) && + (subtable->dead > subtable->keys * 0.95)))) { /* too many dead */ + (void) cuddGarbageCollect(unique,1); + } else { + cuddRehash(unique,(int)level); + } + /* Update pointer to insertion point. In the case of rehashing, + ** the slot may have changed. In the case of garbage collection, + ** the predecessor may have been dead. */ + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); looking = *previousP; + + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif - } - while (T == cuddT(looking) && E < cuddE(looking)) { - previousP = &(looking->next); - looking = *previousP; + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif - } + } } gcNumber = unique->garbageCollections; looking = cuddAllocNode(unique); if (looking == NULL) { - return(NULL); + return(NULL); } unique->keys++; subtable->keys++; if (gcNumber != unique->garbageCollections) { - DdNode *looking2; - pos = ddHash(T, E, subtable->shift); - nodelist = subtable->nodelist; - previousP = &(nodelist[pos]); - looking2 = *previousP; - - while (T < cuddT(looking2)) { - previousP = &(looking2->next); + DdNode *looking2; + pos = ddHash(T, E, subtable->shift); + nodelist = subtable->nodelist; + previousP = &(nodelist[pos]); looking2 = *previousP; + + while (T < cuddT(looking2)) { + previousP = &(looking2->next); + looking2 = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif - } - while (T == cuddT(looking2) && E < cuddE(looking2)) { - previousP = &(looking2->next); - looking2 = *previousP; + } + while (T == cuddT(looking2) && E < cuddE(looking2)) { + previousP = &(looking2->next); + looking2 = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif + } } - } - looking->ref = 0; looking->index = index; cuddT(looking) = T; cuddE(looking) = E; looking->next = *previousP; *previousP = looking; - cuddSatInc(T->ref); /* we know T is a regular pointer */ + cuddSatInc(T->ref); /* we know T is a regular pointer */ cuddRef(E); #ifdef DD_DEBUG @@ -1275,9 +1300,9 @@ cuddUniqueInterIVO( DdNode *v; v = cuddUniqueInter(unique, index, DD_ONE(unique), - Cudd_Not(DD_ONE(unique))); + Cudd_Not(DD_ONE(unique))); if (v == NULL) - return(NULL); + return(NULL); cuddRef(v); result = cuddBddIteRecur(unique, v, T, E); Cudd_RecursiveDeref(unique, v); @@ -1322,7 +1347,7 @@ cuddUniqueInterZdd( #endif if (index >= unique->sizeZ) { - if (!cuddResizeTableZdd(unique,index)) return(NULL); + if (!cuddResizeTableZdd(unique,index)) return(NULL); } level = unique->permZ[index]; @@ -1335,11 +1360,11 @@ cuddUniqueInterZdd( if (subtable->keys > subtable->maxKeys) { if (unique->gcEnabled && ((unique->deadZ > unique->minDead) || - (10 * subtable->dead > 9 * subtable->keys))) { /* too many dead */ - (void) cuddGarbageCollectZdd(unique,1); - } else { - ddRehashZdd(unique,(int)level); - } + (10 * subtable->dead > 9 * subtable->keys))) { /* too many dead */ + (void) cuddGarbageCollect(unique,1); + } else { + ddRehashZdd(unique,(int)level); + } } pos = ddHash(T, E, subtable->shift); @@ -1348,14 +1373,14 @@ cuddUniqueInterZdd( while (looking != NULL) { if (cuddT(looking) == T && cuddE(looking) == E) { - if (looking->ref == 0) { - cuddReclaimZdd(unique,looking); + if (looking->ref == 0) { + cuddReclaimZdd(unique,looking); + } + return(looking); } - return(looking); - } - looking = looking->next; + looking = looking->next; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif } @@ -1363,20 +1388,20 @@ cuddUniqueInterZdd( if (unique->autoDynZ && unique->keysZ - (unique->deadZ & unique->countDead) >= unique->nextDyn) { #ifdef DD_DEBUG - retval = Cudd_DebugCheck(unique); - if (retval != 0) return(NULL); - retval = Cudd_CheckKeys(unique); - if (retval != 0) return(NULL); + retval = Cudd_DebugCheck(unique); + if (retval != 0) return(NULL); + retval = Cudd_CheckKeys(unique); + if (retval != 0) return(NULL); #endif - retval = Cudd_zddReduceHeap(unique,unique->autoMethodZ,10); /* 10 = whatever */ - if (retval == 0) unique->reordered = 2; + retval = Cudd_zddReduceHeap(unique,unique->autoMethodZ,10); /* 10 = whatever */ + if (retval == 0) unique->reordered = 2; #ifdef DD_DEBUG - retval = Cudd_DebugCheck(unique); - if (retval != 0) unique->reordered = 2; - retval = Cudd_CheckKeys(unique); - if (retval != 0) unique->reordered = 2; + retval = Cudd_DebugCheck(unique); + if (retval != 0) unique->reordered = 2; + retval = Cudd_CheckKeys(unique); + if (retval != 0) unique->reordered = 2; #endif - return(NULL); + return(NULL); } unique->keysZ++; @@ -1384,7 +1409,6 @@ cuddUniqueInterZdd( looking = cuddAllocNode(unique); if (looking == NULL) return(NULL); - looking->ref = 0; looking->index = index; cuddT(looking) = T; cuddE(looking) = E; @@ -1427,17 +1451,17 @@ cuddUniqueConst( if (unique->constants.keys > unique->constants.maxKeys) { if (unique->gcEnabled && ((unique->dead > unique->minDead) || - (10 * unique->constants.dead > 9 * unique->constants.keys))) { /* too many dead */ - (void) cuddGarbageCollect(unique,1); - } else { - cuddRehash(unique,CUDD_CONST_INDEX); - } + (10 * unique->constants.dead > 9 * unique->constants.keys))) { /* too many dead */ + (void) cuddGarbageCollect(unique,1); + } else { + cuddRehash(unique,CUDD_CONST_INDEX); + } } cuddAdjust(value); /* for the case of crippled infinities */ if (ddAbs(value) < unique->epsilon) { - value = 0.0; + value = 0.0; } split.value = value; @@ -1452,15 +1476,15 @@ cuddUniqueConst( */ while (looking != NULL) { if (looking->type.value == value || - ddEqualVal(looking->type.value,value,unique->epsilon)) { - if (looking->ref == 0) { - cuddReclaim(unique,looking); + ddEqualVal(looking->type.value,value,unique->epsilon)) { + if (looking->ref == 0) { + cuddReclaim(unique,looking); + } + return(looking); } - return(looking); - } - looking = looking->next; + looking = looking->next; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif } @@ -1469,7 +1493,6 @@ cuddUniqueConst( looking = cuddAllocNode(unique); if (looking == NULL) return(NULL); - looking->ref = 0; looking->index = CUDD_CONST_INDEX; looking->type.value = value; looking->next = nodelist[pos]; @@ -1504,144 +1527,143 @@ cuddRehash( DdNode *node, *next; DdNode *sentinel = &(unique->sentinel); hack split; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; if (unique->gcFrac == DD_GC_FRAC_HI && unique->slots > unique->looseUpTo) { - unique->gcFrac = DD_GC_FRAC_LO; - unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); + unique->gcFrac = DD_GC_FRAC_LO; + unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); #ifdef DD_VERBOSE - (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_LO); - (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_LO); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); #endif } if (unique->gcFrac != DD_GC_FRAC_MIN && unique->memused > unique->maxmem) { - unique->gcFrac = DD_GC_FRAC_MIN; - unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots); + unique->gcFrac = DD_GC_FRAC_MIN; + unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots); #ifdef DD_VERBOSE - (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_MIN); - (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_MIN); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); #endif - cuddShrinkDeathRow(unique); - if (cuddGarbageCollect(unique,1) > 0) return; + cuddShrinkDeathRow(unique); + if (cuddGarbageCollect(unique,1) > 0) return; } if (i != CUDD_CONST_INDEX) { - oldslots = unique->subtables[i].slots; - oldshift = unique->subtables[i].shift; - oldnodelist = unique->subtables[i].nodelist; - - /* Compute the new size of the subtable. */ - slots = oldslots << 1; - shift = oldshift - 1; + oldslots = unique->subtables[i].slots; + oldshift = unique->subtables[i].shift; + oldnodelist = unique->subtables[i].nodelist; - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - nodelist = ABC_ALLOC(DdNodePtr, slots); - MMoutOfMemory = saveHandler; - if (nodelist == NULL) { - (void) fprintf(unique->err, - "Unable to resize subtable %d for lack of memory\n", - i); - /* Prevent frequent resizing attempts. */ - (void) cuddGarbageCollect(unique,1); - if (unique->stash != NULL) { - ABC_FREE(unique->stash); - unique->stash = NULL; - /* Inhibit resizing of tables. */ - cuddSlowTableGrowth(unique); - } - return; - } - unique->subtables[i].nodelist = nodelist; - unique->subtables[i].slots = slots; - unique->subtables[i].shift = shift; - unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + /* Compute the new size of the subtable. */ + slots = oldslots << 1; + shift = oldshift - 1; - /* Move the nodes from the old table to the new table. - ** This code depends on the type of hash function. - ** It assumes that the effect of doubling the size of the table - ** is to retain one more bit of the 32-bit hash value. - ** The additional bit is the LSB. */ - for (j = 0; (unsigned) j < oldslots; j++) { - DdNodePtr *evenP, *oddP; - node = oldnodelist[j]; - evenP = &(nodelist[j<<1]); - oddP = &(nodelist[(j<<1)+1]); - while (node != sentinel) { - next = node->next; - pos = ddHash(cuddT(node), cuddE(node), shift); - if (pos & 1) { - *oddP = node; - oddP = &(node->next); - } else { - *evenP = node; - evenP = &(node->next); + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ABC_ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize subtable %d for lack of memory\n", + i); + /* Prevent frequent resizing attempts. */ + (void) cuddGarbageCollect(unique,1); + if (unique->stash != NULL) { + ABC_FREE(unique->stash); + unique->stash = NULL; + /* Inhibit resizing of tables. */ + cuddSlowTableGrowth(unique); + } + return; } - node = next; + unique->subtables[i].nodelist = nodelist; + unique->subtables[i].slots = slots; + unique->subtables[i].shift = shift; + unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + + /* Move the nodes from the old table to the new table. + ** This code depends on the type of hash function. + ** It assumes that the effect of doubling the size of the table + ** is to retain one more bit of the 32-bit hash value. + ** The additional bit is the LSB. */ + for (j = 0; (unsigned) j < oldslots; j++) { + DdNodePtr *evenP, *oddP; + node = oldnodelist[j]; + evenP = &(nodelist[j<<1]); + oddP = &(nodelist[(j<<1)+1]); + while (node != sentinel) { + next = node->next; + pos = ddHash(cuddT(node), cuddE(node), shift); + if (pos & 1) { + *oddP = node; + oddP = &(node->next); + } else { + *evenP = node; + evenP = &(node->next); + } + node = next; + } + *evenP = *oddP = sentinel; } - *evenP = *oddP = sentinel; - } - ABC_FREE(oldnodelist); + ABC_FREE(oldnodelist); #ifdef DD_VERBOSE - (void) fprintf(unique->err, - "rehashing layer %d: keys %d dead %d new size %d\n", - i, unique->subtables[i].keys, - unique->subtables[i].dead, slots); + (void) fprintf(unique->err, + "rehashing layer %d: keys %d dead %d new size %d\n", + i, unique->subtables[i].keys, + unique->subtables[i].dead, slots); #endif } else { - oldslots = unique->constants.slots; - oldshift = unique->constants.shift; - oldnodelist = unique->constants.nodelist; - - /* The constant subtable is never subjected to reordering. - ** Therefore, when it is resized, it is because it has just - ** reached the maximum load. We can safely just double the size, - ** with no need for the loop we use for the other tables. - */ - slots = oldslots << 1; - shift = oldshift - 1; - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - nodelist = ABC_ALLOC(DdNodePtr, slots); - MMoutOfMemory = saveHandler; - if (nodelist == NULL) { - int j; - (void) fprintf(unique->err, - "Unable to resize constant subtable for lack of memory\n"); - (void) cuddGarbageCollect(unique,1); - for (j = 0; j < unique->size; j++) { - unique->subtables[j].maxKeys <<= 1; + oldslots = unique->constants.slots; + oldshift = unique->constants.shift; + oldnodelist = unique->constants.nodelist; + + /* The constant subtable is never subjected to reordering. + ** Therefore, when it is resized, it is because it has just + ** reached the maximum load. We can safely just double the size, + ** with no need for the loop we use for the other tables. + */ + slots = oldslots << 1; + shift = oldshift - 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ABC_ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + (void) fprintf(unique->err, + "Unable to resize constant subtable for lack of memory\n"); + (void) cuddGarbageCollect(unique,1); + for (j = 0; j < unique->size; j++) { + unique->subtables[j].maxKeys <<= 1; + } + unique->constants.maxKeys <<= 1; + return; } - unique->constants.maxKeys <<= 1; - return; - } - unique->constants.slots = slots; - unique->constants.shift = shift; - unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; - unique->constants.nodelist = nodelist; - for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = NULL; - } - for (j = 0; (unsigned) j < oldslots; j++) { - node = oldnodelist[j]; - while (node != NULL) { - next = node->next; - split.value = cuddV(node); - pos = ddHash(split.bits[0], split.bits[1], shift); - node->next = nodelist[pos]; - nodelist[pos] = node; - node = next; + unique->constants.slots = slots; + unique->constants.shift = shift; + unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + unique->constants.nodelist = nodelist; + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; } - } - ABC_FREE(oldnodelist); + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + split.value = cuddV(node); + pos = ddHash(split.bits[0], split.bits[1], shift); + node->next = nodelist[pos]; + nodelist[pos] = node; + node = next; + } + } + ABC_FREE(oldnodelist); #ifdef DD_VERBOSE - (void) fprintf(unique->err, - "rehashing constants: keys %d dead %d new size %d\n", - unique->constants.keys,unique->constants.dead,slots); + (void) fprintf(unique->err, + "rehashing constants: keys %d dead %d new size %d\n", + unique->constants.keys,unique->constants.dead,slots); #endif } @@ -1676,8 +1698,8 @@ cuddShrinkSubtable( DdNode *node, *next; DdNode *sentinel = &(unique->sentinel); unsigned int slots, oldslots; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; oldnodelist = unique->subtables[i].nodelist; oldslots = unique->subtables[i].slots; @@ -1687,7 +1709,7 @@ cuddShrinkSubtable( nodelist = ABC_ALLOC(DdNodePtr, slots); MMoutOfMemory = saveHandler; if (nodelist == NULL) { - return; + return; } unique->subtables[i].nodelist = nodelist; unique->subtables[i].slots = slots; @@ -1695,43 +1717,43 @@ cuddShrinkSubtable( unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; #ifdef DD_VERBOSE (void) fprintf(unique->err, - "shrunk layer %d (%d keys) from %d to %d slots\n", - i, unique->subtables[i].keys, oldslots, slots); + "shrunk layer %d (%d keys) from %d to %d slots\n", + i, unique->subtables[i].keys, oldslots, slots); #endif for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = sentinel; + nodelist[j] = sentinel; } shift = unique->subtables[i].shift; for (j = 0; (unsigned) j < oldslots; j++) { - node = oldnodelist[j]; - while (node != sentinel) { - DdNode *looking, *T, *E; - DdNodePtr *previousP; - next = node->next; - posn = ddHash(cuddT(node), cuddE(node), shift); - previousP = &(nodelist[posn]); - looking = *previousP; - T = cuddT(node); - E = cuddE(node); - while (T < cuddT(looking)) { - previousP = &(looking->next); - looking = *previousP; + node = oldnodelist[j]; + while (node != sentinel) { + DdNode *looking, *T, *E; + DdNodePtr *previousP; + next = node->next; + posn = ddHash(cuddT(node), cuddE(node), shift); + previousP = &(nodelist[posn]); + looking = *previousP; + T = cuddT(node); + E = cuddE(node); + while (T < cuddT(looking)) { + previousP = &(looking->next); + looking = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif - } - while (T == cuddT(looking) && E < cuddE(looking)) { - previousP = &(looking->next); - looking = *previousP; + } + while (T == cuddT(looking) && E < cuddE(looking)) { + previousP = &(looking->next); + looking = *previousP; #ifdef DD_UNIQUE_PROFILE - unique->uniqueLinks++; + unique->uniqueLinks++; #endif + } + node->next = *previousP; + *previousP = node; + node = next; } - node->next = *previousP; - *previousP = node; - node = next; - } } ABC_FREE(oldnodelist); @@ -1739,8 +1761,8 @@ cuddShrinkSubtable( unique->slots += slots - oldslots; unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); unique->cacheSlack = (int) - ddMin(unique->maxCacheHard,DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) - - 2 * (int) unique->cacheSlots; + ddMin(unique->maxCacheHard,DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) + - 2 * (int) unique->cacheSlots; } /* end of cuddShrinkSubtable */ @@ -1771,8 +1793,7 @@ cuddInsertSubtables( int oldsize,newsize; int i,j,index,reorderSave; unsigned int numSlots = unique->initSlots; - int *newperm, *newinvperm; - int *newmap = NULL; // Suppress "might be used uninitialized" + int *newperm, *newinvperm, *newmap; DdNode *one, *zero; #ifdef DD_DEBUG @@ -1782,210 +1803,210 @@ cuddInsertSubtables( oldsize = unique->size; /* Easy case: there is still room in the current table. */ if (oldsize + n <= unique->maxSize) { - /* Shift the tables at and below level. */ - for (i = oldsize - 1; i >= level; i--) { - unique->subtables[i+n].slots = unique->subtables[i].slots; - unique->subtables[i+n].shift = unique->subtables[i].shift; - unique->subtables[i+n].keys = unique->subtables[i].keys; - unique->subtables[i+n].maxKeys = unique->subtables[i].maxKeys; - unique->subtables[i+n].dead = unique->subtables[i].dead; - unique->subtables[i+n].nodelist = unique->subtables[i].nodelist; - unique->subtables[i+n].bindVar = unique->subtables[i].bindVar; - unique->subtables[i+n].varType = unique->subtables[i].varType; - unique->subtables[i+n].pairIndex = unique->subtables[i].pairIndex; - unique->subtables[i+n].varHandled = unique->subtables[i].varHandled; - unique->subtables[i+n].varToBeGrouped = - unique->subtables[i].varToBeGrouped; - - index = unique->invperm[i]; - unique->invperm[i+n] = index; - unique->perm[index] += n; - } - /* Create new subtables. */ - for (i = 0; i < n; i++) { - unique->subtables[level+i].slots = numSlots; - unique->subtables[level+i].shift = sizeof(int) * 8 - - cuddComputeFloorLog2(numSlots); - unique->subtables[level+i].keys = 0; - unique->subtables[level+i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; - unique->subtables[level+i].dead = 0; - unique->subtables[level+i].bindVar = 0; - unique->subtables[level+i].varType = CUDD_VAR_PRIMARY_INPUT; - unique->subtables[level+i].pairIndex = 0; - unique->subtables[level+i].varHandled = 0; - unique->subtables[level+i].varToBeGrouped = CUDD_LAZY_NONE; - - unique->perm[oldsize+i] = level + i; - unique->invperm[level+i] = oldsize + i; - newnodelist = unique->subtables[level+i].nodelist = - ABC_ALLOC(DdNodePtr, numSlots); - if (newnodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + /* Shift the tables at and below level. */ + for (i = oldsize - 1; i >= level; i--) { + unique->subtables[i+n].slots = unique->subtables[i].slots; + unique->subtables[i+n].shift = unique->subtables[i].shift; + unique->subtables[i+n].keys = unique->subtables[i].keys; + unique->subtables[i+n].maxKeys = unique->subtables[i].maxKeys; + unique->subtables[i+n].dead = unique->subtables[i].dead; + unique->subtables[i+n].nodelist = unique->subtables[i].nodelist; + unique->subtables[i+n].bindVar = unique->subtables[i].bindVar; + unique->subtables[i+n].varType = unique->subtables[i].varType; + unique->subtables[i+n].pairIndex = unique->subtables[i].pairIndex; + unique->subtables[i+n].varHandled = unique->subtables[i].varHandled; + unique->subtables[i+n].varToBeGrouped = + unique->subtables[i].varToBeGrouped; + + index = unique->invperm[i]; + unique->invperm[i+n] = index; + unique->perm[index] += n; } - for (j = 0; j < (int)numSlots; j++) { - newnodelist[j] = sentinel; - } - } - if (unique->map != NULL) { + /* Create new subtables. */ for (i = 0; i < n; i++) { - unique->map[oldsize+i] = oldsize + i; + unique->subtables[level+i].slots = numSlots; + unique->subtables[level+i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtables[level+i].keys = 0; + unique->subtables[level+i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[level+i].dead = 0; + unique->subtables[level+i].bindVar = 0; + unique->subtables[level+i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[level+i].pairIndex = 0; + unique->subtables[level+i].varHandled = 0; + unique->subtables[level+i].varToBeGrouped = CUDD_LAZY_NONE; + + unique->perm[oldsize+i] = level + i; + unique->invperm[level+i] = oldsize + i; + newnodelist = unique->subtables[level+i].nodelist = + ABC_ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = 0; i < n; i++) { + unique->map[oldsize+i] = oldsize + i; + } } - } } else { - /* The current table is too small: we need to allocate a new, - ** larger one; move all old subtables, and initialize the new - ** subtables. - */ - newsize = oldsize + n + DD_DEFAULT_RESIZE; + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables. + */ + newsize = oldsize + n + DD_DEFAULT_RESIZE; #ifdef DD_VERBOSE - (void) fprintf(unique->err, - "Increasing the table size from %d to %d\n", - unique->maxSize, newsize); + (void) fprintf(unique->err, + "Increasing the table size from %d to %d\n", + unique->maxSize, newsize); #endif - /* Allocate memory for new arrays (except nodelists). */ - newsubtables = ABC_ALLOC(DdSubtable,newsize); - if (newsubtables == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - newvars = ABC_ALLOC(DdNodePtr,newsize); - if (newvars == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(newsubtables); - return(0); - } - newperm = ABC_ALLOC(int,newsize); - if (newperm == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(newsubtables); - ABC_FREE(newvars); - return(0); - } - newinvperm = ABC_ALLOC(int,newsize); - if (newinvperm == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(newsubtables); - ABC_FREE(newvars); - ABC_FREE(newperm); - return(0); - } - if (unique->map != NULL) { - newmap = ABC_ALLOC(int,newsize); - if (newmap == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(newsubtables); - ABC_FREE(newvars); - ABC_FREE(newperm); - ABC_FREE(newinvperm); - return(0); + /* Allocate memory for new arrays (except nodelists). */ + newsubtables = ABC_ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - unique->memused += (newsize - unique->maxSize) * sizeof(int); - } - unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * - sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); - /* Copy levels before insertion points from old tables. */ - for (i = 0; i < level; i++) { - newsubtables[i].slots = unique->subtables[i].slots; - newsubtables[i].shift = unique->subtables[i].shift; - newsubtables[i].keys = unique->subtables[i].keys; - newsubtables[i].maxKeys = unique->subtables[i].maxKeys; - newsubtables[i].dead = unique->subtables[i].dead; - newsubtables[i].nodelist = unique->subtables[i].nodelist; - newsubtables[i].bindVar = unique->subtables[i].bindVar; - newsubtables[i].varType = unique->subtables[i].varType; - newsubtables[i].pairIndex = unique->subtables[i].pairIndex; - newsubtables[i].varHandled = unique->subtables[i].varHandled; - newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; - - newvars[i] = unique->vars[i]; - newperm[i] = unique->perm[i]; - newinvperm[i] = unique->invperm[i]; - } - /* Finish initializing permutation for new table to old one. */ - for (i = level; i < oldsize; i++) { - newperm[i] = unique->perm[i]; - } - /* Initialize new levels. */ - for (i = level; i < level + n; i++) { - newsubtables[i].slots = numSlots; - newsubtables[i].shift = sizeof(int) * 8 - - cuddComputeFloorLog2(numSlots); - newsubtables[i].keys = 0; - newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; - newsubtables[i].dead = 0; - newsubtables[i].bindVar = 0; - newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; - newsubtables[i].pairIndex = 0; - newsubtables[i].varHandled = 0; - newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; - - newperm[oldsize + i - level] = i; - newinvperm[i] = oldsize + i - level; - newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots); - if (newnodelist == NULL) { - /* We are going to leak some memory. We should clean up. */ - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + newvars = ABC_ALLOC(DdNodePtr,newsize); + if (newvars == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(newsubtables); + return(0); } - for (j = 0; j < (int)numSlots; j++) { - newnodelist[j] = sentinel; - } - } - /* Copy the old tables for levels past the insertion point. */ - for (i = level; i < oldsize; i++) { - newsubtables[i+n].slots = unique->subtables[i].slots; - newsubtables[i+n].shift = unique->subtables[i].shift; - newsubtables[i+n].keys = unique->subtables[i].keys; - newsubtables[i+n].maxKeys = unique->subtables[i].maxKeys; - newsubtables[i+n].dead = unique->subtables[i].dead; - newsubtables[i+n].nodelist = unique->subtables[i].nodelist; - newsubtables[i+n].bindVar = unique->subtables[i].bindVar; - newsubtables[i+n].varType = unique->subtables[i].varType; - newsubtables[i+n].pairIndex = unique->subtables[i].pairIndex; - newsubtables[i+n].varHandled = unique->subtables[i].varHandled; - newsubtables[i+n].varToBeGrouped = - unique->subtables[i].varToBeGrouped; - - newvars[i] = unique->vars[i]; - index = unique->invperm[i]; - newinvperm[i+n] = index; - newperm[index] += n; - } - /* Update the map. */ - if (unique->map != NULL) { - for (i = 0; i < oldsize; i++) { - newmap[i] = unique->map[i]; + newperm = ABC_ALLOC(int,newsize); + if (newperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(newsubtables); + ABC_FREE(newvars); + return(0); } - for (i = oldsize; i < oldsize + n; i++) { - newmap[i] = i; + newinvperm = ABC_ALLOC(int,newsize); + if (newinvperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(newsubtables); + ABC_FREE(newvars); + ABC_FREE(newperm); + return(0); } - ABC_FREE(unique->map); - unique->map = newmap; - } - /* Install the new tables and free the old ones. */ - ABC_FREE(unique->subtables); - unique->subtables = newsubtables; - unique->maxSize = newsize; - ABC_FREE(unique->vars); - unique->vars = newvars; - ABC_FREE(unique->perm); - unique->perm = newperm; - ABC_FREE(unique->invperm); - unique->invperm = newinvperm; - /* Update the stack for iterative procedures. */ - if (newsize > unique->maxSizeZ) { - ABC_FREE(unique->stack); - unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1); - if (unique->stack == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + if (unique->map != NULL) { + newmap = ABC_ALLOC(int,newsize); + if (newmap == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(newsubtables); + ABC_FREE(newvars); + ABC_FREE(newperm); + ABC_FREE(newinvperm); + return(0); + } + unique->memused += (newsize - unique->maxSize) * sizeof(int); + } + unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + /* Copy levels before insertion points from old tables. */ + for (i = 0; i < level; i++) { + newsubtables[i].slots = unique->subtables[i].slots; + newsubtables[i].shift = unique->subtables[i].shift; + newsubtables[i].keys = unique->subtables[i].keys; + newsubtables[i].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i].dead = unique->subtables[i].dead; + newsubtables[i].nodelist = unique->subtables[i].nodelist; + newsubtables[i].bindVar = unique->subtables[i].bindVar; + newsubtables[i].varType = unique->subtables[i].varType; + newsubtables[i].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i].varHandled = unique->subtables[i].varHandled; + newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + newperm[i] = unique->perm[i]; + newinvperm[i] = unique->invperm[i]; + } + /* Finish initializing permutation for new table to old one. */ + for (i = level; i < oldsize; i++) { + newperm[i] = unique->perm[i]; + } + /* Initialize new levels. */ + for (i = level; i < level + n; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newsubtables[i].bindVar = 0; + newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + newsubtables[i].pairIndex = 0; + newsubtables[i].varHandled = 0; + newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + newperm[oldsize + i - level] = i; + newinvperm[i] = oldsize + i - level; + newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + /* We are going to leak some memory. We should clean up. */ + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + /* Copy the old tables for levels past the insertion point. */ + for (i = level; i < oldsize; i++) { + newsubtables[i+n].slots = unique->subtables[i].slots; + newsubtables[i+n].shift = unique->subtables[i].shift; + newsubtables[i+n].keys = unique->subtables[i].keys; + newsubtables[i+n].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i+n].dead = unique->subtables[i].dead; + newsubtables[i+n].nodelist = unique->subtables[i].nodelist; + newsubtables[i+n].bindVar = unique->subtables[i].bindVar; + newsubtables[i+n].varType = unique->subtables[i].varType; + newsubtables[i+n].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i+n].varHandled = unique->subtables[i].varHandled; + newsubtables[i+n].varToBeGrouped = + unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + index = unique->invperm[i]; + newinvperm[i+n] = index; + newperm[index] += n; + } + /* Update the map. */ + if (unique->map != NULL) { + for (i = 0; i < oldsize; i++) { + newmap[i] = unique->map[i]; + } + for (i = oldsize; i < oldsize + n; i++) { + newmap[i] = i; + } + ABC_FREE(unique->map); + unique->map = newmap; + } + /* Install the new tables and free the old ones. */ + ABC_FREE(unique->subtables); + unique->subtables = newsubtables; + unique->maxSize = newsize; + ABC_FREE(unique->vars); + unique->vars = newvars; + ABC_FREE(unique->perm); + unique->perm = newperm; + ABC_FREE(unique->invperm); + unique->invperm = newinvperm; + /* Update the stack for iterative procedures. */ + if (newsize > unique->maxSizeZ) { + ABC_FREE(unique->stack); + unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); } - unique->stack[0] = NULL; /* to suppress harmless UMR */ - unique->memused += - (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) - * sizeof(DdNode *); - } } /* Update manager parameters to account for the new subtables. */ unique->slots += n * numSlots; @@ -2002,53 +2023,53 @@ cuddInsertSubtables( reorderSave = unique->autoDyn; unique->autoDyn = 0; for (i = oldsize; i < oldsize + n; i++) { - unique->vars[i] = cuddUniqueInter(unique,i,one,zero); - if (unique->vars[i] == NULL) { - unique->autoDyn = reorderSave; - /* Shift everything back so table remains coherent. */ - for (j = oldsize; j < i; j++) { - Cudd_IterDerefBdd(unique,unique->vars[j]); - cuddDeallocNode(unique,unique->vars[j]); - unique->vars[j] = NULL; - } - for (j = level; j < oldsize; j++) { - unique->subtables[j].slots = unique->subtables[j+n].slots; - unique->subtables[j].slots = unique->subtables[j+n].slots; - unique->subtables[j].shift = unique->subtables[j+n].shift; - unique->subtables[j].keys = unique->subtables[j+n].keys; - unique->subtables[j].maxKeys = - unique->subtables[j+n].maxKeys; - unique->subtables[j].dead = unique->subtables[j+n].dead; - ABC_FREE(unique->subtables[j].nodelist); - unique->subtables[j].nodelist = - unique->subtables[j+n].nodelist; - unique->subtables[j+n].nodelist = NULL; - unique->subtables[j].bindVar = - unique->subtables[j+n].bindVar; - unique->subtables[j].varType = - unique->subtables[j+n].varType; - unique->subtables[j].pairIndex = - unique->subtables[j+n].pairIndex; - unique->subtables[j].varHandled = - unique->subtables[j+n].varHandled; - unique->subtables[j].varToBeGrouped = - unique->subtables[j+n].varToBeGrouped; - index = unique->invperm[j+n]; - unique->invperm[j] = index; - unique->perm[index] -= n; - } - unique->size = oldsize; - unique->slots -= n * numSlots; - ddFixLimits(unique); - (void) Cudd_DebugCheck(unique); - return(0); - } - cuddRef(unique->vars[i]); + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) { + unique->autoDyn = reorderSave; + /* Shift everything back so table remains coherent. */ + for (j = oldsize; j < i; j++) { + Cudd_IterDerefBdd(unique,unique->vars[j]); + cuddDeallocNode(unique,unique->vars[j]); + unique->vars[j] = NULL; + } + for (j = level; j < oldsize; j++) { + unique->subtables[j].slots = unique->subtables[j+n].slots; + unique->subtables[j].slots = unique->subtables[j+n].slots; + unique->subtables[j].shift = unique->subtables[j+n].shift; + unique->subtables[j].keys = unique->subtables[j+n].keys; + unique->subtables[j].maxKeys = + unique->subtables[j+n].maxKeys; + unique->subtables[j].dead = unique->subtables[j+n].dead; + ABC_FREE(unique->subtables[j].nodelist); + unique->subtables[j].nodelist = + unique->subtables[j+n].nodelist; + unique->subtables[j+n].nodelist = NULL; + unique->subtables[j].bindVar = + unique->subtables[j+n].bindVar; + unique->subtables[j].varType = + unique->subtables[j+n].varType; + unique->subtables[j].pairIndex = + unique->subtables[j+n].pairIndex; + unique->subtables[j].varHandled = + unique->subtables[j+n].varHandled; + unique->subtables[j].varToBeGrouped = + unique->subtables[j+n].varToBeGrouped; + index = unique->invperm[j+n]; + unique->invperm[j] = index; + unique->perm[index] -= n; + } + unique->size = oldsize; + unique->slots -= n * numSlots; + ddFixLimits(unique); + (void) Cudd_DebugCheck(unique); + return(0); + } + cuddRef(unique->vars[i]); } if (unique->tree != NULL) { - unique->tree->size += n; - unique->tree->index = unique->invperm[0]; - ddPatchTree(unique,unique->tree); + unique->tree->size += n; + unique->tree->index = unique->invperm[0]; + ddPatchTree(unique,unique->tree); } unique->autoDyn = reorderSave; @@ -2103,26 +2124,26 @@ cuddDestroySubtables( */ lowestLevel = unique->size; for (index = firstIndex; index < lastIndex; index++) { - level = unique->perm[index]; - if (level < lowestLevel) lowestLevel = level; - nodelist = subtables[level].nodelist; - if (subtables[level].keys - subtables[level].dead != 1) return(0); - /* The projection function should be isolated. If the ref count - ** is 1, everything is OK. If the ref count is saturated, then - ** we need to make sure that there are no nodes pointing to it. - ** As for the external references, we assume the application is - ** responsible for them. - */ - if (vars[index]->ref != 1) { - if (vars[index]->ref != DD_MAXREF) return(0); - found = cuddFindParent(unique,vars[index]); - if (found) { - return(0); - } else { - vars[index]->ref = 1; + level = unique->perm[index]; + if (level < lowestLevel) lowestLevel = level; + nodelist = subtables[level].nodelist; + if (subtables[level].keys - subtables[level].dead != 1) return(0); + /* The projection function should be isolated. If the ref count + ** is 1, everything is OK. If the ref count is saturated, then + ** we need to make sure that there are no nodes pointing to it. + ** As for the external references, we assume the application is + ** responsible for them. + */ + if (vars[index]->ref != 1) { + if (vars[index]->ref != DD_MAXREF) return(0); + found = cuddFindParent(unique,vars[index]); + if (found) { + return(0); + } else { + vars[index]->ref = 1; + } } - } - Cudd_RecursiveDeref(unique,vars[index]); + Cudd_RecursiveDeref(unique,vars[index]); } /* Collect garbage, because we cannot afford having dead nodes pointing @@ -2132,15 +2153,15 @@ cuddDestroySubtables( /* Here we know we can destroy our subtables. */ for (index = firstIndex; index < lastIndex; index++) { - level = unique->perm[index]; - nodelist = subtables[level].nodelist; + level = unique->perm[index]; + nodelist = subtables[level].nodelist; #ifdef DD_DEBUG - assert(subtables[level].keys == 0); + assert(subtables[level].keys == 0); #endif - ABC_FREE(nodelist); - unique->memused -= sizeof(DdNodePtr) * subtables[level].slots; - unique->slots -= subtables[level].slots; - unique->dead -= subtables[level].dead; + ABC_FREE(nodelist); + unique->memused -= sizeof(DdNodePtr) * subtables[level].slots; + unique->slots -= subtables[level].slots; + unique->dead -= subtables[level].dead; } /* Here all subtables to be destroyed have their keys field == 0 and @@ -2152,33 +2173,33 @@ cuddDestroySubtables( */ shift = 1; for (level = lowestLevel + 1; level < unique->size; level++) { - if (subtables[level].keys == 0) { - shift++; - continue; - } - newlevel = level - shift; - subtables[newlevel].slots = subtables[level].slots; - subtables[newlevel].shift = subtables[level].shift; - subtables[newlevel].keys = subtables[level].keys; - subtables[newlevel].maxKeys = subtables[level].maxKeys; - subtables[newlevel].dead = subtables[level].dead; - subtables[newlevel].nodelist = subtables[level].nodelist; - index = unique->invperm[level]; - unique->perm[index] = newlevel; - unique->invperm[newlevel] = index; - subtables[newlevel].bindVar = subtables[level].bindVar; - subtables[newlevel].varType = subtables[level].varType; - subtables[newlevel].pairIndex = subtables[level].pairIndex; - subtables[newlevel].varHandled = subtables[level].varHandled; - subtables[newlevel].varToBeGrouped = subtables[level].varToBeGrouped; + if (subtables[level].keys == 0) { + shift++; + continue; + } + newlevel = level - shift; + subtables[newlevel].slots = subtables[level].slots; + subtables[newlevel].shift = subtables[level].shift; + subtables[newlevel].keys = subtables[level].keys; + subtables[newlevel].maxKeys = subtables[level].maxKeys; + subtables[newlevel].dead = subtables[level].dead; + subtables[newlevel].nodelist = subtables[level].nodelist; + index = unique->invperm[level]; + unique->perm[index] = newlevel; + unique->invperm[newlevel] = index; + subtables[newlevel].bindVar = subtables[level].bindVar; + subtables[newlevel].varType = subtables[level].varType; + subtables[newlevel].pairIndex = subtables[level].pairIndex; + subtables[newlevel].varHandled = subtables[level].varHandled; + subtables[newlevel].varToBeGrouped = subtables[level].varToBeGrouped; } /* Destroy the map. If a surviving variable is ** mapped to a dying variable, and the map were used again, ** an out-of-bounds access to unique->vars would result. */ if (unique->map != NULL) { - cuddCacheFlush(unique); - ABC_FREE(unique->map); - unique->map = NULL; + cuddCacheFlush(unique); + ABC_FREE(unique->map); + unique->map = NULL; } unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); @@ -2216,105 +2237,104 @@ cuddResizeTableZdd( int i,j,reorderSave; unsigned int numSlots = unique->initSlots; int *newperm, *newinvperm; - DdNode *one, *zero; oldsize = unique->sizeZ; /* Easy case: there is still room in the current table. */ if (index < unique->maxSizeZ) { - for (i = oldsize; i <= index; i++) { - unique->subtableZ[i].slots = numSlots; - unique->subtableZ[i].shift = sizeof(int) * 8 - - cuddComputeFloorLog2(numSlots); - unique->subtableZ[i].keys = 0; - unique->subtableZ[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; - unique->subtableZ[i].dead = 0; - unique->permZ[i] = i; - unique->invpermZ[i] = i; - newnodelist = unique->subtableZ[i].nodelist = - ABC_ALLOC(DdNodePtr, numSlots); - if (newnodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - for (j = 0; j < (int)numSlots; j++) { - newnodelist[j] = NULL; + for (i = oldsize; i <= index; i++) { + unique->subtableZ[i].slots = numSlots; + unique->subtableZ[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtableZ[i].keys = 0; + unique->subtableZ[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtableZ[i].dead = 0; + unique->permZ[i] = i; + unique->invpermZ[i] = i; + newnodelist = unique->subtableZ[i].nodelist = + ABC_ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = NULL; + } } - } } else { - /* The current table is too small: we need to allocate a new, - ** larger one; move all old subtables, and initialize the new - ** subtables up to index included. - */ - newsize = index + DD_DEFAULT_RESIZE; + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables up to index included. + */ + newsize = index + DD_DEFAULT_RESIZE; #ifdef DD_VERBOSE - (void) fprintf(unique->err, - "Increasing the ZDD table size from %d to %d\n", - unique->maxSizeZ, newsize); + (void) fprintf(unique->err, + "Increasing the ZDD table size from %d to %d\n", + unique->maxSizeZ, newsize); #endif - newsubtables = ABC_ALLOC(DdSubtable,newsize); - if (newsubtables == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - newperm = ABC_ALLOC(int,newsize); - if (newperm == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - newinvperm = ABC_ALLOC(int,newsize); - if (newinvperm == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - unique->memused += (newsize - unique->maxSizeZ) * ((numSlots+1) * - sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); - if (newsize > unique->maxSize) { - ABC_FREE(unique->stack); - unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1); - if (unique->stack == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + newsubtables = ABC_ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - unique->stack[0] = NULL; /* to suppress harmless UMR */ - unique->memused += - (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) - * sizeof(DdNode *); - } - for (i = 0; i < oldsize; i++) { - newsubtables[i].slots = unique->subtableZ[i].slots; - newsubtables[i].shift = unique->subtableZ[i].shift; - newsubtables[i].keys = unique->subtableZ[i].keys; - newsubtables[i].maxKeys = unique->subtableZ[i].maxKeys; - newsubtables[i].dead = unique->subtableZ[i].dead; - newsubtables[i].nodelist = unique->subtableZ[i].nodelist; - newperm[i] = unique->permZ[i]; - newinvperm[i] = unique->invpermZ[i]; - } - for (i = oldsize; i <= index; i++) { - newsubtables[i].slots = numSlots; - newsubtables[i].shift = sizeof(int) * 8 - - cuddComputeFloorLog2(numSlots); - newsubtables[i].keys = 0; - newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; - newsubtables[i].dead = 0; - newperm[i] = i; - newinvperm[i] = i; - newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots); - if (newnodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + newperm = ABC_ALLOC(int,newsize); + if (newperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - for (j = 0; j < (int)numSlots; j++) { - newnodelist[j] = NULL; + newinvperm = ABC_ALLOC(int,newsize); + if (newinvperm == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - } - ABC_FREE(unique->subtableZ); - unique->subtableZ = newsubtables; - unique->maxSizeZ = newsize; - ABC_FREE(unique->permZ); - unique->permZ = newperm; - ABC_FREE(unique->invpermZ); - unique->invpermZ = newinvperm; + unique->memused += (newsize - unique->maxSizeZ) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + if (newsize > unique->maxSize) { + ABC_FREE(unique->stack); + unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); + } + for (i = 0; i < oldsize; i++) { + newsubtables[i].slots = unique->subtableZ[i].slots; + newsubtables[i].shift = unique->subtableZ[i].shift; + newsubtables[i].keys = unique->subtableZ[i].keys; + newsubtables[i].maxKeys = unique->subtableZ[i].maxKeys; + newsubtables[i].dead = unique->subtableZ[i].dead; + newsubtables[i].nodelist = unique->subtableZ[i].nodelist; + newperm[i] = unique->permZ[i]; + newinvperm[i] = unique->invpermZ[i]; + } + for (i = oldsize; i <= index; i++) { + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newperm[i] = i; + newinvperm[i] = i; + newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; (unsigned) j < numSlots; j++) { + newnodelist[j] = NULL; + } + } + ABC_FREE(unique->subtableZ); + unique->subtableZ = newsubtables; + unique->maxSizeZ = newsize; + ABC_FREE(unique->permZ); + unique->permZ = newperm; + ABC_FREE(unique->invpermZ); + unique->invpermZ = newinvperm; } unique->slots += (index + 1 - unique->sizeZ) * numSlots; ddFixLimits(unique); @@ -2324,15 +2344,13 @@ cuddResizeTableZdd( ** universe. We need to temporarily disable reordering, ** because we cannot reorder without universe in place. */ - one = unique->one; - zero = unique->zero; reorderSave = unique->autoDynZ; unique->autoDynZ = 0; cuddZddFreeUniv(unique); if (!cuddZddInitUniv(unique)) { - unique->autoDynZ = reorderSave; - return(0); + unique->autoDynZ = reorderSave; + return(0); } unique->autoDynZ = reorderSave; @@ -2359,16 +2377,16 @@ cuddSlowTableGrowth( int i; unique->maxCacheHard = unique->cacheSlots - 1; - unique->cacheSlack = -(int)(unique->cacheSlots + 1); + unique->cacheSlack = - (int) (unique->cacheSlots + 1); for (i = 0; i < unique->size; i++) { - unique->subtables[i].maxKeys <<= 2; + unique->subtables[i].maxKeys <<= 2; } unique->gcFrac = DD_GC_FRAC_MIN; unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots); cuddShrinkDeathRow(unique); (void) fprintf(unique->err,"Slowing down table growth: "); (void) fprintf(unique->err,"GC fraction = %.2f\t", unique->gcFrac); - (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + (void) fprintf(unique->err,"minDead = %u\n", unique->minDead); } /* end of cuddSlowTableGrowth */ @@ -2399,19 +2417,19 @@ ddRehashZdd( int j, pos; DdNodePtr *nodelist, *oldnodelist; DdNode *node, *next; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; if (unique->slots > unique->looseUpTo) { - unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); + unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots); #ifdef DD_VERBOSE - if (unique->gcFrac == DD_GC_FRAC_HI) { - (void) fprintf(unique->err,"GC fraction = %.2f\t", - DD_GC_FRAC_LO); - (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); - } + if (unique->gcFrac == DD_GC_FRAC_HI) { + (void) fprintf(unique->err,"GC fraction = %.2f\t", + DD_GC_FRAC_LO); + (void) fprintf(unique->err,"minDead = %d\n", unique->minDead); + } #endif - unique->gcFrac = DD_GC_FRAC_LO; + unique->gcFrac = DD_GC_FRAC_LO; } assert(i != CUDD_MAXINDEX); @@ -2425,8 +2443,8 @@ ddRehashZdd( slots = oldslots; shift = oldshift; do { - slots <<= 1; - shift--; + slots <<= 1; + shift--; } while (slots * DD_MAX_SUBTABLE_DENSITY < unique->subtableZ[i].keys); saveHandler = MMoutOfMemory; @@ -2434,40 +2452,39 @@ ddRehashZdd( nodelist = ABC_ALLOC(DdNodePtr, slots); MMoutOfMemory = saveHandler; if (nodelist == NULL) { - int j; - (void) fprintf(unique->err, - "Unable to resize ZDD subtable %d for lack of memory.\n", - i); - (void) cuddGarbageCollectZdd(unique,1); - for (j = 0; j < unique->sizeZ; j++) { - unique->subtableZ[j].maxKeys <<= 1; - } - return; + (void) fprintf(unique->err, + "Unable to resize ZDD subtable %d for lack of memory.\n", + i); + (void) cuddGarbageCollect(unique,1); + for (j = 0; j < unique->sizeZ; j++) { + unique->subtableZ[j].maxKeys <<= 1; + } + return; } unique->subtableZ[i].nodelist = nodelist; unique->subtableZ[i].slots = slots; unique->subtableZ[i].shift = shift; unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = NULL; + nodelist[j] = NULL; } for (j = 0; (unsigned) j < oldslots; j++) { - node = oldnodelist[j]; - while (node != NULL) { - next = node->next; - pos = ddHash(cuddT(node), cuddE(node), shift); - node->next = nodelist[pos]; - nodelist[pos] = node; - node = next; - } + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + pos = ddHash(cuddT(node), cuddE(node), shift); + node->next = nodelist[pos]; + nodelist[pos] = node; + node = next; + } } ABC_FREE(oldnodelist); #ifdef DD_VERBOSE (void) fprintf(unique->err, - "rehashing layer %d: keys %d dead %d new size %d\n", - i, unique->subtableZ[i].keys, - unique->subtableZ[i].dead, slots); + "rehashing layer %d: keys %d dead %d new size %d\n", + i, unique->subtableZ[i].keys, + unique->subtableZ[i].dead, slots); #endif /* Update global data. */ @@ -2503,176 +2520,175 @@ ddResizeTable( int oldsize,newsize; int i,j,reorderSave; int numSlots = unique->initSlots; - int *newperm, *newinvperm; - int *newmap = NULL; // Suppress "might be used uninitialized" + int *newperm, *newinvperm, *newmap; DdNode *one, *zero; oldsize = unique->size; /* Easy case: there is still room in the current table. */ if (index < unique->maxSize) { - for (i = oldsize; i <= index; i++) { - unique->subtables[i].slots = numSlots; - unique->subtables[i].shift = sizeof(int) * 8 - - cuddComputeFloorLog2(numSlots); - unique->subtables[i].keys = 0; - unique->subtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; - unique->subtables[i].dead = 0; - unique->subtables[i].bindVar = 0; - unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; - unique->subtables[i].pairIndex = 0; - unique->subtables[i].varHandled = 0; - unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; - - unique->perm[i] = i; - unique->invperm[i] = i; - newnodelist = unique->subtables[i].nodelist = - ABC_ALLOC(DdNodePtr, numSlots); - if (newnodelist == NULL) { - for (j = oldsize; j < i; j++) { - ABC_FREE(unique->subtables[j].nodelist); - } - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - for (j = 0; j < numSlots; j++) { - newnodelist[j] = sentinel; - } - } - if (unique->map != NULL) { for (i = oldsize; i <= index; i++) { - unique->map[i] = i; + unique->subtables[i].slots = numSlots; + unique->subtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + unique->subtables[i].keys = 0; + unique->subtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + unique->subtables[i].dead = 0; + unique->subtables[i].bindVar = 0; + unique->subtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + unique->subtables[i].pairIndex = 0; + unique->subtables[i].varHandled = 0; + unique->subtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + unique->perm[i] = i; + unique->invperm[i] = i; + newnodelist = unique->subtables[i].nodelist = + ABC_ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + for (j = oldsize; j < i; j++) { + ABC_FREE(unique->subtables[j].nodelist); + } + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; j < numSlots; j++) { + newnodelist[j] = sentinel; + } + } + if (unique->map != NULL) { + for (i = oldsize; i <= index; i++) { + unique->map[i] = i; + } } - } } else { - /* The current table is too small: we need to allocate a new, - ** larger one; move all old subtables, and initialize the new - ** subtables up to index included. - */ - newsize = index + DD_DEFAULT_RESIZE; + /* The current table is too small: we need to allocate a new, + ** larger one; move all old subtables, and initialize the new + ** subtables up to index included. + */ + newsize = index + DD_DEFAULT_RESIZE; #ifdef DD_VERBOSE - (void) fprintf(unique->err, - "Increasing the table size from %d to %d\n", - unique->maxSize, newsize); + (void) fprintf(unique->err, + "Increasing the table size from %d to %d\n", + unique->maxSize, newsize); #endif - newsubtables = ABC_ALLOC(DdSubtable,newsize); - if (newsubtables == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - newvars = ABC_ALLOC(DdNodePtr,newsize); - if (newvars == NULL) { - ABC_FREE(newsubtables); - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - newperm = ABC_ALLOC(int,newsize); - if (newperm == NULL) { - ABC_FREE(newsubtables); - ABC_FREE(newvars); - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - newinvperm = ABC_ALLOC(int,newsize); - if (newinvperm == NULL) { - ABC_FREE(newsubtables); - ABC_FREE(newvars); - ABC_FREE(newperm); - unique->errorCode = CUDD_MEMORY_OUT; - return(0); - } - if (unique->map != NULL) { - newmap = ABC_ALLOC(int,newsize); - if (newmap == NULL) { - ABC_FREE(newsubtables); - ABC_FREE(newvars); - ABC_FREE(newperm); - ABC_FREE(newinvperm); - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + newsubtables = ABC_ALLOC(DdSubtable,newsize); + if (newsubtables == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - unique->memused += (newsize - unique->maxSize) * sizeof(int); - } - unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * - sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); - if (newsize > unique->maxSizeZ) { - ABC_FREE(unique->stack); - unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1); - if (unique->stack == NULL) { - ABC_FREE(newsubtables); - ABC_FREE(newvars); - ABC_FREE(newperm); - ABC_FREE(newinvperm); - if (unique->map != NULL) { - ABC_FREE(newmap); + newvars = ABC_ALLOC(DdNodePtr,newsize); + if (newvars == NULL) { + ABC_FREE(newsubtables); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + newperm = ABC_ALLOC(int,newsize); + if (newperm == NULL) { + ABC_FREE(newsubtables); + ABC_FREE(newvars); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - unique->stack[0] = NULL; /* to suppress harmless UMR */ - unique->memused += - (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) - * sizeof(DdNode *); - } - for (i = 0; i < oldsize; i++) { - newsubtables[i].slots = unique->subtables[i].slots; - newsubtables[i].shift = unique->subtables[i].shift; - newsubtables[i].keys = unique->subtables[i].keys; - newsubtables[i].maxKeys = unique->subtables[i].maxKeys; - newsubtables[i].dead = unique->subtables[i].dead; - newsubtables[i].nodelist = unique->subtables[i].nodelist; - newsubtables[i].bindVar = unique->subtables[i].bindVar; - newsubtables[i].varType = unique->subtables[i].varType; - newsubtables[i].pairIndex = unique->subtables[i].pairIndex; - newsubtables[i].varHandled = unique->subtables[i].varHandled; - newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; - - newvars[i] = unique->vars[i]; - newperm[i] = unique->perm[i]; - newinvperm[i] = unique->invperm[i]; - } - for (i = oldsize; i <= index; i++) { - newsubtables[i].slots = numSlots; - newsubtables[i].shift = sizeof(int) * 8 - - cuddComputeFloorLog2(numSlots); - newsubtables[i].keys = 0; - newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; - newsubtables[i].dead = 0; - newsubtables[i].bindVar = 0; - newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; - newsubtables[i].pairIndex = 0; - newsubtables[i].varHandled = 0; - newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; - - newperm[i] = i; - newinvperm[i] = i; - newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots); - if (newnodelist == NULL) { - unique->errorCode = CUDD_MEMORY_OUT; - return(0); + newinvperm = ABC_ALLOC(int,newsize); + if (newinvperm == NULL) { + ABC_FREE(newsubtables); + ABC_FREE(newvars); + ABC_FREE(newperm); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); } - for (j = 0; j < numSlots; j++) { - newnodelist[j] = sentinel; + if (unique->map != NULL) { + newmap = ABC_ALLOC(int,newsize); + if (newmap == NULL) { + ABC_FREE(newsubtables); + ABC_FREE(newvars); + ABC_FREE(newperm); + ABC_FREE(newinvperm); + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->memused += (newsize - unique->maxSize) * sizeof(int); + } + unique->memused += (newsize - unique->maxSize) * ((numSlots+1) * + sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable)); + if (newsize > unique->maxSizeZ) { + ABC_FREE(unique->stack); + unique->stack = ABC_ALLOC(DdNodePtr,newsize + 1); + if (unique->stack == NULL) { + ABC_FREE(newsubtables); + ABC_FREE(newvars); + ABC_FREE(newperm); + ABC_FREE(newinvperm); + if (unique->map != NULL) { + ABC_FREE(newmap); + } + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + unique->stack[0] = NULL; /* to suppress harmless UMR */ + unique->memused += + (newsize - ddMax(unique->maxSize,unique->maxSizeZ)) + * sizeof(DdNode *); } - } - if (unique->map != NULL) { for (i = 0; i < oldsize; i++) { - newmap[i] = unique->map[i]; + newsubtables[i].slots = unique->subtables[i].slots; + newsubtables[i].shift = unique->subtables[i].shift; + newsubtables[i].keys = unique->subtables[i].keys; + newsubtables[i].maxKeys = unique->subtables[i].maxKeys; + newsubtables[i].dead = unique->subtables[i].dead; + newsubtables[i].nodelist = unique->subtables[i].nodelist; + newsubtables[i].bindVar = unique->subtables[i].bindVar; + newsubtables[i].varType = unique->subtables[i].varType; + newsubtables[i].pairIndex = unique->subtables[i].pairIndex; + newsubtables[i].varHandled = unique->subtables[i].varHandled; + newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped; + + newvars[i] = unique->vars[i]; + newperm[i] = unique->perm[i]; + newinvperm[i] = unique->invperm[i]; } for (i = oldsize; i <= index; i++) { - newmap[i] = i; + newsubtables[i].slots = numSlots; + newsubtables[i].shift = sizeof(int) * 8 - + cuddComputeFloorLog2(numSlots); + newsubtables[i].keys = 0; + newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY; + newsubtables[i].dead = 0; + newsubtables[i].bindVar = 0; + newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT; + newsubtables[i].pairIndex = 0; + newsubtables[i].varHandled = 0; + newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE; + + newperm[i] = i; + newinvperm[i] = i; + newnodelist = newsubtables[i].nodelist = ABC_ALLOC(DdNodePtr, numSlots); + if (newnodelist == NULL) { + unique->errorCode = CUDD_MEMORY_OUT; + return(0); + } + for (j = 0; j < numSlots; j++) { + newnodelist[j] = sentinel; + } } - ABC_FREE(unique->map); - unique->map = newmap; - } - ABC_FREE(unique->subtables); - unique->subtables = newsubtables; - unique->maxSize = newsize; - ABC_FREE(unique->vars); - unique->vars = newvars; - ABC_FREE(unique->perm); - unique->perm = newperm; - ABC_FREE(unique->invperm); - unique->invperm = newinvperm; + if (unique->map != NULL) { + for (i = 0; i < oldsize; i++) { + newmap[i] = unique->map[i]; + } + for (i = oldsize; i <= index; i++) { + newmap[i] = i; + } + ABC_FREE(unique->map); + unique->map = newmap; + } + ABC_FREE(unique->subtables); + unique->subtables = newsubtables; + unique->maxSize = newsize; + ABC_FREE(unique->vars); + unique->vars = newvars; + ABC_FREE(unique->perm); + unique->perm = newperm; + ABC_FREE(unique->invperm); + unique->invperm = newinvperm; } /* Now that the table is in a coherent state, create the new @@ -2689,24 +2705,24 @@ ddResizeTable( reorderSave = unique->autoDyn; unique->autoDyn = 0; for (i = oldsize; i <= index; i++) { - unique->vars[i] = cuddUniqueInter(unique,i,one,zero); - if (unique->vars[i] == NULL) { - unique->autoDyn = reorderSave; - for (j = oldsize; j < i; j++) { - Cudd_IterDerefBdd(unique,unique->vars[j]); - cuddDeallocNode(unique,unique->vars[j]); - unique->vars[j] = NULL; - } - for (j = oldsize; j <= index; j++) { - ABC_FREE(unique->subtables[j].nodelist); - unique->subtables[j].nodelist = NULL; - } - unique->size = oldsize; - unique->slots -= (index + 1 - oldsize) * numSlots; - ddFixLimits(unique); - return(0); - } - cuddRef(unique->vars[i]); + unique->vars[i] = cuddUniqueInter(unique,i,one,zero); + if (unique->vars[i] == NULL) { + unique->autoDyn = reorderSave; + for (j = oldsize; j < i; j++) { + Cudd_IterDerefBdd(unique,unique->vars[j]); + cuddDeallocNode(unique,unique->vars[j]); + unique->vars[j] = NULL; + } + for (j = oldsize; j <= index; j++) { + ABC_FREE(unique->subtables[j].nodelist); + unique->subtables[j].nodelist = NULL; + } + unique->size = oldsize; + unique->slots -= (index + 1 - oldsize) * numSlots; + ddFixLimits(unique); + return(0); + } + cuddRef(unique->vars[i]); } unique->autoDyn = reorderSave; @@ -2733,27 +2749,27 @@ cuddFindParent( DdNode * node) { int i,j; - int slots; - DdNodePtr *nodelist; - DdNode *f; + int slots; + DdNodePtr *nodelist; + DdNode *f; for (i = cuddI(table,node->index) - 1; i >= 0; i--) { - nodelist = table->subtables[i].nodelist; - slots = table->subtables[i].slots; + nodelist = table->subtables[i].nodelist; + slots = table->subtables[i].slots; - for (j = 0; j < slots; j++) { - f = nodelist[j]; - while (cuddT(f) > node) { - f = f->next; - } - while (cuddT(f) == node && Cudd_Regular(cuddE(f)) > node) { - f = f->next; - } - if (cuddT(f) == node && Cudd_Regular(cuddE(f)) == node) { - return(1); + for (j = 0; j < slots; j++) { + f = nodelist[j]; + while (cuddT(f) > node) { + f = f->next; + } + while (cuddT(f) == node && Cudd_Regular(cuddE(f)) > node) { + f = f->next; + } + if (cuddT(f) == node && Cudd_Regular(cuddE(f)) == node) { + return(1); + } } } - } return(0); @@ -2780,16 +2796,17 @@ ddFixLimits( { unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots); unique->cacheSlack = (int) ddMin(unique->maxCacheHard, - DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) - - 2 * (int) unique->cacheSlots; + DD_MAX_CACHE_TO_SLOTS_RATIO * unique->slots) - + 2 * (int) unique->cacheSlots; if (unique->cacheSlots < unique->slots/2 && unique->cacheSlack >= 0) - cuddCacheResize(unique); + cuddCacheResize(unique); return; } /* end of ddFixLimits */ #ifndef DD_UNSORTED_FREE_LIST +#ifdef DD_RED_BLACK_FREE_LIST /**Function******************************************************************** Synopsis [Inserts a DdNode in a red/black search tree.] @@ -2814,13 +2831,13 @@ cuddOrderedInsert( scanP = root; while ((scan = *scanP) != NULL) { - stack[stackN++] = scanP; - if (DD_INSERT_COMPARE(node, scan) == 0) { /* add to page list */ - DD_NEXT(node) = DD_NEXT(scan); - DD_NEXT(scan) = node; - return; - } - scanP = (node < scan) ? &DD_LEFT(scan) : &DD_RIGHT(scan); + stack[stackN++] = scanP; + if (DD_INSERT_COMPARE(node, scan) == 0) { /* add to page list */ + DD_NEXT(node) = DD_NEXT(scan); + DD_NEXT(scan) = node; + return; + } + scanP = (node < scan) ? &DD_LEFT(scan) : &DD_RIGHT(scan); } DD_RIGHT(node) = DD_LEFT(node) = DD_NEXT(node) = NULL; DD_COLOR(node) = DD_RED; @@ -2866,42 +2883,42 @@ cuddOrderedThread( *((DdNodePtr *) current) = NULL; while (current != NULL) { - if (DD_RIGHT(current) != NULL) { - /* If possible, we follow the "right" link. Eventually we'll - ** find the node with the largest address in the current tree. - ** In this phase we use the first word of a node to implemen - ** a stack of the nodes on the path from the root to "current". - ** Also, we disconnect the "right" pointers to indicate that - ** we have already followed them. - */ - next = DD_RIGHT(current); - DD_RIGHT(current) = NULL; - *((DdNodePtr *)next) = current; - current = next; - } else { - /* We can't proceed along the "right" links any further. - ** Hence "current" is the largest element in the current tree. - ** We make this node the new head of "list". (Repeating this - ** operation until the tree is empty yields the desired linear - ** threading of all nodes.) - */ - prev = *((DdNodePtr *) current); /* save prev node on stack in prev */ - /* Traverse the linked list of current until the end. */ - for (end = current; DD_NEXT(end) != NULL; end = DD_NEXT(end)); - DD_NEXT(end) = list; /* attach "list" at end and make */ - list = current; /* "current" the new head of "list" */ - /* Now, if current has a "left" child, we push it on the stack. - ** Otherwise, we just continue with the parent of "current". - */ - if (DD_LEFT(current) != NULL) { - next = DD_LEFT(current); - *((DdNodePtr *) next) = prev; - current = next; + if (DD_RIGHT(current) != NULL) { + /* If possible, we follow the "right" link. Eventually we'll + ** find the node with the largest address in the current tree. + ** In this phase we use the first word of a node to implemen + ** a stack of the nodes on the path from the root to "current". + ** Also, we disconnect the "right" pointers to indicate that + ** we have already followed them. + */ + next = DD_RIGHT(current); + DD_RIGHT(current) = NULL; + *((DdNodePtr *)next) = current; + current = next; } else { - current = prev; + /* We can't proceed along the "right" links any further. + ** Hence "current" is the largest element in the current tree. + ** We make this node the new head of "list". (Repeating this + ** operation until the tree is empty yields the desired linear + ** threading of all nodes.) + */ + prev = *((DdNodePtr *) current); /* save prev node on stack in prev */ + /* Traverse the linked list of current until the end. */ + for (end = current; DD_NEXT(end) != NULL; end = DD_NEXT(end)); + DD_NEXT(end) = list; /* attach "list" at end and make */ + list = current; /* "current" the new head of "list" */ + /* Now, if current has a "left" child, we push it on the stack. + ** Otherwise, we just continue with the parent of "current". + */ + if (DD_LEFT(current) != NULL) { + next = DD_LEFT(current); + *((DdNodePtr *) next) = prev; + current = next; + } else { + current = prev; + } } } - } return(list); @@ -2983,55 +3000,56 @@ cuddDoRebalance( x = *xP; /* Work our way back up, re-balancing the tree. */ while (--stackN >= 0) { - parentP = stack[stackN]; - parent = *parentP; - if (DD_IS_BLACK(parent)) break; - /* Since the root is black, here a non-null grandparent exists. */ - grandpaP = stack[stackN-1]; - grandpa = *grandpaP; - if (parent == DD_LEFT(grandpa)) { - y = DD_RIGHT(grandpa); - if (y != NULL && DD_IS_RED(y)) { - DD_COLOR(parent) = DD_BLACK; - DD_COLOR(y) = DD_BLACK; - DD_COLOR(grandpa) = DD_RED; - x = grandpa; - stackN--; - } else { - if (x == DD_RIGHT(parent)) { - cuddRotateLeft(parentP); - DD_COLOR(x) = DD_BLACK; - } else { - DD_COLOR(parent) = DD_BLACK; - } - DD_COLOR(grandpa) = DD_RED; - cuddRotateRight(grandpaP); - break; - } - } else { - y = DD_LEFT(grandpa); - if (y != NULL && DD_IS_RED(y)) { - DD_COLOR(parent) = DD_BLACK; - DD_COLOR(y) = DD_BLACK; - DD_COLOR(grandpa) = DD_RED; - x = grandpa; - stackN--; - } else { - if (x == DD_LEFT(parent)) { - cuddRotateRight(parentP); - DD_COLOR(x) = DD_BLACK; + parentP = stack[stackN]; + parent = *parentP; + if (DD_IS_BLACK(parent)) break; + /* Since the root is black, here a non-null grandparent exists. */ + grandpaP = stack[stackN-1]; + grandpa = *grandpaP; + if (parent == DD_LEFT(grandpa)) { + y = DD_RIGHT(grandpa); + if (y != NULL && DD_IS_RED(y)) { + DD_COLOR(parent) = DD_BLACK; + DD_COLOR(y) = DD_BLACK; + DD_COLOR(grandpa) = DD_RED; + x = grandpa; + stackN--; + } else { + if (x == DD_RIGHT(parent)) { + cuddRotateLeft(parentP); + DD_COLOR(x) = DD_BLACK; + } else { + DD_COLOR(parent) = DD_BLACK; + } + DD_COLOR(grandpa) = DD_RED; + cuddRotateRight(grandpaP); + break; + } } else { - DD_COLOR(parent) = DD_BLACK; - } - DD_COLOR(grandpa) = DD_RED; - cuddRotateLeft(grandpaP); + y = DD_LEFT(grandpa); + if (y != NULL && DD_IS_RED(y)) { + DD_COLOR(parent) = DD_BLACK; + DD_COLOR(y) = DD_BLACK; + DD_COLOR(grandpa) = DD_RED; + x = grandpa; + stackN--; + } else { + if (x == DD_LEFT(parent)) { + cuddRotateRight(parentP); + DD_COLOR(x) = DD_BLACK; + } else { + DD_COLOR(parent) = DD_BLACK; + } + DD_COLOR(grandpa) = DD_RED; + cuddRotateLeft(grandpaP); + } } } - } DD_COLOR(*(stack[0])) = DD_BLACK; } /* end of cuddDoRebalance */ #endif +#endif /**Function******************************************************************** @@ -3055,11 +3073,11 @@ ddPatchTree( MtrNode *auxnode = treenode; while (auxnode != NULL) { - auxnode->low = dd->perm[auxnode->index]; - if (auxnode->child != NULL) { - ddPatchTree(dd, auxnode->child); - } - auxnode = auxnode->younger; + auxnode->low = dd->perm[auxnode->index]; + if (auxnode->child != NULL) { + ddPatchTree(dd, auxnode->child); + } + auxnode = auxnode->younger; } return; @@ -3096,14 +3114,14 @@ cuddCheckCollisionOrdering( if (node == sentinel) return(1); next = node->next; while (next != sentinel) { - if (cuddT(node) < cuddT(next) || - (cuddT(node) == cuddT(next) && cuddE(node) < cuddE(next))) { - (void) fprintf(unique->err, - "Unordered list: index %u, position %d\n", i, j); - return(0); - } - node = next; - next = node->next; + if (cuddT(node) < cuddT(next) || + (cuddT(node) == cuddT(next) && cuddE(node) < cuddE(next))) { + (void) fprintf(unique->err, + "Unordered list: index %u, position %d\n", i, j); + return(0); + } + node = next; + next = node->next; } return(1); @@ -3128,14 +3146,14 @@ static void ddReportRefMess( DdManager *unique /* manager */, int i /* table in which the problem occurred */, - char *caller /* procedure that detected the problem */) + const char *caller /* procedure that detected the problem */) { if (i == CUDD_CONST_INDEX) { - (void) fprintf(unique->err, - "%s: problem in constants\n", caller); + (void) fprintf(unique->err, + "%s: problem in constants\n", caller); } else if (i != -1) { - (void) fprintf(unique->err, - "%s: problem in table %d\n", caller, i); + (void) fprintf(unique->err, + "%s: problem in table %d\n", caller, i); } (void) fprintf(unique->err, " dead count != deleted\n"); (void) fprintf(unique->err, " This problem is often due to a missing \ @@ -3144,5 +3162,7 @@ See the CUDD Programmer's Guide for additional details."); abort(); } /* end of ddReportRefMess */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddUtil.c b/src/bdd/cudd/cuddUtil.c index cbaafb5a..80577366 100644 --- a/src/bdd/cudd/cuddUtil.c +++ b/src/bdd/cudd/cuddUtil.c @@ -7,72 +7,101 @@ Synopsis [Utility functions.] Description [External procedures included in this module: - <ul> - <li> Cudd_PrintMinterm() - <li> Cudd_PrintDebug() - <li> Cudd_DagSize() - <li> Cudd_EstimateCofactor() - <li> Cudd_EstimateCofactorSimple() - <li> Cudd_SharingSize() - <li> Cudd_CountMinterm() - <li> Cudd_EpdCountMinterm() - <li> Cudd_CountPath() - <li> Cudd_CountPathsToNonZero() - <li> Cudd_Support() - <li> Cudd_SupportIndex() - <li> Cudd_SupportSize() - <li> Cudd_VectorSupport() - <li> Cudd_VectorSupportIndex() - <li> Cudd_VectorSupportSize() - <li> Cudd_ClassifySupport() - <li> Cudd_CountLeaves() - <li> Cudd_bddPickOneCube() - <li> Cudd_bddPickOneMinterm() - <li> Cudd_bddPickArbitraryMinterms() - <li> Cudd_SubsetWithMaskVars() - <li> Cudd_FirstCube() - <li> Cudd_NextCube() - <li> Cudd_bddComputeCube() - <li> Cudd_addComputeCube() - <li> Cudd_FirstNode() - <li> Cudd_NextNode() - <li> Cudd_GenFree() - <li> Cudd_IsGenEmpty() - <li> Cudd_IndicesToCube() - <li> Cudd_PrintVersion() - <li> Cudd_AverageDistance() - <li> Cudd_Random() - <li> Cudd_Srandom() - <li> Cudd_Density() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddP() - <li> cuddStCountfree() - <li> cuddCollectNodes() - </ul> - Static procedures included in this module: - <ul> - <li> dp2() - <li> ddPrintMintermAux() - <li> ddDagInt() - <li> ddCountMintermAux() - <li> ddEpdCountMintermAux() - <li> ddCountPathAux() - <li> ddSupportStep() - <li> ddClearFlag() - <li> ddLeavesInt() - <li> ddPickArbitraryMinterms() - <li> ddPickRepresentativeCube() - <li> ddEpdFree() - </ul>] + <ul> + <li> Cudd_PrintMinterm() + <li> Cudd_bddPrintCover() + <li> Cudd_PrintDebug() + <li> Cudd_DagSize() + <li> Cudd_EstimateCofactor() + <li> Cudd_EstimateCofactorSimple() + <li> Cudd_SharingSize() + <li> Cudd_CountMinterm() + <li> Cudd_EpdCountMinterm() + <li> Cudd_CountPath() + <li> Cudd_CountPathsToNonZero() + <li> Cudd_Support() + <li> Cudd_SupportIndex() + <li> Cudd_SupportSize() + <li> Cudd_VectorSupport() + <li> Cudd_VectorSupportIndex() + <li> Cudd_VectorSupportSize() + <li> Cudd_ClassifySupport() + <li> Cudd_CountLeaves() + <li> Cudd_bddPickOneCube() + <li> Cudd_bddPickOneMinterm() + <li> Cudd_bddPickArbitraryMinterms() + <li> Cudd_SubsetWithMaskVars() + <li> Cudd_FirstCube() + <li> Cudd_NextCube() + <li> Cudd_bddComputeCube() + <li> Cudd_addComputeCube() + <li> Cudd_FirstNode() + <li> Cudd_NextNode() + <li> Cudd_GenFree() + <li> Cudd_IsGenEmpty() + <li> Cudd_IndicesToCube() + <li> Cudd_PrintVersion() + <li> Cudd_AverageDistance() + <li> Cudd_Random() + <li> Cudd_Srandom() + <li> Cudd_Density() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddP() + <li> cuddStCountfree() + <li> cuddCollectNodes() + <li> cuddNodeArray() + </ul> + Static procedures included in this module: + <ul> + <li> dp2() + <li> ddPrintMintermAux() + <li> ddDagInt() + <li> ddCountMintermAux() + <li> ddEpdCountMintermAux() + <li> ddCountPathAux() + <li> ddSupportStep() + <li> ddClearFlag() + <li> ddLeavesInt() + <li> ddPickArbitraryMinterms() + <li> ddPickRepresentativeCube() + <li> ddEpdFree() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -82,6 +111,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -112,21 +142,25 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddUtil.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddUtil.c,v 1.81 2009/03/08 02:49:02 fabio Exp $"; #endif -static DdNode *background, *zero; +static DdNode *background, *zero; -static long cuddRand = 0; -static long cuddRand2; -static long shuffleSelect; -static long shuffleTable[STAB_SIZE]; +static long cuddRand = 0; +static long cuddRand2; +static long shuffleSelect; +static long shuffleTable[STAB_SIZE]; /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ -#define bang(f) ((Cudd_IsComplement(f)) ? '!' : ' ') +#define bang(f) ((Cudd_IsComplement(f)) ? '!' : ' ') + +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -134,25 +168,29 @@ static long shuffleTable[STAB_SIZE]; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int dp2 ARGS((DdManager *dd, DdNode *f, st_table *t)); -static void ddPrintMintermAux ARGS((DdManager *dd, DdNode *node, int *list)); -static int ddDagInt ARGS((DdNode *n)); -static int cuddEstimateCofactor ARGS((DdManager *dd, st_table *table, DdNode * node, int i, int phase, DdNode ** ptr)); -static DdNode * cuddUniqueLookup ARGS((DdManager * unique, int index, DdNode * T, DdNode * E)); -static int cuddEstimateCofactorSimple ARGS((DdNode * node, int i)); -static double ddCountMintermAux ARGS((DdNode *node, double max, DdHashTable *table)); -static int ddEpdCountMintermAux ARGS((DdNode *node, EpDouble *max, EpDouble *epd, st_table *table)); -static double ddCountPathAux ARGS((DdNode *node, st_table *table)); -static double ddCountPathsToNonZero ARGS((DdNode * N, st_table * table)); -static void ddSupportStep ARGS((DdNode *f, int *support)); -static void ddClearFlag ARGS((DdNode *f)); -static int ddLeavesInt ARGS((DdNode *n)); -static int ddPickArbitraryMinterms ARGS((DdManager *dd, DdNode *node, int nvars, int nminterms, char **string)); -static int ddPickRepresentativeCube ARGS((DdManager *dd, DdNode *node, int nvars, double *weight, char *string)); -static enum st_retval ddEpdFree ARGS((char * key, char * value, char * arg)); +static int dp2 (DdManager *dd, DdNode *f, st_table *t); +static void ddPrintMintermAux (DdManager *dd, DdNode *node, int *list); +static int ddDagInt (DdNode *n); +static int cuddNodeArrayRecur (DdNode *f, DdNodePtr *table, int index); +static int cuddEstimateCofactor (DdManager *dd, st_table *table, DdNode * node, int i, int phase, DdNode ** ptr); +static DdNode * cuddUniqueLookup (DdManager * unique, int index, DdNode * T, DdNode * E); +static int cuddEstimateCofactorSimple (DdNode * node, int i); +static double ddCountMintermAux (DdNode *node, double max, DdHashTable *table); +static int ddEpdCountMintermAux (DdNode *node, EpDouble *max, EpDouble *epd, st_table *table); +static double ddCountPathAux (DdNode *node, st_table *table); +static double ddCountPathsToNonZero (DdNode * N, st_table * table); +static void ddSupportStep (DdNode *f, int *support); +static void ddClearFlag (DdNode *f); +static int ddLeavesInt (DdNode *n); +static int ddPickArbitraryMinterms (DdManager *dd, DdNode *node, int nvars, int nminterms, char **string); +static int ddPickRepresentativeCube (DdManager *dd, DdNode *node, double *weight, char *string); +static enum st_retval ddEpdFree (char * key, char * value, char * arg); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -179,14 +217,14 @@ Cudd_PrintMinterm( DdManager * manager, DdNode * node) { - int i, *list; + int i, *list; background = manager->background; zero = Cudd_Not(manager->one); list = ABC_ALLOC(int,manager->size); if (list == NULL) { - manager->errorCode = CUDD_MEMORY_OUT; - return(0); + manager->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < manager->size; i++) list[i] = 2; ddPrintMintermAux(manager,node,list); @@ -233,71 +271,71 @@ Cudd_bddPrintCover( cuddRef(cover); #endif while (lb != Cudd_ReadLogicZero(dd)) { - DdNode *implicant, *prime, *tmp; - int length; - implicant = Cudd_LargestCube(dd,lb,&length); - if (implicant == NULL) { - Cudd_RecursiveDeref(dd,lb); - ABC_FREE(array); - return(0); - } - cuddRef(implicant); - prime = Cudd_bddMakePrime(dd,implicant,u); - if (prime == NULL) { - Cudd_RecursiveDeref(dd,lb); + DdNode *implicant, *prime, *tmp; + int length; + implicant = Cudd_LargestCube(dd,lb,&length); + if (implicant == NULL) { + Cudd_RecursiveDeref(dd,lb); + ABC_FREE(array); + return(0); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,u); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,implicant); + ABC_FREE(array); + return(0); + } + cuddRef(prime); Cudd_RecursiveDeref(dd,implicant); - ABC_FREE(array); - return(0); - } - cuddRef(prime); - Cudd_RecursiveDeref(dd,implicant); - tmp = Cudd_bddAnd(dd,lb,Cudd_Not(prime)); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,lb); - Cudd_RecursiveDeref(dd,prime); - ABC_FREE(array); - return(0); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,lb); - lb = tmp; - result = Cudd_BddToCubeArray(dd,prime,array); - if (result == 0) { + tmp = Cudd_bddAnd(dd,lb,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + ABC_FREE(array); + return(0); + } + cuddRef(tmp); Cudd_RecursiveDeref(dd,lb); - Cudd_RecursiveDeref(dd,prime); - ABC_FREE(array); - return(0); - } - for (q = 0; q < dd->size; q++) { - switch (array[q]) { - case 0: - (void) fprintf(dd->out, "0"); - break; - case 1: - (void) fprintf(dd->out, "1"); - break; - case 2: - (void) fprintf(dd->out, "-"); - break; - default: - (void) fprintf(dd->out, "?"); + lb = tmp; + result = Cudd_BddToCubeArray(dd,prime,array); + if (result == 0) { + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + ABC_FREE(array); + return(0); } - } - (void) fprintf(dd->out, " 1\n"); + for (q = 0; q < dd->size; q++) { + switch (array[q]) { + case 0: + (void) fprintf(dd->out, "0"); + break; + case 1: + (void) fprintf(dd->out, "1"); + break; + case 2: + (void) fprintf(dd->out, "-"); + break; + default: + (void) fprintf(dd->out, "?"); + } + } + (void) fprintf(dd->out, " 1\n"); #ifdef DD_DEBUG - tmp = Cudd_bddOr(dd,prime,cover); - if (tmp == NULL) { + tmp = Cudd_bddOr(dd,prime,cover); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cover); + Cudd_RecursiveDeref(dd,lb); + Cudd_RecursiveDeref(dd,prime); + ABC_FREE(array); + return(0); + } + cuddRef(tmp); Cudd_RecursiveDeref(dd,cover); - Cudd_RecursiveDeref(dd,lb); - Cudd_RecursiveDeref(dd,prime); - ABC_FREE(array); - return(0); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,cover); - cover = tmp; + cover = tmp; #endif - Cudd_RecursiveDeref(dd,prime); + Cudd_RecursiveDeref(dd,prime); } (void) fprintf(dd->out, "\n"); Cudd_RecursiveDeref(dd,lb); @@ -348,15 +386,15 @@ Cudd_PrintDebug( int pr) { DdNode *azero, *bzero; - int nodes; - int leaves; + int nodes; + int leaves; double minterms; int retval = 1; if (f == NULL) { - (void) fprintf(dd->out,": is the NULL DD\n"); - (void) fflush(dd->out); - return(0); + (void) fprintf(dd->out,": is the NULL DD\n"); + (void) fflush(dd->out); + return(0); } azero = DD_ZERO(dd); bzero = Cudd_Not(DD_ONE(dd)); @@ -366,21 +404,21 @@ Cudd_PrintDebug( return(1); } if (pr > 0) { - nodes = Cudd_DagSize(f); - if (nodes == CUDD_OUT_OF_MEM) retval = 0; - leaves = Cudd_CountLeaves(f); - if (leaves == CUDD_OUT_OF_MEM) retval = 0; - minterms = Cudd_CountMinterm(dd, f, n); - if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; - (void) fprintf(dd->out,": %d nodes %d leaves %g minterms\n", - nodes, leaves, minterms); + nodes = Cudd_DagSize(f); + if (nodes == CUDD_OUT_OF_MEM) retval = 0; + leaves = Cudd_CountLeaves(f); + if (leaves == CUDD_OUT_OF_MEM) retval = 0; + minterms = Cudd_CountMinterm(dd, f, n); + if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; + (void) fprintf(dd->out,": %d nodes %d leaves %g minterms\n", + nodes, leaves, minterms); if (pr > 2) { - if (!cuddP(dd, f)) retval = 0; - } - if (pr == 2 || pr > 3) { - if (!Cudd_PrintMinterm(dd,f)) retval = 0; - (void) fprintf(dd->out,"\n"); - } + if (!cuddP(dd, f)) retval = 0; + } + if (pr == 2 || pr > 3) { + if (!Cudd_PrintMinterm(dd,f)) retval = 0; + (void) fprintf(dd->out,"\n"); + } (void) fflush(dd->out); } return(retval); @@ -404,7 +442,7 @@ int Cudd_DagSize( DdNode * node) { - int i; + int i; i = ddDagInt(Cudd_Regular(node)); ddClearFlag(Cudd_Regular(node)); @@ -426,7 +464,7 @@ Cudd_DagSize( (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 itmay run out of memory. + 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.] @@ -439,15 +477,15 @@ int Cudd_EstimateCofactor( DdManager *dd /* manager */, DdNode * f /* function */, - int i /* index of variable */, - int phase /* 1: positive; 0: negative */ + int i /* index of variable */, + int phase /* 1: positive; 0: negative */ ) { - int val; + int val; DdNode *ptr; st_table *table; - table = st_init_table(st_ptrcmp, st_ptrhash);; + table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) return(CUDD_OUT_OF_MEM); val = cuddEstimateCofactor(dd,table,Cudd_Regular(f),i,phase,&ptr); ddClearFlag(Cudd_Regular(f)); @@ -480,7 +518,7 @@ Cudd_EstimateCofactorSimple( DdNode * node, int i) { - int val; + int val; val = cuddEstimateCofactorSimple(Cudd_Regular(node),i); ddClearFlag(Cudd_Regular(node)); @@ -507,14 +545,14 @@ Cudd_SharingSize( DdNode ** nodeArray, int n) { - int i,j; + int i,j; i = 0; for (j = 0; j < n; j++) { - i += ddDagInt(Cudd_Regular(nodeArray[j])); + i += ddDagInt(Cudd_Regular(nodeArray[j])); } for (j = 0; j < n; j++) { - ddClearFlag(Cudd_Regular(nodeArray[j])); + ddClearFlag(Cudd_Regular(nodeArray[j])); } return(i); @@ -542,18 +580,18 @@ Cudd_CountMinterm( DdNode * node, int nvars) { - double max; - DdHashTable *table; - double res; + double max; + DdHashTable *table; + double res; CUDD_VALUE_TYPE epsilon; background = manager->background; zero = Cudd_Not(manager->one); - + max = pow(2.0,(double)nvars); table = cuddHashTableInit(manager,1,2); if (table == NULL) { - return((double)CUDD_OUT_OF_MEM); + return((double)CUDD_OUT_OF_MEM); } epsilon = Cudd_ReadEpsilon(manager); Cudd_SetEpsilon(manager,(CUDD_VALUE_TYPE)0.0); @@ -587,14 +625,14 @@ Cudd_CountPath( { st_table *table; - double i; + double i; - table = st_init_table(st_ptrcmp, st_ptrhash);; + table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) { - return((double)CUDD_OUT_OF_MEM); + return((double)CUDD_OUT_OF_MEM); } i = ddCountPathAux(Cudd_Regular(node),table); - st_foreach(table, (ST_PFSR)cuddStCountfree, NULL); + st_foreach(table, cuddStCountfree, NULL); st_free_table(table); return(i); @@ -624,23 +662,23 @@ Cudd_EpdCountMinterm( { EpDouble max, tmp; st_table *table; - int status; + int status; background = manager->background; zero = Cudd_Not(manager->one); - + EpdPow2(nvars, &max); table = st_init_table(EpdCmp, st_ptrhash); if (table == NULL) { - EpdMakeZero(epd, 0); - return(CUDD_OUT_OF_MEM); + EpdMakeZero(epd, 0); + return(CUDD_OUT_OF_MEM); } status = ddEpdCountMintermAux(Cudd_Regular(node),&max,epd,table); - st_foreach(table, (ST_PFSR)ddEpdFree, NULL); + st_foreach(table, ddEpdFree, NULL); st_free_table(table); if (status == CUDD_OUT_OF_MEM) { - EpdMakeZero(epd, 0); - return(CUDD_OUT_OF_MEM); + EpdMakeZero(epd, 0); + return(CUDD_OUT_OF_MEM); } if (Cudd_IsComplement(node)) { EpdSubtract3(&max, epd, &tmp); @@ -671,14 +709,14 @@ Cudd_CountPathsToNonZero( { st_table *table; - double i; + double i; - table = st_init_table(st_ptrcmp, st_ptrhash);; + table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) { - return((double)CUDD_OUT_OF_MEM); + return((double)CUDD_OUT_OF_MEM); } i = ddCountPathsToNonZero(node,table); - st_foreach(table, (ST_PFSR)cuddStCountfree, NULL); + st_foreach(table, cuddStCountfree, NULL); st_free_table(table); return(i); @@ -703,20 +741,20 @@ Cudd_Support( DdManager * dd /* manager */, DdNode * f /* DD whose support is sought */) { - int *support; + int *support; DdNode *res, *tmp, *var; - int i,j; + int i,j; int size; /* Allocate and initialize support array for ddSupportStep. */ size = ddMax(dd->size, dd->sizeZ); support = ABC_ALLOC(int,size); if (support == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < size; i++) { - support[i] = 0; + support[i] = 0; } /* Compute support and clean up markers. */ @@ -725,27 +763,30 @@ Cudd_Support( /* Transform support from array to cube. */ do { - dd->reordered = 0; - res = DD_ONE(dd); - cuddRef(res); - for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ - i = (j >= dd->size) ? j : dd->invperm[j]; - if (support[i] == 1) { - var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); - cuddRef(var); - tmp = cuddBddAndRecur(dd,res,var); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,res); - Cudd_RecursiveDeref(dd,var); - res = NULL; - break; - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,res); - Cudd_RecursiveDeref(dd,var); - res = tmp; + dd->reordered = 0; + res = DD_ONE(dd); + cuddRef(res); + for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ + i = (j >= dd->size) ? j : dd->invperm[j]; + if (support[i] == 1) { + /* The following call to cuddUniqueInter is guaranteed + ** not to trigger reordering because the node we look up + ** already exists. */ + var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + cuddRef(var); + tmp = cuddBddAndRecur(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + res = NULL; + break; + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + res = tmp; + } } - } } while (dd->reordered == 1); ABC_FREE(support); @@ -759,8 +800,11 @@ Cudd_Support( 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.] + 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] @@ -772,19 +816,19 @@ Cudd_SupportIndex( DdManager * dd /* manager */, DdNode * f /* DD whose support is sought */) { - int *support; - int i; + int *support; + int i; int size; /* Allocate and initialize support array for ddSupportStep. */ size = ddMax(dd->size, dd->sizeZ); support = ABC_ALLOC(int,size); if (support == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < size; i++) { - support[i] = 0; + support[i] = 0; } /* Compute support and clean up markers. */ @@ -814,8 +858,8 @@ Cudd_SupportSize( DdManager * dd /* manager */, DdNode * f /* DD whose support size is sought */) { - int *support; - int i; + int *support; + int i; int size; int count; @@ -823,11 +867,11 @@ Cudd_SupportSize( size = ddMax(dd->size, dd->sizeZ); support = ABC_ALLOC(int,size); if (support == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); } for (i = 0; i < size; i++) { - support[i] = 0; + support[i] = 0; } /* Compute support and clean up markers. */ @@ -837,7 +881,7 @@ Cudd_SupportSize( /* Count support variables. */ count = 0; for (i = 0; i < size; i++) { - if (support[i] == 1) count++; + if (support[i] == 1) count++; } ABC_FREE(support); @@ -866,50 +910,50 @@ Cudd_VectorSupport( DdNode ** F /* array of DDs whose support is sought */, int n /* size of the array */) { - int *support; + int *support; DdNode *res, *tmp, *var; - int i,j; + int i,j; int size; /* Allocate and initialize support array for ddSupportStep. */ size = ddMax(dd->size, dd->sizeZ); support = ABC_ALLOC(int,size); if (support == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < size; i++) { - support[i] = 0; + support[i] = 0; } /* Compute support and clean up markers. */ for (i = 0; i < n; i++) { - ddSupportStep(Cudd_Regular(F[i]),support); + ddSupportStep(Cudd_Regular(F[i]),support); } for (i = 0; i < n; i++) { - ddClearFlag(Cudd_Regular(F[i])); + ddClearFlag(Cudd_Regular(F[i])); } /* Transform support from array to cube. */ res = DD_ONE(dd); cuddRef(res); for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ - i = (j >= dd->size) ? j : dd->invperm[j]; - if (support[i] == 1) { - var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); - cuddRef(var); - tmp = Cudd_bddAnd(dd,res,var); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,res); - Cudd_RecursiveDeref(dd,var); - ABC_FREE(support); - return(NULL); + i = (j >= dd->size) ? j : dd->invperm[j]; + if (support[i] == 1) { + var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + cuddRef(var); + tmp = Cudd_bddAnd(dd,res,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + ABC_FREE(support); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,res); + Cudd_RecursiveDeref(dd,var); + res = tmp; } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,res); - Cudd_RecursiveDeref(dd,var); - res = tmp; - } } ABC_FREE(support); @@ -938,27 +982,27 @@ Cudd_VectorSupportIndex( DdNode ** F /* array of DDs whose support is sought */, int n /* size of the array */) { - int *support; - int i; + int *support; + int i; int size; /* Allocate and initialize support array for ddSupportStep. */ size = ddMax(dd->size, dd->sizeZ); support = ABC_ALLOC(int,size); if (support == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < size; i++) { - support[i] = 0; + support[i] = 0; } /* Compute support and clean up markers. */ for (i = 0; i < n; i++) { - ddSupportStep(Cudd_Regular(F[i]),support); + ddSupportStep(Cudd_Regular(F[i]),support); } for (i = 0; i < n; i++) { - ddClearFlag(Cudd_Regular(F[i])); + ddClearFlag(Cudd_Regular(F[i])); } return(support); @@ -986,8 +1030,8 @@ Cudd_VectorSupportSize( DdNode ** F /* array of DDs whose support is sought */, int n /* size of the array */) { - int *support; - int i; + int *support; + int i; int size; int count; @@ -995,25 +1039,25 @@ Cudd_VectorSupportSize( size = ddMax(dd->size, dd->sizeZ); support = ABC_ALLOC(int,size); if (support == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(CUDD_OUT_OF_MEM); + dd->errorCode = CUDD_MEMORY_OUT; + return(CUDD_OUT_OF_MEM); } for (i = 0; i < size; i++) { - support[i] = 0; + support[i] = 0; } /* Compute support and clean up markers. */ for (i = 0; i < n; i++) { - ddSupportStep(Cudd_Regular(F[i]),support); + ddSupportStep(Cudd_Regular(F[i]),support); } for (i = 0; i < n; i++) { - ddClearFlag(Cudd_Regular(F[i])); + ddClearFlag(Cudd_Regular(F[i])); } /* Count vriables in support. */ count = 0; for (i = 0; i < size; i++) { - if (support[i] == 1) count++; + if (support[i] == 1) count++; } ABC_FREE(support); @@ -1046,27 +1090,27 @@ Cudd_ClassifySupport( DdNode ** onlyF /* cube of variables only in f */, DdNode ** onlyG /* cube of variables only in g */) { - int *supportF, *supportG; + int *supportF, *supportG; DdNode *tmp, *var; - int i,j; + int i,j; int size; /* Allocate and initialize support arrays for ddSupportStep. */ size = ddMax(dd->size, dd->sizeZ); supportF = ABC_ALLOC(int,size); if (supportF == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + return(0); } supportG = ABC_ALLOC(int,size); if (supportG == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(supportF); - return(0); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(supportF); + return(0); } for (i = 0; i < size; i++) { - supportF[i] = 0; - supportG[i] = 0; + supportF[i] = 0; + supportG[i] = 0; } /* Compute supports and clean up markers. */ @@ -1079,51 +1123,51 @@ Cudd_ClassifySupport( *common = *onlyF = *onlyG = DD_ONE(dd); cuddRef(*common); cuddRef(*onlyF); cuddRef(*onlyG); for (j = size - 1; j >= 0; j--) { /* for each level bottom-up */ - i = (j >= dd->size) ? j : dd->invperm[j]; - if (supportF[i] == 0 && supportG[i] == 0) continue; - var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); - cuddRef(var); - if (supportG[i] == 0) { - tmp = Cudd_bddAnd(dd,*onlyF,var); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,*common); - Cudd_RecursiveDeref(dd,*onlyF); - Cudd_RecursiveDeref(dd,*onlyG); - Cudd_RecursiveDeref(dd,var); - ABC_FREE(supportF); ABC_FREE(supportG); - return(0); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,*onlyF); - *onlyF = tmp; - } else if (supportF[i] == 0) { - tmp = Cudd_bddAnd(dd,*onlyG,var); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,*common); - Cudd_RecursiveDeref(dd,*onlyF); - Cudd_RecursiveDeref(dd,*onlyG); - Cudd_RecursiveDeref(dd,var); - ABC_FREE(supportF); ABC_FREE(supportG); - return(0); + i = (j >= dd->size) ? j : dd->invperm[j]; + if (supportF[i] == 0 && supportG[i] == 0) continue; + var = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one)); + cuddRef(var); + if (supportG[i] == 0) { + tmp = Cudd_bddAnd(dd,*onlyF,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + Cudd_RecursiveDeref(dd,var); + ABC_FREE(supportF); ABC_FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*onlyF); + *onlyF = tmp; + } else if (supportF[i] == 0) { + tmp = Cudd_bddAnd(dd,*onlyG,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + Cudd_RecursiveDeref(dd,var); + ABC_FREE(supportF); ABC_FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*onlyG); + *onlyG = tmp; + } else { + tmp = Cudd_bddAnd(dd,*common,var); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,*common); + Cudd_RecursiveDeref(dd,*onlyF); + Cudd_RecursiveDeref(dd,*onlyG); + Cudd_RecursiveDeref(dd,var); + ABC_FREE(supportF); ABC_FREE(supportG); + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,*common); + *common = tmp; } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,*onlyG); - *onlyG = tmp; - } else { - tmp = Cudd_bddAnd(dd,*common,var); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,*common); - Cudd_RecursiveDeref(dd,*onlyF); - Cudd_RecursiveDeref(dd,*onlyG); Cudd_RecursiveDeref(dd,var); - ABC_FREE(supportF); ABC_FREE(supportG); - return(0); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,*common); - *common = tmp; - } - Cudd_RecursiveDeref(dd,var); } ABC_FREE(supportF); ABC_FREE(supportG); @@ -1150,7 +1194,7 @@ int Cudd_CountLeaves( DdNode * node) { - int i; + int i; i = ddLeavesInt(Cudd_Regular(node)); ddClearFlag(Cudd_Regular(node)); @@ -1195,25 +1239,25 @@ Cudd_bddPickOneCube( for (;;) { - if (node == one) break; + if (node == one) break; - N = Cudd_Regular(node); + N = Cudd_Regular(node); - T = cuddT(N); E = cuddE(N); - if (Cudd_IsComplement(node)) { - T = Cudd_Not(T); E = Cudd_Not(E); - } - if (T == bzero) { - string[N->index] = 0; - node = E; - } else if (E == bzero) { - string[N->index] = 1; - node = T; - } else { - dir = (char) ((Cudd_Random() & 0x2000) >> 13); - string[N->index] = dir; - node = dir ? T : E; - } + T = cuddT(N); E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); E = Cudd_Not(E); + } + if (T == bzero) { + string[N->index] = 0; + node = E; + } else if (E == bzero) { + string[N->index] = 1; + node = T; + } else { + dir = (char) ((Cudd_Random() & 0x2000) >> 13); + string[N->index] = dir; + node = dir ? T : E; + } } return(1); @@ -1259,14 +1303,14 @@ Cudd_bddPickOneMinterm( size = dd->size; string = ABC_ALLOC(char, size); if (string == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } indices = ABC_ALLOC(int,n); if (indices == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(string); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(string); + return(NULL); } for (i = 0; i < n; i++) { @@ -1275,15 +1319,15 @@ Cudd_bddPickOneMinterm( result = Cudd_bddPickOneCube(dd,f,string); if (result == 0) { - ABC_FREE(string); - ABC_FREE(indices); - return(NULL); + ABC_FREE(string); + ABC_FREE(indices); + return(NULL); } /* Randomize choice for don't cares. */ for (i = 0; i < n; i++) { - if (string[indices[i]] == 2) - string[indices[i]] = (char) ((Cudd_Random() & 0x20) >> 5); + if (string[indices[i]] == 2) + string[indices[i]] = (char) ((Cudd_Random() & 0x20) >> 5); } /* Build result BDD. */ @@ -1291,25 +1335,25 @@ Cudd_bddPickOneMinterm( cuddRef(old); for (i = n-1; i >= 0; i--) { - neW = Cudd_bddAnd(dd,old,Cudd_NotCond(vars[i],string[indices[i]]==0)); - if (neW == NULL) { - ABC_FREE(string); - ABC_FREE(indices); + neW = Cudd_bddAnd(dd,old,Cudd_NotCond(vars[i],string[indices[i]]==0)); + if (neW == NULL) { + ABC_FREE(string); + ABC_FREE(indices); + Cudd_RecursiveDeref(dd,old); + return(NULL); + } + cuddRef(neW); Cudd_RecursiveDeref(dd,old); - return(NULL); - } - cuddRef(neW); - Cudd_RecursiveDeref(dd,old); - old = neW; + old = neW; } #ifdef DD_DEBUG /* Test. */ if (Cudd_bddLeq(dd,old,f)) { - cuddDeref(old); + cuddDeref(old); } else { - Cudd_RecursiveDeref(dd,old); - old = NULL; + Cudd_RecursiveDeref(dd,old); + old = NULL; } #else cuddDeref(old); @@ -1360,39 +1404,38 @@ Cudd_bddPickArbitraryMinterms( DdNode **old, *neW; double minterms; char *saveString; - int saveFlag, isSame; - int savePoint = 0; // Suppress "might be used uninitialized" + int saveFlag, savePoint, isSame; minterms = Cudd_CountMinterm(dd,f,n); if ((double)k > minterms) { - return(NULL); + return(NULL); } size = dd->size; string = ABC_ALLOC(char *, k); if (string == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); - } - for (i = 0; i < k; i++) { - string[i] = ABC_ALLOC(char, size + 1); - if (string[i] == NULL) { - for (j = 0; j < i; j++) - ABC_FREE(string[i]); - ABC_FREE(string); dd->errorCode = CUDD_MEMORY_OUT; return(NULL); } - for (j = 0; j < size; j++) string[i][j] = '2'; - string[i][size] = '\0'; + for (i = 0; i < k; i++) { + string[i] = ABC_ALLOC(char, size + 1); + if (string[i] == NULL) { + for (j = 0; j < i; j++) + ABC_FREE(string[i]); + ABC_FREE(string); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + for (j = 0; j < size; j++) string[i][j] = '2'; + string[i][size] = '\0'; } indices = ABC_ALLOC(int,n); if (indices == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - for (i = 0; i < k; i++) - ABC_FREE(string[i]); - ABC_FREE(string); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + ABC_FREE(string[i]); + ABC_FREE(string); + return(NULL); } for (i = 0; i < n; i++) { @@ -1401,129 +1444,130 @@ Cudd_bddPickArbitraryMinterms( result = ddPickArbitraryMinterms(dd,f,n,k,string); if (result == 0) { - for (i = 0; i < k; i++) - ABC_FREE(string[i]); - ABC_FREE(string); - ABC_FREE(indices); - return(NULL); + for (i = 0; i < k; i++) + ABC_FREE(string[i]); + ABC_FREE(string); + ABC_FREE(indices); + return(NULL); } old = ABC_ALLOC(DdNode *, k); if (old == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - for (i = 0; i < k; i++) - ABC_FREE(string[i]); - ABC_FREE(string); - ABC_FREE(indices); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + ABC_FREE(string[i]); + ABC_FREE(string); + ABC_FREE(indices); + return(NULL); } saveString = ABC_ALLOC(char, size + 1); if (saveString == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - for (i = 0; i < k; i++) - ABC_FREE(string[i]); - ABC_FREE(string); - ABC_FREE(indices); - ABC_FREE(old); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + for (i = 0; i < k; i++) + ABC_FREE(string[i]); + ABC_FREE(string); + ABC_FREE(indices); + ABC_FREE(old); + return(NULL); } saveFlag = 0; /* Build result BDD array. */ for (i = 0; i < k; i++) { - isSame = 0; - if (!saveFlag) { - for (j = i + 1; j < k; j++) { - if (strcmp(string[i], string[j]) == 0) { - savePoint = i; - strcpy(saveString, string[i]); - saveFlag = 1; - break; - } - } - } else { - if (strcmp(string[i], saveString) == 0) { - isSame = 1; + isSame = 0; + if (!saveFlag) { + for (j = i + 1; j < k; j++) { + if (strcmp(string[i], string[j]) == 0) { + savePoint = i; + strcpy(saveString, string[i]); + saveFlag = 1; + break; + } + } } else { - saveFlag = 0; - for (j = i + 1; j < k; j++) { - if (strcmp(string[i], string[j]) == 0) { - savePoint = i; - strcpy(saveString, string[i]); - saveFlag = 1; - break; + if (strcmp(string[i], saveString) == 0) { + isSame = 1; + } else { + saveFlag = 0; + for (j = i + 1; j < k; j++) { + if (strcmp(string[i], string[j]) == 0) { + savePoint = i; + strcpy(saveString, string[i]); + saveFlag = 1; + break; + } + } } } - } - } - /* Randomize choice for don't cares. */ - for (j = 0; j < n; j++) { - if (string[i][indices[j]] == '2') - string[i][indices[j]] = (Cudd_Random() & 0x20) ? '1' : '0'; - } - - while (isSame) { - isSame = 0; - for (j = savePoint; j < i; j++) { - if (strcmp(string[i], string[j]) == 0) { - isSame = 1; - break; - } - } - if (isSame) { - strcpy(string[i], saveString); /* Randomize choice for don't cares. */ for (j = 0; j < n; j++) { - if (string[i][indices[j]] == '2') - string[i][indices[j]] = (Cudd_Random() & 0x20) ? - '1' : '0'; + if (string[i][indices[j]] == '2') + string[i][indices[j]] = + (char) ((Cudd_Random() & 0x20) ? '1' : '0'); } + + while (isSame) { + isSame = 0; + for (j = savePoint; j < i; j++) { + if (strcmp(string[i], string[j]) == 0) { + isSame = 1; + break; + } + } + if (isSame) { + strcpy(string[i], saveString); + /* Randomize choice for don't cares. */ + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '2') + string[i][indices[j]] = + (char) ((Cudd_Random() & 0x20) ? '1' : '0'); + } + } } - } - old[i] = Cudd_ReadOne(dd); - cuddRef(old[i]); + old[i] = Cudd_ReadOne(dd); + cuddRef(old[i]); - for (j = 0; j < n; j++) { - if (string[i][indices[j]] == '0') { - neW = Cudd_bddAnd(dd,old[i],Cudd_Not(vars[j])); - } else { - neW = Cudd_bddAnd(dd,old[i],vars[j]); - } - if (neW == NULL) { - ABC_FREE(saveString); - for (l = 0; l < k; l++) - ABC_FREE(string[l]); - ABC_FREE(string); - ABC_FREE(indices); - for (l = 0; l <= i; l++) - Cudd_RecursiveDeref(dd,old[l]); - ABC_FREE(old); - return(NULL); + for (j = 0; j < n; j++) { + if (string[i][indices[j]] == '0') { + neW = Cudd_bddAnd(dd,old[i],Cudd_Not(vars[j])); + } else { + neW = Cudd_bddAnd(dd,old[i],vars[j]); + } + if (neW == NULL) { + ABC_FREE(saveString); + for (l = 0; l < k; l++) + ABC_FREE(string[l]); + ABC_FREE(string); + ABC_FREE(indices); + for (l = 0; l <= i; l++) + Cudd_RecursiveDeref(dd,old[l]); + ABC_FREE(old); + return(NULL); + } + cuddRef(neW); + Cudd_RecursiveDeref(dd,old[i]); + old[i] = neW; } - cuddRef(neW); - Cudd_RecursiveDeref(dd,old[i]); - old[i] = neW; - } - /* Test. */ - if (!Cudd_bddLeq(dd,old[i],f)) { - ABC_FREE(saveString); - for (l = 0; l < k; l++) - ABC_FREE(string[l]); - ABC_FREE(string); - ABC_FREE(indices); - for (l = 0; l <= i; l++) - Cudd_RecursiveDeref(dd,old[l]); - ABC_FREE(old); - return(NULL); - } + /* Test. */ + if (!Cudd_bddLeq(dd,old[i],f)) { + ABC_FREE(saveString); + for (l = 0; l < k; l++) + ABC_FREE(string[l]); + ABC_FREE(string); + ABC_FREE(indices); + for (l = 0; l <= i; l++) + Cudd_RecursiveDeref(dd,old[l]); + ABC_FREE(old); + return(NULL); + } } ABC_FREE(saveString); for (i = 0; i < k; i++) { - cuddDeref(old[i]); - ABC_FREE(string[i]); + cuddDeref(old[i]); + ABC_FREE(string[i]); } ABC_FREE(string); ABC_FREE(indices); @@ -1563,114 +1607,119 @@ Cudd_SubsetWithMaskVars( DdNode ** maskVars /* array of variables */, int mvars /* size of <code>maskVars</code> */) { - double *weight; - char *string; - int i, size; - int *indices, *mask; - int result; - DdNode *zero, *cube, *newCube, *subset; - DdNode *cof; - - DdNode *support; + double *weight; + char *string; + int i, size; + int *indices, *mask; + int result; + DdNode *zero, *cube, *newCube, *subset; + DdNode *cof; + + DdNode *support; support = Cudd_Support(dd,f); cuddRef(support); Cudd_RecursiveDeref(dd,support); zero = Cudd_Not(dd->one); size = dd->size; - + weight = ABC_ALLOC(double,size); if (weight == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } for (i = 0; i < size; i++) { weight[i] = 0.0; } for (i = 0; i < mvars; i++) { - cof = Cudd_Cofactor(dd, f, maskVars[i]); - cuddRef(cof); - weight[i] = Cudd_CountMinterm(dd, cof, nvars); - Cudd_RecursiveDeref(dd,cof); + cof = Cudd_Cofactor(dd, f, maskVars[i]); + cuddRef(cof); + weight[i] = Cudd_CountMinterm(dd, cof, nvars); + Cudd_RecursiveDeref(dd,cof); - cof = Cudd_Cofactor(dd, f, Cudd_Not(maskVars[i])); - cuddRef(cof); - weight[i] -= Cudd_CountMinterm(dd, cof, nvars); - Cudd_RecursiveDeref(dd,cof); + cof = Cudd_Cofactor(dd, f, Cudd_Not(maskVars[i])); + cuddRef(cof); + weight[i] -= Cudd_CountMinterm(dd, cof, nvars); + Cudd_RecursiveDeref(dd,cof); } string = ABC_ALLOC(char, size + 1); if (string == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(weight); + return(NULL); } mask = ABC_ALLOC(int, size); if (mask == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(string); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(weight); + ABC_FREE(string); + return(NULL); } for (i = 0; i < size; i++) { - string[i] = '2'; - mask[i] = 0; + string[i] = '2'; + mask[i] = 0; } string[size] = '\0'; indices = ABC_ALLOC(int,nvars); if (indices == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(string); - ABC_FREE(mask); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(weight); + ABC_FREE(string); + ABC_FREE(mask); + return(NULL); } for (i = 0; i < nvars; i++) { indices[i] = vars[i]->index; } - result = ddPickRepresentativeCube(dd,f,nvars,weight,string); + result = ddPickRepresentativeCube(dd,f,weight,string); if (result == 0) { - ABC_FREE(string); - ABC_FREE(mask); - ABC_FREE(indices); - return(NULL); + ABC_FREE(weight); + ABC_FREE(string); + ABC_FREE(mask); + ABC_FREE(indices); + return(NULL); } cube = Cudd_ReadOne(dd); cuddRef(cube); zero = Cudd_Not(Cudd_ReadOne(dd)); for (i = 0; i < nvars; i++) { - if (string[indices[i]] == '0') { - newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); - } else if (string[indices[i]] == '1') { - newCube = Cudd_bddIte(dd,cube,vars[i],zero); - } else - continue; - if (newCube == NULL) { - ABC_FREE(string); - ABC_FREE(mask); - ABC_FREE(indices); + if (string[indices[i]] == '0') { + newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); + } else if (string[indices[i]] == '1') { + newCube = Cudd_bddIte(dd,cube,vars[i],zero); + } else + continue; + if (newCube == NULL) { + ABC_FREE(weight); + ABC_FREE(string); + ABC_FREE(mask); + ABC_FREE(indices); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(newCube); Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(newCube); - Cudd_RecursiveDeref(dd,cube); - cube = newCube; + cube = newCube; } Cudd_RecursiveDeref(dd,cube); for (i = 0; i < mvars; i++) { - mask[maskVars[i]->index] = 1; + mask[maskVars[i]->index] = 1; } for (i = 0; i < nvars; i++) { - if (mask[indices[i]]) { - if (string[indices[i]] == '2') { - if (weight[indices[i]] >= 0.0) - string[indices[i]] = '1'; - else - string[indices[i]] = '0'; + if (mask[indices[i]]) { + if (string[indices[i]] == '2') { + if (weight[indices[i]] >= 0.0) + string[indices[i]] = '1'; + else + string[indices[i]] = '0'; + } + } else { + string[indices[i]] = '2'; } - } else { - string[indices[i]] = '2'; - } } cube = Cudd_ReadOne(dd); @@ -1679,22 +1728,23 @@ Cudd_SubsetWithMaskVars( /* Build result BDD. */ for (i = 0; i < nvars; i++) { - if (string[indices[i]] == '0') { - newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); - } else if (string[indices[i]] == '1') { - newCube = Cudd_bddIte(dd,cube,vars[i],zero); - } else - continue; - if (newCube == NULL) { - ABC_FREE(string); - ABC_FREE(mask); - ABC_FREE(indices); + if (string[indices[i]] == '0') { + newCube = Cudd_bddIte(dd,cube,Cudd_Not(vars[i]),zero); + } else if (string[indices[i]] == '1') { + newCube = Cudd_bddIte(dd,cube,vars[i],zero); + } else + continue; + if (newCube == NULL) { + ABC_FREE(weight); + ABC_FREE(string); + ABC_FREE(mask); + ABC_FREE(indices); + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(newCube); Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(newCube); - Cudd_RecursiveDeref(dd,cube); - cube = newCube; + cube = newCube; } subset = Cudd_bddAnd(dd,f,cube); @@ -1703,16 +1753,16 @@ Cudd_SubsetWithMaskVars( /* Test. */ if (Cudd_bddLeq(dd,subset,f)) { - cuddDeref(subset); + cuddDeref(subset); } else { - Cudd_RecursiveDeref(dd,subset); - subset = NULL; + Cudd_RecursiveDeref(dd,subset); + subset = NULL; } + ABC_FREE(weight); ABC_FREE(string); ABC_FREE(mask); ABC_FREE(indices); - ABC_FREE(weight); return(subset); } /* end of Cudd_SubsetWithMaskVars */ @@ -1762,8 +1812,8 @@ Cudd_FirstCube( /* Allocate generator an initialize it. */ gen = ABC_ALLOC(DdGen,1); if (gen == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } gen->manager = dd; @@ -1778,9 +1828,9 @@ Cudd_FirstCube( nvars = dd->size; gen->gen.cubes.cube = ABC_ALLOC(int,nvars); if (gen->gen.cubes.cube == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(gen); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(gen); + return(NULL); } for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; @@ -1788,12 +1838,12 @@ Cudd_FirstCube( ** because a path may have nodes at all levels, including the ** constant level. */ - gen->stack.stack = ABC_ALLOC(DdNode *, nvars+1); + gen->stack.stack = ABC_ALLOC(DdNodePtr, nvars+1); if (gen->stack.stack == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(gen->gen.cubes.cube); - ABC_FREE(gen); - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(gen->gen.cubes.cube); + ABC_FREE(gen); + return(NULL); } for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; @@ -1801,43 +1851,43 @@ Cudd_FirstCube( gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; while (1) { - top = gen->stack.stack[gen->stack.sp-1]; - treg = Cudd_Regular(top); - if (!cuddIsConstant(treg)) { - /* Take the else branch first. */ - gen->gen.cubes.cube[treg->index] = 0; - next = cuddE(treg); - if (top != treg) next = Cudd_Not(next); - gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; - } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { - /* Backtrack */ - while (1) { - if (gen->stack.sp == 1) { - /* The current node has no predecessor. */ - gen->status = CUDD_GEN_EMPTY; - gen->stack.sp--; - goto done; - } - prev = gen->stack.stack[gen->stack.sp-2]; - preg = Cudd_Regular(prev); - nreg = cuddT(preg); - if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} - if (next != top) { /* follow the then branch next */ - gen->gen.cubes.cube[preg->index] = 1; - gen->stack.stack[gen->stack.sp-1] = next; - break; - } - /* Pop the stack and try again. */ - gen->gen.cubes.cube[preg->index] = 2; - gen->stack.sp--; top = gen->stack.stack[gen->stack.sp-1]; treg = Cudd_Regular(top); + if (!cuddIsConstant(treg)) { + /* Take the else branch first. */ + gen->gen.cubes.cube[treg->index] = 0; + next = cuddE(treg); + if (top != treg) next = Cudd_Not(next); + gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; + } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { + /* Backtrack */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(top); + goto done; } - } else { - gen->status = CUDD_GEN_NONEMPTY; - gen->gen.cubes.value = cuddV(top); - goto done; - } } done: @@ -1874,46 +1924,14 @@ Cudd_NextCube( /* Backtrack from previously reached terminal node. */ while (1) { - if (gen->stack.sp == 1) { - /* The current node has no predecessor. */ - gen->status = CUDD_GEN_EMPTY; - gen->stack.sp--; - goto done; - } - top = gen->stack.stack[gen->stack.sp-1]; - treg = Cudd_Regular(top); - prev = gen->stack.stack[gen->stack.sp-2]; - preg = Cudd_Regular(prev); - nreg = cuddT(preg); - if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} - if (next != top) { /* follow the then branch next */ - gen->gen.cubes.cube[preg->index] = 1; - gen->stack.stack[gen->stack.sp-1] = next; - break; - } - /* Pop the stack and try again. */ - gen->gen.cubes.cube[preg->index] = 2; - gen->stack.sp--; - } - - while (1) { - top = gen->stack.stack[gen->stack.sp-1]; - treg = Cudd_Regular(top); - if (!cuddIsConstant(treg)) { - /* Take the else branch first. */ - gen->gen.cubes.cube[treg->index] = 0; - next = cuddE(treg); - if (top != treg) next = Cudd_Not(next); - gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; - } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { - /* Backtrack */ - while (1) { if (gen->stack.sp == 1) { /* The current node has no predecessor. */ gen->status = CUDD_GEN_EMPTY; gen->stack.sp--; goto done; } + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); prev = gen->stack.stack[gen->stack.sp-2]; preg = Cudd_Regular(prev); nreg = cuddT(preg); @@ -1926,14 +1944,46 @@ Cudd_NextCube( /* Pop the stack and try again. */ gen->gen.cubes.cube[preg->index] = 2; gen->stack.sp--; + } + + while (1) { top = gen->stack.stack[gen->stack.sp-1]; treg = Cudd_Regular(top); + if (!cuddIsConstant(treg)) { + /* Take the else branch first. */ + gen->gen.cubes.cube[treg->index] = 0; + next = cuddE(treg); + if (top != treg) next = Cudd_Not(next); + gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; + } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) { + /* Backtrack */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = gen->stack.stack[gen->stack.sp-2]; + preg = Cudd_Regular(prev); + nreg = cuddT(preg); + if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;} + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[preg->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[preg->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + treg = Cudd_Regular(top); + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(top); + goto done; } - } else { - gen->status = CUDD_GEN_NONEMPTY; - gen->gen.cubes.value = cuddV(top); - goto done; - } } done: @@ -1947,6 +1997,188 @@ done: /**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.<p> + + 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.<p> + + 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.<p> + + 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] + +******************************************************************************/ +DdGen * +Cudd_FirstPrime( + DdManager *dd, + DdNode *l, + DdNode *u, + int **cube) +{ + DdGen *gen; + DdNode *implicant, *prime, *tmp; + int length, result; + + /* Sanity Check. */ + if (dd == NULL || l == NULL || u == NULL) return(NULL); + + /* Allocate generator an initialize it. */ + gen = ABC_ALLOC(DdGen,1); + if (gen == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); + } + + gen->manager = dd; + gen->type = CUDD_GEN_PRIMES; + gen->status = CUDD_GEN_EMPTY; + gen->gen.primes.cube = NULL; + gen->gen.primes.ub = u; + gen->stack.sp = 0; + gen->stack.stack = NULL; + gen->node = l; + cuddRef(l); + + gen->gen.primes.cube = ABC_ALLOC(int,dd->size); + if (gen->gen.primes.cube == NULL) { + dd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(gen); + return(NULL); + } + + if (gen->node == Cudd_ReadLogicZero(dd)) { + gen->status = CUDD_GEN_EMPTY; + } else { + implicant = Cudd_LargestCube(dd,gen->node,&length); + if (implicant == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + ABC_FREE(gen->gen.primes.cube); + ABC_FREE(gen); + return(NULL); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,implicant); + ABC_FREE(gen->gen.primes.cube); + ABC_FREE(gen); + return(NULL); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,prime); + ABC_FREE(gen->gen.primes.cube); + ABC_FREE(gen); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,gen->node); + gen->node = tmp; + result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); + if (result == 0) { + Cudd_RecursiveDeref(dd,gen->node); + Cudd_RecursiveDeref(dd,prime); + ABC_FREE(gen->gen.primes.cube); + ABC_FREE(gen); + return(NULL); + } + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_NONEMPTY; + } + *cube = gen->gen.primes.cube; + return(gen); + +} /* end of Cudd_FirstPrime */ + + +/**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] + +******************************************************************************/ +int +Cudd_NextPrime( + DdGen *gen, + int **cube) +{ + DdNode *implicant, *prime, *tmp; + DdManager *dd = gen->manager; + int length, result; + + if (gen->node == Cudd_ReadLogicZero(dd)) { + gen->status = CUDD_GEN_EMPTY; + } else { + implicant = Cudd_LargestCube(dd,gen->node,&length); + if (implicant == NULL) { + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(implicant); + prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub); + if (prime == NULL) { + Cudd_RecursiveDeref(dd,implicant); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(prime); + Cudd_RecursiveDeref(dd,implicant); + tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,gen->node); + gen->node = tmp; + result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube); + if (result == 0) { + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_EMPTY; + return(0); + } + Cudd_RecursiveDeref(dd,prime); + gen->status = CUDD_GEN_NONEMPTY; + } + if (gen->status == CUDD_GEN_EMPTY) return(0); + *cube = gen->gen.primes.cube; + return(1); + +} /* end of Cudd_NextPrime */ + + +/**Function******************************************************************** + Synopsis [Computes the cube of an array of BDD variables.] Description [Computes the cube of an array of BDD variables. If @@ -1967,26 +2199,26 @@ Cudd_bddComputeCube( int * phase, int n) { - DdNode *cube; - DdNode *fn; + DdNode *cube; + DdNode *fn; int i; cube = DD_ONE(dd); cuddRef(cube); for (i = n - 1; i >= 0; i--) { - if (phase == NULL || phase[i] != 0) { - fn = Cudd_bddAnd(dd,vars[i],cube); - } else { - fn = Cudd_bddAnd(dd,Cudd_Not(vars[i]),cube); - } - if (fn == NULL) { + if (phase == NULL || phase[i] != 0) { + fn = Cudd_bddAnd(dd,vars[i],cube); + } else { + fn = Cudd_bddAnd(dd,Cudd_Not(vars[i]),cube); + } + if (fn == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(fn); Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(fn); - Cudd_RecursiveDeref(dd,cube); - cube = fn; + cube = fn; } cuddDeref(cube); @@ -2017,8 +2249,8 @@ Cudd_addComputeCube( int * phase, int n) { - DdNode *cube, *zero; - DdNode *fn; + DdNode *cube, *zero; + DdNode *fn; int i; cube = DD_ONE(dd); @@ -2026,18 +2258,18 @@ Cudd_addComputeCube( zero = DD_ZERO(dd); for (i = n - 1; i >= 0; i--) { - if (phase == NULL || phase[i] != 0) { - fn = Cudd_addIte(dd,vars[i],cube,zero); - } else { - fn = Cudd_addIte(dd,vars[i],zero,cube); - } - if (fn == NULL) { + if (phase == NULL || phase[i] != 0) { + fn = Cudd_addIte(dd,vars[i],cube,zero); + } else { + fn = Cudd_addIte(dd,vars[i],zero,cube); + } + if (fn == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(fn); Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(fn); - Cudd_RecursiveDeref(dd,cube); - cube = fn; + cube = fn; } cuddDeref(cube); @@ -2074,17 +2306,17 @@ Cudd_CubeArrayToBdd( cube = DD_ONE(dd); cuddRef(cube); for (i = size - 1; i >= 0; i--) { - if ((array[i] & ~1) == 0) { - var = Cudd_bddIthVar(dd,i); - tmp = Cudd_bddAnd(dd,cube,Cudd_NotCond(var,array[i]==0)); - if (tmp == NULL) { - Cudd_RecursiveDeref(dd,cube); - return(NULL); + if ((array[i] & ~1) == 0) { + var = Cudd_bddIthVar(dd,i); + tmp = Cudd_bddAnd(dd,cube,Cudd_NotCond(var,array[i]==0)); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmp); + Cudd_RecursiveDeref(dd,cube); + cube = tmp; } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,cube); - cube = tmp; - } } cuddDeref(cube); return(cube); @@ -2122,26 +2354,26 @@ Cudd_BddToCubeArray( DdNode *zero = Cudd_Not(DD_ONE(dd)); for (i = size-1; i >= 0; i--) { - array[i] = 2; + array[i] = 2; } scan = cube; while (!Cudd_IsConstant(scan)) { - int index = Cudd_Regular(scan)->index; - cuddGetBranches(scan,&t,&e); - if (t == zero) { - array[index] = 0; - scan = e; - } else if (e == zero) { - array[index] = 1; - scan = t; - } else { - return(0); /* cube is not a cube */ - } + int index = Cudd_Regular(scan)->index; + cuddGetBranches(scan,&t,&e); + if (t == zero) { + array[index] = 0; + scan = e; + } else if (e == zero) { + array[index] = 1; + scan = t; + } else { + return(0); /* cube is not a cube */ + } } if (scan == zero) { - return(0); + return(0); } else { - return(1); + return(1); } } /* end of Cudd_BddToCubeArray */ @@ -2153,8 +2385,10 @@ Cudd_BddToCubeArray( 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.] + 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.] @@ -2169,7 +2403,7 @@ Cudd_FirstNode( DdNode ** node) { DdGen *gen; - int retval; + int size; /* Sanity Check. */ if (dd == NULL || f == NULL) return(NULL); @@ -2177,46 +2411,30 @@ Cudd_FirstNode( /* Allocate generator an initialize it. */ gen = ABC_ALLOC(DdGen,1); if (gen == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } gen->manager = dd; gen->type = CUDD_GEN_NODES; gen->status = CUDD_GEN_EMPTY; - gen->gen.nodes.visited = NULL; - gen->gen.nodes.stGen = NULL; gen->stack.sp = 0; - gen->stack.stack = NULL; gen->node = NULL; - gen->gen.nodes.visited = st_init_table(st_ptrcmp, st_ptrhash);; - if (gen->gen.nodes.visited == NULL) { - ABC_FREE(gen); - return(NULL); - } - - /* Collect all the nodes in a st table for later perusal. */ - retval = cuddCollectNodes(Cudd_Regular(f),gen->gen.nodes.visited); - if (retval == 0) { - st_free_table(gen->gen.nodes.visited); - ABC_FREE(gen); - return(NULL); - } - - /* Initialize the st table generator. */ - gen->gen.nodes.stGen = st_init_gen(gen->gen.nodes.visited); - if (gen->gen.nodes.stGen == NULL) { - st_free_table(gen->gen.nodes.visited); - ABC_FREE(gen); - return(NULL); + /* Collect all the nodes on the generator stack for later perusal. */ + gen->stack.stack = cuddNodeArray(Cudd_Regular(f), &size); + if (gen->stack.stack == NULL) { + ABC_FREE(gen); + dd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } + gen->gen.nodes.size = size; /* Find the first node. */ - retval = st_gen(gen->gen.nodes.stGen, (const char **) &(gen->node), NULL); - if (retval != 0) { - gen->status = CUDD_GEN_NONEMPTY; - *node = gen->node; + if (gen->stack.sp < gen->gen.nodes.size) { + gen->status = CUDD_GEN_NONEMPTY; + gen->node = gen->stack.stack[gen->stack.sp]; + *node = gen->node; } return(gen); @@ -2242,18 +2460,17 @@ Cudd_NextNode( DdGen * gen, DdNode ** node) { - int retval; - /* Find the next node. */ - retval = st_gen(gen->gen.nodes.stGen, (const char **) &(gen->node), NULL); - if (retval == 0) { - gen->status = CUDD_GEN_EMPTY; + gen->stack.sp++; + if (gen->stack.sp < gen->gen.nodes.size) { + gen->node = gen->stack.stack[gen->stack.sp]; + *node = gen->node; + return(1); } else { - *node = gen->node; + gen->status = CUDD_GEN_EMPTY; + return(0); } - return(retval); - } /* end of Cudd_NextNode */ @@ -2274,20 +2491,22 @@ int Cudd_GenFree( DdGen * gen) { - if (gen == NULL) return(0); switch (gen->type) { case CUDD_GEN_CUBES: case CUDD_GEN_ZDD_PATHS: - ABC_FREE(gen->gen.cubes.cube); - ABC_FREE(gen->stack.stack); - break; + ABC_FREE(gen->gen.cubes.cube); + ABC_FREE(gen->stack.stack); + break; + case CUDD_GEN_PRIMES: + ABC_FREE(gen->gen.primes.cube); + Cudd_RecursiveDeref(gen->manager,gen->node); + break; case CUDD_GEN_NODES: - st_free_gen(gen->gen.nodes.stGen); - st_free_table(gen->gen.nodes.visited); - break; + ABC_FREE(gen->stack.stack); + break; default: - return(0); + return(0); } ABC_FREE(gen); return(0); @@ -2342,14 +2561,14 @@ Cudd_IndicesToCube( cube = DD_ONE(dd); cuddRef(cube); for (i = n - 1; i >= 0; i--) { - tmp = Cudd_bddAnd(dd,Cudd_bddIthVar(dd,array[i]),cube); - if (tmp == NULL) { + tmp = Cudd_bddAnd(dd,Cudd_bddIthVar(dd,array[i]),cube); + if (tmp == NULL) { + Cudd_RecursiveDeref(dd,cube); + return(NULL); + } + cuddRef(tmp); Cudd_RecursiveDeref(dd,cube); - return(NULL); - } - cuddRef(tmp); - Cudd_RecursiveDeref(dd,cube); - cube = tmp; + cube = tmp; } cuddDeref(cube); @@ -2416,28 +2635,28 @@ Cudd_AverageDistance( /* Scan the variable subtables. */ for (i = 0; i < nvars; i++) { - nodelist = dd->subtables[i].nodelist; - tesubtotal = 0.0; - nextsubtotal = 0.0; - slots = dd->subtables[i].slots; - for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != sentinel) { - diff = (long) scan - (long) cuddT(scan); - tesubtotal += (double) ddAbs(diff); - diff = (long) scan - (long) Cudd_Regular(cuddE(scan)); - tesubtotal += (double) ddAbs(diff); - temeasured += 2.0; - if (scan->next != NULL) { - diff = (long) scan - (long) scan->next; - nextsubtotal += (double) ddAbs(diff); - nextmeasured += 1.0; - } - scan = scan->next; + nodelist = dd->subtables[i].nodelist; + tesubtotal = 0.0; + nextsubtotal = 0.0; + slots = dd->subtables[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != sentinel) { + diff = (long) scan - (long) cuddT(scan); + tesubtotal += (double) ddAbs(diff); + diff = (long) scan - (long) Cudd_Regular(cuddE(scan)); + tesubtotal += (double) ddAbs(diff); + temeasured += 2.0; + if (scan->next != sentinel) { + diff = (long) scan - (long) scan->next; + nextsubtotal += (double) ddAbs(diff); + nextmeasured += 1.0; + } + scan = scan->next; + } } - } - tetotal += tesubtotal; - nexttotal += nextsubtotal; + tetotal += tesubtotal; + nexttotal += nextsubtotal; } /* Scan the constant table. */ @@ -2445,15 +2664,15 @@ Cudd_AverageDistance( nextsubtotal = 0.0; slots = dd->constants.slots; for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (scan->next != NULL) { - diff = (long) scan - (long) scan->next; - nextsubtotal += (double) ddAbs(diff); - nextmeasured += 1.0; + scan = nodelist[j]; + while (scan != NULL) { + if (scan->next != NULL) { + diff = (long) scan - (long) scan->next; + nextsubtotal += (double) ddAbs(diff); + nextmeasured += 1.0; + } + scan = scan->next; } - scan = scan->next; - } } nexttotal += nextsubtotal; @@ -2480,10 +2699,9 @@ Cudd_AverageDistance( ******************************************************************************/ long -Cudd_Random( - ) +Cudd_Random(void) { - int i; /* index in the shuffle table */ + int i; /* index in the shuffle table */ long int w; /* work variable */ /* cuddRand == 0 if the geneartor has not been initialized yet. */ @@ -2554,11 +2772,11 @@ Cudd_Srandom( cuddRand2 = cuddRand; /* Load the shuffle table (after 11 warm-ups). */ for (i = 0; i < STAB_SIZE + 11; i++) { - long int w; - w = cuddRand / LEQQ1; - cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; - cuddRand += (cuddRand < 0) * MODULUS1; - shuffleTable[i % STAB_SIZE] = cuddRand; + long int w; + w = cuddRand / LEQQ1; + cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1; + cuddRand += (cuddRand < 0) * MODULUS1; + shuffleTable[i % STAB_SIZE] = cuddRand; } shuffleSelect = shuffleTable[1 % STAB_SIZE]; @@ -2650,7 +2868,7 @@ cuddP( DdNode * f) { int retval; - st_table *table = st_init_table(st_ptrcmp, st_ptrhash);; + st_table *table = st_init_table(st_ptrcmp,st_ptrhash); if (table == NULL) return(0); @@ -2679,7 +2897,7 @@ cuddStCountfree( char * value, char * arg) { - double *d; + double *d; d = (double *)value; ABC_FREE(d); @@ -2693,7 +2911,7 @@ cuddStCountfree( Synopsis [Recursively collects all the nodes of a DD in a symbol table.] - Description [Traverses the BDD f and collects all its nodes in a + Description [Traverses the DD f and collects all its nodes in a symbol table. f is assumed to be a regular pointer and cuddCollectNodes guarantees this assumption in the recursive calls. Returns 1 in case of success; 0 otherwise.] @@ -2708,8 +2926,8 @@ cuddCollectNodes( DdNode * f, st_table * visited) { - DdNode *T, *E; - int retval; + DdNode *T, *E; + int retval; #ifdef DD_DEBUG assert(!Cudd_IsComplement(f)); @@ -2729,7 +2947,7 @@ cuddCollectNodes( /* Check terminal case. */ if (cuddIsConstant(f)) - return(1); + return(1); /* Recursive calls. */ T = cuddT(f); @@ -2742,6 +2960,45 @@ cuddCollectNodes( } /* end of cuddCollectNodes */ +/**Function******************************************************************** + + Synopsis [Recursively collects all the nodes of a DD in an array.] + + Description [Traverses the DD f and collects all its nodes in an array. + The caller should free the array returned by cuddNodeArray. + Returns a pointer to the array of nodes in case of success; NULL + otherwise. The nodes are collected in reverse topological order, so + that a node is always preceded in the array by all its descendants.] + + SideEffects [The number of nodes is returned as a side effect.] + + SeeAlso [Cudd_FirstNode] + +******************************************************************************/ +DdNodePtr * +cuddNodeArray( + DdNode *f, + int *n) +{ + DdNodePtr *table; + int size, retval; + + size = ddDagInt(Cudd_Regular(f)); + table = ABC_ALLOC(DdNodePtr, size); + if (table == NULL) { + ddClearFlag(Cudd_Regular(f)); + return(NULL); + } + + retval = cuddNodeArrayRecur(f, table, 0); + assert(retval == size); + + *n = size; + return(table); + +} /* cuddNodeArray */ + + /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ @@ -2765,7 +3022,7 @@ dp2( { DdNode *g, *n, *N; int T,E; - + if (f == NULL) { return(0); } @@ -2773,68 +3030,68 @@ dp2( if (cuddIsConstant(g)) { #if SIZEOF_VOID_P == 8 (void) fprintf(dd->out,"ID = %c0x%lx\tvalue = %-9g\n", bang(f), - (unsigned long) g / (unsigned long) sizeof(DdNode),cuddV(g)); + (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g)); #else (void) fprintf(dd->out,"ID = %c0x%x\tvalue = %-9g\n", bang(f), - (unsigned) g / (unsigned) sizeof(DdNode),cuddV(g)); + (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g)); #endif - return(1); + return(1); } if (st_is_member(t,(char *) g) == 1) { return(1); } if (st_add_direct(t,(char *) g,NULL) == ST_OUT_OF_MEM) - return(0); + return(0); #ifdef DD_STATS #if SIZEOF_VOID_P == 8 (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %d\tr = %d\t", bang(f), - (unsigned long) g / (unsigned long) sizeof(DdNode), g->index, g->ref); + (ptruint) g / (ptruint) sizeof(DdNode), g->index, g->ref); #else (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\tr = %d\t", bang(f), - (unsigned) g / (unsigned) sizeof(DdNode),g->index,g->ref); + (ptruint) g / (ptruint) sizeof(DdNode),g->index,g->ref); #endif #else #if SIZEOF_VOID_P == 8 - (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %d\t", bang(f), - (unsigned long) g / (unsigned long) sizeof(DdNode),g->index); + (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %u\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index); #else - (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\t", bang(f), - (unsigned) g / (unsigned) sizeof(DdNode),g->index); + (void) fprintf(dd->out,"ID = %c0x%x\tindex = %hu\t", bang(f), + (ptruint) g / (ptruint) sizeof(DdNode),g->index); #endif #endif n = cuddT(g); if (cuddIsConstant(n)) { (void) fprintf(dd->out,"T = %-9g\t",cuddV(n)); - T = 1; + T = 1; } else { #if SIZEOF_VOID_P == 8 - (void) fprintf(dd->out,"T = 0x%lx\t",(unsigned long) n / (unsigned long) sizeof(DdNode)); + (void) fprintf(dd->out,"T = 0x%lx\t",(ptruint) n / (ptruint) sizeof(DdNode)); #else - (void) fprintf(dd->out,"T = 0x%x\t",(unsigned) n / (unsigned) sizeof(DdNode)); + (void) fprintf(dd->out,"T = 0x%x\t",(ptruint) n / (ptruint) sizeof(DdNode)); #endif - T = 0; + T = 0; } n = cuddE(g); N = Cudd_Regular(n); if (cuddIsConstant(N)) { (void) fprintf(dd->out,"E = %c%-9g\n",bang(n),cuddV(N)); - E = 1; + E = 1; } else { #if SIZEOF_VOID_P == 8 - (void) fprintf(dd->out,"E = %c0x%lx\n", bang(n), (unsigned long) N/(unsigned long) sizeof(DdNode)); + (void) fprintf(dd->out,"E = %c0x%lx\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode)); #else - (void) fprintf(dd->out,"E = %c0x%x\n", bang(n), (unsigned) N/(unsigned) sizeof(DdNode)); + (void) fprintf(dd->out,"E = %c0x%x\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode)); #endif - E = 0; + E = 0; } if (E == 0) { if (dp2(dd,N,t) == 0) - return(0); + return(0); } if (T == 0) { if (dp2(dd,cuddT(g),t) == 0) - return(0); + return(0); } return(1); @@ -2856,38 +3113,38 @@ ddPrintMintermAux( DdNode * node /* current node */, int * list /* current recursion path */) { - DdNode *N,*Nv,*Nnv; - int i,v,index; + DdNode *N,*Nv,*Nnv; + int i,v,index; N = Cudd_Regular(node); if (cuddIsConstant(N)) { - /* Terminal case: Print one cube based on the current recursion - ** path, unless we have reached the background value (ADDs) or - ** the logical zero (BDDs). - */ - if (node != background && node != zero) { - for (i = 0; i < dd->size; i++) { - v = list[i]; - if (v == 0) (void) fprintf(dd->out,"0"); - else if (v == 1) (void) fprintf(dd->out,"1"); - else (void) fprintf(dd->out,"-"); + /* Terminal case: Print one cube based on the current recursion + ** path, unless we have reached the background value (ADDs) or + ** the logical zero (BDDs). + */ + if (node != background && node != zero) { + for (i = 0; i < dd->size; i++) { + v = list[i]; + if (v == 0) (void) fprintf(dd->out,"0"); + else if (v == 1) (void) fprintf(dd->out,"1"); + else (void) fprintf(dd->out,"-"); + } + (void) fprintf(dd->out," % g\n", cuddV(node)); } - (void) fprintf(dd->out," % g\n", cuddV(node)); - } } else { - Nv = cuddT(N); - Nnv = cuddE(N); - if (Cudd_IsComplement(node)) { - Nv = Cudd_Not(Nv); - Nnv = Cudd_Not(Nnv); - } - index = N->index; - list[index] = 0; - ddPrintMintermAux(dd,Nnv,list); - list[index] = 1; - ddPrintMintermAux(dd,Nv,list); - list[index] = 2; + Nv = cuddT(N); + Nnv = cuddE(N); + if (Cudd_IsComplement(node)) { + Nv = Cudd_Not(Nv); + Nnv = Cudd_Not(Nnv); + } + index = N->index; + list[index] = 0; + ddPrintMintermAux(dd,Nnv,list); + list[index] = 1; + ddPrintMintermAux(dd,Nv,list); + list[index] = 2; } return; @@ -2911,11 +3168,11 @@ ddDagInt( int tval, eval; if (Cudd_IsComplement(n->next)) { - return(0); + return(0); } n->next = Cudd_Not(n->next); if (cuddIsConstant(n)) { - return(1); + return(1); } tval = ddDagInt(cuddT(n)); eval = ddDagInt(Cudd_Regular(cuddE(n))); @@ -2926,6 +3183,46 @@ ddDagInt( /**Function******************************************************************** + Synopsis [Performs the recursive step of cuddNodeArray.] + + Description [Performs the recursive step of cuddNodeArray. Returns + an the number of nodes in the DD. Clear the least significant bit + of the next field that was used as visited flag by + cuddNodeArrayRecur when counting the nodes. node is supposed to be + regular; the invariant is maintained by this procedure.] + + SideEffects [None] + + SeeAlso [] + +******************************************************************************/ +static int +cuddNodeArrayRecur( + DdNode *f, + DdNodePtr *table, + int index) +{ + int tindex, eindex; + + if (!Cudd_IsComplement(f->next)) { + return(index); + } + /* Clear visited flag. */ + f->next = Cudd_Regular(f->next); + if (cuddIsConstant(f)) { + table[index] = f; + return(index + 1); + } + tindex = cuddNodeArrayRecur(cuddT(f), table, index); + eindex = cuddNodeArrayRecur(Cudd_Regular(cuddE(f)), table, tindex); + table[eindex] = f; + return(eindex + 1); + +} /* end of cuddNodeArrayRecur */ + + +/**Function******************************************************************** + Synopsis [Performs the recursive step of Cudd_CofactorEstimate.] Description [Performs the recursive step of Cudd_CofactorEstimate. @@ -2952,74 +3249,76 @@ cuddEstimateCofactor( DdNode *ptrT, *ptrE; if (Cudd_IsComplement(node->next)) { - if (!st_lookup(table,(char *)node,(char **)ptr)) { - st_add_direct(table,(char *)node,(char *)node); - *ptr = node; - } - return(0); + if (!st_lookup(table,(char *)node,(char **)ptr)) { + if (st_add_direct(table,(char *)node,(char *)node) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + *ptr = node; + } + return(0); } node->next = Cudd_Not(node->next); if (cuddIsConstant(node)) { - *ptr = node; - if (st_add_direct(table,(char *)node,(char *)node) == ST_OUT_OF_MEM) - return(CUDD_OUT_OF_MEM); - return(1); + *ptr = node; + if (st_add_direct(table,(char *)node,(char *)node) == ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + return(1); } if ((int) node->index == i) { - if (phase == 1) { - *ptr = cuddT(node); - val = ddDagInt(cuddT(node)); - } else { - *ptr = cuddE(node); - val = ddDagInt(Cudd_Regular(cuddE(node))); - } - if (node->ref > 1) { - if (st_add_direct(table,(char *)node,(char *)*ptr) == - ST_OUT_OF_MEM) - return(CUDD_OUT_OF_MEM); - } - return(val); + if (phase == 1) { + *ptr = cuddT(node); + val = ddDagInt(cuddT(node)); + } else { + *ptr = cuddE(node); + val = ddDagInt(Cudd_Regular(cuddE(node))); + } + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + return(val); } if (dd->perm[node->index] > dd->perm[i]) { - *ptr = node; - tval = ddDagInt(cuddT(node)); - eval = ddDagInt(Cudd_Regular(cuddE(node))); - if (node->ref > 1) { - if (st_add_direct(table,(char *)node,(char *)node) == - ST_OUT_OF_MEM) - return(CUDD_OUT_OF_MEM); - } - val = 1 + tval + eval; - return(val); + *ptr = node; + tval = ddDagInt(cuddT(node)); + eval = ddDagInt(Cudd_Regular(cuddE(node))); + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)node) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } + val = 1 + tval + eval; + return(val); } tval = cuddEstimateCofactor(dd,table,cuddT(node),i,phase,&ptrT); eval = cuddEstimateCofactor(dd,table,Cudd_Regular(cuddE(node)),i, - phase,&ptrE); + phase,&ptrE); ptrE = Cudd_NotCond(ptrE,Cudd_IsComplement(cuddE(node))); - if (ptrT == ptrE) { /* recombination */ - *ptr = ptrT; - val = tval; - if (node->ref > 1) { - if (st_add_direct(table,(char *)node,(char *)*ptr) == - ST_OUT_OF_MEM) - return(CUDD_OUT_OF_MEM); - } + if (ptrT == ptrE) { /* recombination */ + *ptr = ptrT; + val = tval; + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } } else if ((ptrT != cuddT(node) || ptrE != cuddE(node)) && - (*ptr = cuddUniqueLookup(dd,node->index,ptrT,ptrE)) != NULL) { - if (Cudd_IsComplement((*ptr)->next)) { - val = 0; + (*ptr = cuddUniqueLookup(dd,node->index,ptrT,ptrE)) != NULL) { + if (Cudd_IsComplement((*ptr)->next)) { + val = 0; + } else { + val = 1 + tval + eval; + } + if (node->ref > 1) { + if (st_add_direct(table,(char *)node,(char *)*ptr) == + ST_OUT_OF_MEM) + return(CUDD_OUT_OF_MEM); + } } else { + *ptr = node; val = 1 + tval + eval; } - if (node->ref > 1) { - if (st_add_direct(table,(char *)node,(char *)*ptr) == - ST_OUT_OF_MEM) - return(CUDD_OUT_OF_MEM); - } - } else { - *ptr = node; - val = 1 + tval + eval; - } return(val); } /* end of cuddEstimateCofactor */ @@ -3051,7 +3350,7 @@ cuddUniqueLookup( DdSubtable *subtable; if (index >= unique->size) { - return(NULL); + return(NULL); } level = unique->perm[index]; @@ -3067,13 +3366,13 @@ cuddUniqueLookup( looking = nodelist[posn]; while (T < cuddT(looking)) { - looking = Cudd_Regular(looking->next); + looking = Cudd_Regular(looking->next); } while (T == cuddT(looking) && E < cuddE(looking)) { - looking = Cudd_Regular(looking->next); + looking = Cudd_Regular(looking->next); } if (cuddT(looking) == T && cuddE(looking) == E) { - return(looking); + return(looking); } return(NULL); @@ -3104,11 +3403,11 @@ cuddEstimateCofactorSimple( int tval, eval; if (Cudd_IsComplement(node->next)) { - return(0); + return(0); } node->next = Cudd_Not(node->next); if (cuddIsConstant(node)) { - return(1); + return(1); } tval = cuddEstimateCofactorSimple(cuddT(node),i); if ((int) node->index == i) return(tval); @@ -3142,31 +3441,31 @@ ddCountMintermAux( double max, DdHashTable * table) { - DdNode *N, *Nt, *Ne; - double min, minT, minE; - DdNode *res; + DdNode *N, *Nt, *Ne; + double min, minT, minE; + DdNode *res; N = Cudd_Regular(node); if (cuddIsConstant(N)) { - if (node == background || node == zero) { - return(0.0); - } else { - return(max); - } + if (node == background || node == zero) { + return(0.0); + } else { + return(max); + } } if (N->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) { - min = cuddV(res); - if (res->ref == 0) { - table->manager->dead++; - table->manager->constants.dead++; - } - return(min); + min = cuddV(res); + if (res->ref == 0) { + table->manager->dead++; + table->manager->constants.dead++; + } + return(min); } Nt = cuddT(N); Ne = cuddE(N); if (Cudd_IsComplement(node)) { - Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); + Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); } minT = ddCountMintermAux(Nt,max,table); @@ -3178,13 +3477,13 @@ ddCountMintermAux( min = minT + minE; if (N->ref != 1) { - ptrint fanout = (ptrint) N->ref; - cuddSatDec(fanout); - res = cuddUniqueConst(table->manager,min); - if (!cuddHashTableInsert1(table,node,res,fanout)) { - cuddRef(res); Cudd_RecursiveDeref(table->manager, res); - return((double)CUDD_OUT_OF_MEM); - } + ptrint fanout = (ptrint) N->ref; + cuddSatDec(fanout); + res = cuddUniqueConst(table->manager,min); + if (!cuddHashTableInsert1(table,node,res,fanout)) { + cuddRef(res); Cudd_RecursiveDeref(table->manager, res); + return((double)CUDD_OUT_OF_MEM); + } } return(min); @@ -3215,17 +3514,17 @@ ddCountPathAux( st_table * table) { - DdNode *Nv, *Nnv; - double paths, *ppaths, paths1, paths2; - double *dummy; + DdNode *Nv, *Nnv; + double paths, *ppaths, paths1, paths2; + double *dummy; if (cuddIsConstant(node)) { - return(1.0); + return(1.0); } - if (st_lookup(table, (char *)node, (char **)&dummy)) { - paths = *dummy; - return(paths); + if (st_lookup(table, (const char *)node, (char **)&dummy)) { + paths = *dummy; + return(paths); } Nv = cuddT(node); Nnv = cuddE(node); @@ -3235,17 +3534,17 @@ ddCountPathAux( paths2 = ddCountPathAux(Cudd_Regular(Nnv),table); if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM); paths = paths1 + paths2; - + ppaths = ABC_ALLOC(double,1); if (ppaths == NULL) { - return((double)CUDD_OUT_OF_MEM); + return((double)CUDD_OUT_OF_MEM); } *ppaths = paths; if (st_add_direct(table,(char *)node, (char *)ppaths) == ST_OUT_OF_MEM) { - ABC_FREE(ppaths); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(ppaths); + return((double)CUDD_OUT_OF_MEM); } return(paths); @@ -3254,9 +3553,9 @@ ddCountPathAux( /**Function******************************************************************** - Synopsis [Performs the recursive step of Cudd_CountMinterm.] + Synopsis [Performs the recursive step of Cudd_EpdCountMinterm.] - Description [Performs the recursive step of Cudd_CountMinterm. + Description [Performs the recursive step of Cudd_EpdCountMinterm. It is based on the following identity. Let |f| be the number of minterms of f. Then: <xmp> @@ -3277,33 +3576,31 @@ ddEpdCountMintermAux( EpDouble * epd, st_table * table) { - DdNode *Nt, *Ne; + DdNode *Nt, *Ne; EpDouble *min, minT, minE; EpDouble *res; - int status; + int status; + /* node is assumed to be regular */ if (cuddIsConstant(node)) { - if (node == background || node == zero) { - EpdMakeZero(epd, 0); - } else { - EpdCopy(max, epd); - } - return(0); + if (node == background || node == zero) { + EpdMakeZero(epd, 0); + } else { + EpdCopy(max, epd); + } + return(0); } - if (node->ref != 1 && st_lookup(table, (char *)node, (char **)&res)) { - EpdCopy(res, epd); - return(0); + if (node->ref != 1 && st_lookup(table, (const char *)node, (char **)&res)) { + EpdCopy(res, epd); + return(0); } Nt = cuddT(node); Ne = cuddE(node); - if (Cudd_IsComplement(node)) { - Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); - } status = ddEpdCountMintermAux(Nt,max,&minT,table); if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); EpdMultiply(&minT, (double)0.5); - status = ddEpdCountMintermAux(Ne,max,&minE,table); + status = ddEpdCountMintermAux(Cudd_Regular(Ne),max,&minE,table); if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM); if (Cudd_IsComplement(Ne)) { EpdSubtract3(max, &minE, epd); @@ -3313,14 +3610,14 @@ ddEpdCountMintermAux( EpdAdd3(&minT, &minE, epd); if (node->ref > 1) { - min = EpdAlloc(); - if (!min) - return(CUDD_OUT_OF_MEM); - EpdCopy(epd, min); - if (st_insert(table, (char *)node, (char *)min) == ST_OUT_OF_MEM) { - EpdFree(min); - return(CUDD_OUT_OF_MEM); - } + min = EpdAlloc(); + if (!min) + return(CUDD_OUT_OF_MEM); + EpdCopy(epd, min); + if (st_insert(table, (char *)node, (char *)min) == ST_OUT_OF_MEM) { + EpdFree(min); + return(CUDD_OUT_OF_MEM); + } } return(0); @@ -3350,22 +3647,22 @@ ddCountPathsToNonZero( st_table * table) { - DdNode *node, *Nt, *Ne; - double paths, *ppaths, paths1, paths2; - double *dummy; + DdNode *node, *Nt, *Ne; + double paths, *ppaths, paths1, paths2; + double *dummy; node = Cudd_Regular(N); if (cuddIsConstant(node)) { - return((double) !(Cudd_IsComplement(N) || cuddV(node)==DD_ZERO_VAL)); + return((double) !(Cudd_IsComplement(N) || cuddV(node)==DD_ZERO_VAL)); } - if (st_lookup(table, (char *)N, (char **)&dummy)) { - paths = *dummy; - return(paths); + if (st_lookup(table, (const char *)N, (char **)&dummy)) { + paths = *dummy; + return(paths); } Nt = cuddT(node); Ne = cuddE(node); if (node != N) { - Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); + Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne); } paths1 = ddCountPathsToNonZero(Nt,table); @@ -3376,14 +3673,14 @@ ddCountPathsToNonZero( ppaths = ABC_ALLOC(double,1); if (ppaths == NULL) { - return((double)CUDD_OUT_OF_MEM); + return((double)CUDD_OUT_OF_MEM); } *ppaths = paths; if (st_add_direct(table,(char *)N, (char *)ppaths) == ST_OUT_OF_MEM) { - ABC_FREE(ppaths); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(ppaths); + return((double)CUDD_OUT_OF_MEM); } return(paths); @@ -3409,7 +3706,7 @@ ddSupportStep( int * support) { if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) { - return; + return; } support[f->index] = 1; @@ -3439,12 +3736,12 @@ ddClearFlag( DdNode * f) { if (!Cudd_IsComplement(f->next)) { - return; + return; } /* Clear visited flag. */ f->next = Cudd_Regular(f->next); if (cuddIsConstant(f)) { - return; + return; } ddClearFlag(cuddT(f)); ddClearFlag(Cudd_Regular(cuddE(f))); @@ -3472,11 +3769,11 @@ ddLeavesInt( int tval, eval; if (Cudd_IsComplement(n->next)) { - return(0); + return(0); } n->next = Cudd_Not(n->next); if (cuddIsConstant(n)) { - return(1); + return(1); } tval = ddLeavesInt(cuddT(n)); eval = ddLeavesInt(Cudd_Regular(cuddE(n))); @@ -3517,13 +3814,13 @@ ddPickArbitraryMinterms( bzero = Cudd_Not(one); if (nminterms == 0 || node == bzero) return(1); if (node == one) { - return(1); + return(1); } N = Cudd_Regular(node); T = cuddT(N); E = cuddE(N); if (Cudd_IsComplement(node)) { - T = Cudd_Not(T); E = Cudd_Not(E); + T = Cudd_Not(T); E = Cudd_Not(E); } min1 = Cudd_CountMinterm(dd, T, nvars) / 2.0; @@ -3533,13 +3830,13 @@ ddPickArbitraryMinterms( t = (int)((double)nminterms * min1 / (min1 + min2) + 0.5); for (i = 0; i < t; i++) - string[i][N->index] = '1'; + string[i][N->index] = '1'; for (i = t; i < nminterms; i++) - string[i][N->index] = '0'; + string[i][N->index] = '0'; result = ddPickArbitraryMinterms(dd,T,nvars,t,&string[0]); if (result == 0) - return(0); + return(0); result = ddPickArbitraryMinterms(dd,E,nvars,nminterms-t,&string[t]); return(result); @@ -3562,7 +3859,6 @@ static int ddPickRepresentativeCube( DdManager *dd, DdNode *node, - int nvars, double *weight, char *string) { @@ -3579,33 +3875,33 @@ ddPickRepresentativeCube( if (node == DD_ONE(dd)) return(1); for (;;) { - N = Cudd_Regular(node); - if (N == one) - break; - T = cuddT(N); - E = cuddE(N); - if (Cudd_IsComplement(node)) { - T = Cudd_Not(T); - E = Cudd_Not(E); - } - if (weight[N->index] >= 0.0) { - if (T == bzero) { - node = E; - string[N->index] = '0'; - } else { - node = T; - string[N->index] = '1'; + N = Cudd_Regular(node); + if (N == one) + break; + T = cuddT(N); + E = cuddE(N); + if (Cudd_IsComplement(node)) { + T = Cudd_Not(T); + E = Cudd_Not(E); } - } else { - if (E == bzero) { - node = T; - string[N->index] = '1'; + if (weight[N->index] >= 0.0) { + if (T == bzero) { + node = E; + string[N->index] = '0'; + } else { + node = T; + string[N->index] = '1'; + } } else { - node = E; - string[N->index] = '0'; + if (E == bzero) { + node = T; + string[N->index] = '1'; + } else { + node = E; + string[N->index] = '0'; + } } } - } return(1); } /* end of ddPickRepresentativeCube */ @@ -3635,5 +3931,7 @@ ddEpdFree( return(ST_CONTINUE); } /* end of ddEpdFree */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddWindow.c b/src/bdd/cudd/cuddWindow.c index 62c92ff2..0a7c6705 100644 --- a/src/bdd/cudd/cuddWindow.c +++ b/src/bdd/cudd/cuddWindow.c @@ -4,30 +4,57 @@ PackageName [cudd] - Synopsis [Functions for window permutation] + Synopsis [Functions for variable reordering by window permutation.] Description [Internal procedures included in this module: - <ul> - <li> cuddWindowReorder() - </ul> - Static procedures included in this module: - <ul> - <li> ddWindow2() - <li> ddWindowConv2() - <li> ddPermuteWindow3() - <li> ddWindow3() - <li> ddWindowConv3() - <li> ddPermuteWindow4() - <li> ddWindow4() - <li> ddWindowConv4() - </ul>] + <ul> + <li> cuddWindowReorder() + </ul> + Static procedures included in this module: + <ul> + <li> ddWindow2() + <li> ddWindowConv2() + <li> ddPermuteWindow3() + <li> ddWindow3() + <li> ddWindowConv3() + <li> ddPermuteWindow4() + <li> ddWindow4() + <li> ddWindowConv4() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -37,6 +64,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -57,7 +85,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddWindow.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddWindow.c,v 1.14 2009/02/20 02:14:58 fabio Exp $"; #endif #ifdef DD_STATS @@ -76,14 +104,14 @@ extern int ddTotalNISwaps; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int ddWindow2 ARGS((DdManager *table, int low, int high)); -static int ddWindowConv2 ARGS((DdManager *table, int low, int high)); -static int ddPermuteWindow3 ARGS((DdManager *table, int x)); -static int ddWindow3 ARGS((DdManager *table, int low, int high)); -static int ddWindowConv3 ARGS((DdManager *table, int low, int high)); -static int ddPermuteWindow4 ARGS((DdManager *table, int w)); -static int ddWindow4 ARGS((DdManager *table, int low, int high)); -static int ddWindowConv4 ARGS((DdManager *table, int low, int high)); +static int ddWindow2 (DdManager *table, int low, int high); +static int ddWindowConv2 (DdManager *table, int low, int high); +static int ddPermuteWindow3 (DdManager *table, int x); +static int ddWindow3 (DdManager *table, int low, int high); +static int ddWindowConv3 (DdManager *table, int low, int high); +static int ddPermuteWindow4 (DdManager *table, int w); +static int ddWindow4 (DdManager *table, int low, int high); +static int ddWindowConv4 (DdManager *table, int low, int high); /**AutomaticEnd***************************************************************/ @@ -125,39 +153,39 @@ cuddWindowReorder( switch (submethod) { case CUDD_REORDER_WINDOW2: - res = ddWindow2(table,low,high); - break; + res = ddWindow2(table,low,high); + break; case CUDD_REORDER_WINDOW3: - res = ddWindow3(table,low,high); - break; + res = ddWindow3(table,low,high); + break; case CUDD_REORDER_WINDOW4: - res = ddWindow4(table,low,high); - break; + res = ddWindow4(table,low,high); + break; case CUDD_REORDER_WINDOW2_CONV: - res = ddWindowConv2(table,low,high); - break; + res = ddWindowConv2(table,low,high); + break; case CUDD_REORDER_WINDOW3_CONV: - res = ddWindowConv3(table,low,high); + res = ddWindowConv3(table,low,high); #ifdef DD_DEBUG - supposedOpt = table->keys - table->isolated; - res = ddWindow3(table,low,high); - if (table->keys - table->isolated != (unsigned) supposedOpt) { - (void) fprintf(table->err, "Convergence failed! (%d != %d)\n", - table->keys - table->isolated, supposedOpt); - } + supposedOpt = table->keys - table->isolated; + res = ddWindow3(table,low,high); + if (table->keys - table->isolated != (unsigned) supposedOpt) { + (void) fprintf(table->err, "Convergence failed! (%d != %d)\n", + table->keys - table->isolated, supposedOpt); + } #endif - break; + break; case CUDD_REORDER_WINDOW4_CONV: - res = ddWindowConv4(table,low,high); + res = ddWindowConv4(table,low,high); #ifdef DD_DEBUG - supposedOpt = table->keys - table->isolated; - res = ddWindow4(table,low,high); - if (table->keys - table->isolated != (unsigned) supposedOpt) { - (void) fprintf(table->err,"Convergence failed! (%d != %d)\n", - table->keys - table->isolated, supposedOpt); - } + supposedOpt = table->keys - table->isolated; + res = ddWindow4(table,low,high); + if (table->keys - table->isolated != (unsigned) supposedOpt) { + (void) fprintf(table->err,"Convergence failed! (%d != %d)\n", + table->keys - table->isolated, supposedOpt); + } #endif - break; + break; default: return(0); } @@ -201,20 +229,20 @@ ddWindow2( res = table->keys - table->isolated; for (x = low; x < high; x++) { - size = res; - res = cuddSwapInPlace(table,x,x+1); - if (res == 0) return(0); - if (res >= size) { /* no improvement: undo permutation */ + size = res; res = cuddSwapInPlace(table,x,x+1); if (res == 0) return(0); - } + if (res >= size) { /* no improvement: undo permutation */ + res = cuddSwapInPlace(table,x,x+1); + if (res == 0) return(0); + } #ifdef DD_STATS - if (res < size) { - (void) fprintf(table->out,"-"); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (res < size) { + (void) fprintf(table->out,"-"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } @@ -258,52 +286,52 @@ ddWindowConv2( nwin = high-low; events = ABC_ALLOC(int,nwin); if (events == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (x=0; x<nwin; x++) { - events[x] = 1; + events[x] = 1; } res = table->keys - table->isolated; do { - newevent = 0; - for (x=0; x<nwin; x++) { - if (events[x]) { - size = res; - res = cuddSwapInPlace(table,x+low,x+low+1); - if (res == 0) { - ABC_FREE(events); - return(0); - } - if (res >= size) { /* no improvement: undo permutation */ - res = cuddSwapInPlace(table,x+low,x+low+1); - if (res == 0) { - ABC_FREE(events); - return(0); - } - } - if (res < size) { - if (x < nwin-1) events[x+1] = 1; - if (x > 0) events[x-1] = 1; - newevent = 1; - } - events[x] = 0; + newevent = 0; + for (x=0; x<nwin; x++) { + if (events[x]) { + size = res; + res = cuddSwapInPlace(table,x+low,x+low+1); + if (res == 0) { + ABC_FREE(events); + return(0); + } + if (res >= size) { /* no improvement: undo permutation */ + res = cuddSwapInPlace(table,x+low,x+low+1); + if (res == 0) { + ABC_FREE(events); + return(0); + } + } + if (res < size) { + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + } + events[x] = 0; #ifdef DD_STATS - if (res < size) { - (void) fprintf(table->out,"-"); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (res < size) { + (void) fprintf(table->out,"-"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif + } } - } #ifdef DD_STATS - if (newevent) { - (void) fprintf(table->out,"|"); - fflush(table->out); - } + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } #endif } while (newevent); @@ -335,8 +363,8 @@ ddPermuteWindow3( int x) { int y,z; - int size,sizeNew; - int best; + int size,sizeNew; + int best; #ifdef DD_DEBUG assert(table->dead == 0); @@ -345,7 +373,7 @@ ddPermuteWindow3( size = table->keys - table->isolated; y = x+1; z = y+1; - + /* The permutation pattern is: ** (x,y)(y,z) ** repeated three times to get all 3! = 6 permutations. @@ -353,40 +381,40 @@ ddPermuteWindow3( #define ABC 1 best = ABC; -#define BAC 2 +#define BAC 2 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = BAC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BAC; + size = sizeNew; } #define BCA 3 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = BCA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BCA; + size = sizeNew; } #define CBA 4 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = CBA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CBA; + size = sizeNew; } #define CAB 5 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = CAB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CAB; + size = sizeNew; } #define ACB 6 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = ACB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = ACB; + size = sizeNew; } /* Now take the shortest route to the best permuytation. @@ -399,7 +427,7 @@ ddPermuteWindow3( case ACB: break; case BAC: if (!cuddSwapInPlace(table,y,z)) return(0); case CAB: if (!cuddSwapInPlace(table,x,y)) return(0); - break; + break; default: return(0); } @@ -441,15 +469,15 @@ ddWindow3( if (high-low < 2) return(ddWindow2(table,low,high)); for (x = low; x+1 < high; x++) { - res = ddPermuteWindow3(table,x); - if (res == 0) return(0); + res = ddPermuteWindow3(table,x); + if (res == 0) return(0); #ifdef DD_STATS - if (res == ABC) { - (void) fprintf(table->out,"="); - } else { - (void) fprintf(table->out,"-"); - } - fflush(table->out); + if (res == ABC) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); #endif } @@ -492,60 +520,60 @@ ddWindowConv3( nwin = high-low-1; events = ABC_ALLOC(int,nwin); if (events == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (x=0; x<nwin; x++) { - events[x] = 1; + events[x] = 1; } do { - newevent = 0; - for (x=0; x<nwin; x++) { - if (events[x]) { - res = ddPermuteWindow3(table,x+low); - switch (res) { - case ABC: - break; - case BAC: - if (x < nwin-1) events[x+1] = 1; - if (x > 1) events[x-2] = 1; - newevent = 1; - break; - case BCA: - case CBA: - case CAB: - if (x < nwin-2) events[x+2] = 1; - if (x < nwin-1) events[x+1] = 1; - if (x > 0) events[x-1] = 1; - if (x > 1) events[x-2] = 1; - newevent = 1; - break; - case ACB: - if (x < nwin-2) events[x+2] = 1; - if (x > 0) events[x-1] = 1; - newevent = 1; - break; - default: - ABC_FREE(events); - return(0); - } - events[x] = 0; + newevent = 0; + for (x=0; x<nwin; x++) { + if (events[x]) { + res = ddPermuteWindow3(table,x+low); + switch (res) { + case ABC: + break; + case BAC: + if (x < nwin-1) events[x+1] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + case BCA: + case CBA: + case CAB: + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + case ACB: + if (x < nwin-2) events[x+2] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + break; + default: + ABC_FREE(events); + return(0); + } + events[x] = 0; #ifdef DD_STATS - if (res == ABC) { - (void) fprintf(table->out,"="); - } else { - (void) fprintf(table->out,"-"); - } - fflush(table->out); + if (res == ABC) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); #endif + } } - } #ifdef DD_STATS - if (newevent) { - (void) fprintf(table->out,"|"); - fflush(table->out); - } + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } #endif } while (newevent); @@ -575,8 +603,8 @@ ddPermuteWindow4( int w) { int x,y,z; - int size,sizeNew; - int best; + int size,sizeNew; + int best; #ifdef DD_DEBUG assert(table->dead == 0); @@ -585,7 +613,7 @@ ddPermuteWindow4( size = table->keys - table->isolated; x = w+1; y = x+1; z = y+1; - + /* The permutation pattern is: * (w,x)(y,z)(w,x)(x,y) * (y,z)(w,x)(y,z)(x,y) @@ -602,166 +630,166 @@ ddPermuteWindow4( #define ABCD 1 best = ABCD; -#define BACD 7 +#define BACD 7 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = BACD; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BACD; + size = sizeNew; } #define BADC 13 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = BADC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BADC; + size = sizeNew; } #define ABDC 8 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size || (sizeNew == size && ABDC < best)) { - if (sizeNew == 0) return(0); - best = ABDC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = ABDC; + size = sizeNew; } #define ADBC 14 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = ADBC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = ADBC; + size = sizeNew; } #define ADCB 9 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && ADCB < best)) { - if (sizeNew == 0) return(0); - best = ADCB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = ADCB; + size = sizeNew; } #define DACB 15 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = DACB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = DACB; + size = sizeNew; } #define DABC 20 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = DABC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = DABC; + size = sizeNew; } #define DBAC 23 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = DBAC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = DBAC; + size = sizeNew; } #define BDAC 19 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size || (sizeNew == size && BDAC < best)) { - if (sizeNew == 0) return(0); - best = BDAC; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BDAC; + size = sizeNew; } #define BDCA 21 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && BDCA < best)) { - if (sizeNew == 0) return(0); - best = BDCA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BDCA; + size = sizeNew; } #define DBCA 24 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size) { - if (sizeNew == 0) return(0); - best = DBCA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = DBCA; + size = sizeNew; } #define DCBA 22 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size || (sizeNew == size && DCBA < best)) { - if (sizeNew == 0) return(0); - best = DCBA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = DCBA; + size = sizeNew; } #define DCAB 18 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && DCAB < best)) { - if (sizeNew == 0) return(0); - best = DCAB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = DCAB; + size = sizeNew; } #define CDAB 12 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size || (sizeNew == size && CDAB < best)) { - if (sizeNew == 0) return(0); - best = CDAB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CDAB; + size = sizeNew; } #define CDBA 17 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && CDBA < best)) { - if (sizeNew == 0) return(0); - best = CDBA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CDBA; + size = sizeNew; } #define CBDA 11 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size || (sizeNew == size && CBDA < best)) { - if (sizeNew == 0) return(0); - best = CBDA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CBDA; + size = sizeNew; } #define BCDA 16 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size || (sizeNew == size && BCDA < best)) { - if (sizeNew == 0) return(0); - best = BCDA; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BCDA; + size = sizeNew; } #define BCAD 10 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && BCAD < best)) { - if (sizeNew == 0) return(0); - best = BCAD; - size = sizeNew; + if (sizeNew == 0) return(0); + best = BCAD; + size = sizeNew; } #define CBAD 5 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size || (sizeNew == size && CBAD < best)) { - if (sizeNew == 0) return(0); - best = CBAD; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CBAD; + size = sizeNew; } #define CABD 3 sizeNew = cuddSwapInPlace(table,x,y); if (sizeNew < size || (sizeNew == size && CABD < best)) { - if (sizeNew == 0) return(0); - best = CABD; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CABD; + size = sizeNew; } #define CADB 6 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && CADB < best)) { - if (sizeNew == 0) return(0); - best = CADB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = CADB; + size = sizeNew; } #define ACDB 4 sizeNew = cuddSwapInPlace(table,w,x); if (sizeNew < size || (sizeNew == size && ACDB < best)) { - if (sizeNew == 0) return(0); - best = ACDB; - size = sizeNew; + if (sizeNew == 0) return(0); + best = ACDB; + size = sizeNew; } #define ACBD 2 sizeNew = cuddSwapInPlace(table,y,z); if (sizeNew < size || (sizeNew == size && ACBD < best)) { - if (sizeNew == 0) return(0); - best = ACBD; - size = sizeNew; + if (sizeNew == 0) return(0); + best = ACBD; + size = sizeNew; } /* Now take the shortest route to the best permutation. @@ -778,29 +806,29 @@ ddPermuteWindow4( case DCBA: if (!cuddSwapInPlace(table,y,z)) return(0); case BCDA: if (!cuddSwapInPlace(table,x,y)) return(0); case CBDA: if (!cuddSwapInPlace(table,w,x)) return(0); - if (!cuddSwapInPlace(table,x,y)) return(0); - if (!cuddSwapInPlace(table,y,z)) return(0); - break; + if (!cuddSwapInPlace(table,x,y)) return(0); + if (!cuddSwapInPlace(table,y,z)) return(0); + break; case DBAC: if (!cuddSwapInPlace(table,x,y)) return(0); case DCAB: if (!cuddSwapInPlace(table,w,x)) return(0); case DACB: if (!cuddSwapInPlace(table,y,z)) return(0); case BACD: if (!cuddSwapInPlace(table,x,y)) return(0); case CABD: if (!cuddSwapInPlace(table,w,x)) return(0); - break; + break; case DABC: if (!cuddSwapInPlace(table,y,z)) return(0); case BADC: if (!cuddSwapInPlace(table,x,y)) return(0); case CADB: if (!cuddSwapInPlace(table,w,x)) return(0); - if (!cuddSwapInPlace(table,y,z)) return(0); - break; + if (!cuddSwapInPlace(table,y,z)) return(0); + break; case BDAC: if (!cuddSwapInPlace(table,x,y)) return(0); case CDAB: if (!cuddSwapInPlace(table,w,x)) return(0); case ADCB: if (!cuddSwapInPlace(table,y,z)) return(0); case ABCD: if (!cuddSwapInPlace(table,x,y)) return(0); - break; + break; case BCAD: if (!cuddSwapInPlace(table,x,y)) return(0); case CBAD: if (!cuddSwapInPlace(table,w,x)) return(0); - if (!cuddSwapInPlace(table,x,y)) return(0); - break; + if (!cuddSwapInPlace(table,x,y)) return(0); + break; default: return(0); } @@ -842,15 +870,15 @@ ddWindow4( if (high-low < 3) return(ddWindow3(table,low,high)); for (w = low; w+2 < high; w++) { - res = ddPermuteWindow4(table,w); - if (res == 0) return(0); + res = ddPermuteWindow4(table,w); + if (res == 0) return(0); #ifdef DD_STATS - if (res == ABCD) { - (void) fprintf(table->out,"="); - } else { - (void) fprintf(table->out,"-"); - } - fflush(table->out); + if (res == ABCD) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); #endif } @@ -893,102 +921,102 @@ ddWindowConv4( nwin = high-low-2; events = ABC_ALLOC(int,nwin); if (events == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (x=0; x<nwin; x++) { - events[x] = 1; + events[x] = 1; } do { - newevent = 0; - for (x=0; x<nwin; x++) { - if (events[x]) { - res = ddPermuteWindow4(table,x+low); - switch (res) { - case ABCD: - break; - case BACD: - if (x < nwin-1) events[x+1] = 1; - if (x > 2) events[x-3] = 1; - newevent = 1; - break; - case BADC: - if (x < nwin-3) events[x+3] = 1; - if (x < nwin-1) events[x+1] = 1; - if (x > 0) events[x-1] = 1; - if (x > 2) events[x-3] = 1; - newevent = 1; - break; - case ABDC: - if (x < nwin-3) events[x+3] = 1; - if (x > 0) events[x-1] = 1; - newevent = 1; - break; - case ADBC: - case ADCB: - case ACDB: - if (x < nwin-3) events[x+3] = 1; - if (x < nwin-2) events[x+2] = 1; - if (x > 0) events[x-1] = 1; - if (x > 1) events[x-2] = 1; - newevent = 1; - break; - case DACB: - case DABC: - case DBAC: - case BDAC: - case BDCA: - case DBCA: - case DCBA: - case DCAB: - case CDAB: - case CDBA: - case CBDA: - case BCDA: - case CADB: - if (x < nwin-3) events[x+3] = 1; - if (x < nwin-2) events[x+2] = 1; - if (x < nwin-1) events[x+1] = 1; - if (x > 0) events[x-1] = 1; - if (x > 1) events[x-2] = 1; - if (x > 2) events[x-3] = 1; - newevent = 1; - break; - case BCAD: - case CBAD: - case CABD: - if (x < nwin-2) events[x+2] = 1; - if (x < nwin-1) events[x+1] = 1; - if (x > 1) events[x-2] = 1; - if (x > 2) events[x-3] = 1; - newevent = 1; - break; - case ACBD: - if (x < nwin-2) events[x+2] = 1; - if (x > 1) events[x-2] = 1; - newevent = 1; - break; - default: - ABC_FREE(events); - return(0); - } - events[x] = 0; + newevent = 0; + for (x=0; x<nwin; x++) { + if (events[x]) { + res = ddPermuteWindow4(table,x+low); + switch (res) { + case ABCD: + break; + case BACD: + if (x < nwin-1) events[x+1] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case BADC: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case ABDC: + if (x < nwin-3) events[x+3] = 1; + if (x > 0) events[x-1] = 1; + newevent = 1; + break; + case ADBC: + case ADCB: + case ACDB: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-2) events[x+2] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + case DACB: + case DABC: + case DBAC: + case BDAC: + case BDCA: + case DBCA: + case DCBA: + case DCAB: + case CDAB: + case CDBA: + case CBDA: + case BCDA: + case CADB: + if (x < nwin-3) events[x+3] = 1; + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 0) events[x-1] = 1; + if (x > 1) events[x-2] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case BCAD: + case CBAD: + case CABD: + if (x < nwin-2) events[x+2] = 1; + if (x < nwin-1) events[x+1] = 1; + if (x > 1) events[x-2] = 1; + if (x > 2) events[x-3] = 1; + newevent = 1; + break; + case ACBD: + if (x < nwin-2) events[x+2] = 1; + if (x > 1) events[x-2] = 1; + newevent = 1; + break; + default: + ABC_FREE(events); + return(0); + } + events[x] = 0; #ifdef DD_STATS - if (res == ABCD) { - (void) fprintf(table->out,"="); - } else { - (void) fprintf(table->out,"-"); - } - fflush(table->out); + if (res == ABCD) { + (void) fprintf(table->out,"="); + } else { + (void) fprintf(table->out,"-"); + } + fflush(table->out); #endif + } } - } #ifdef DD_STATS - if (newevent) { - (void) fprintf(table->out,"|"); - fflush(table->out); - } + if (newevent) { + (void) fprintf(table->out,"|"); + fflush(table->out); + } #endif } while (newevent); @@ -998,5 +1026,6 @@ ddWindowConv4( } /* end of ddWindowConv4 */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddZddCount.c b/src/bdd/cudd/cuddZddCount.c index 8f974e5e..a422ad99 100644 --- a/src/bdd/cudd/cuddZddCount.c +++ b/src/bdd/cudd/cuddZddCount.c @@ -7,39 +7,67 @@ Synopsis [Procedures to count the number of minterms of a ZDD.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddCount(); - <li> Cudd_zddCountDouble(); - </ul> - Internal procedures included in this module: - <ul> - </ul> - Static procedures included in this module: - <ul> - <li> cuddZddCountStep(); - <li> cuddZddCountDoubleStep(); - <li> st_zdd_count_dbl_free() - <li> st_zdd_countfree() - </ul> - ] + <ul> + <li> Cudd_zddCount(); + <li> Cudd_zddCountDouble(); + </ul> + Internal procedures included in this module: + <ul> + </ul> + Static procedures included in this module: + <ul> + <li> cuddZddCountStep(); + <li> cuddZddCountDoubleStep(); + <li> st_zdd_count_dbl_free() + <li> st_zdd_countfree() + </ul> + ] SeeAlso [] Author [Hyong-Kyoon Shin, In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -60,13 +88,16 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.14 2004/08/13 18:04:53 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -74,13 +105,16 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddCount.c,v 1.1.1.1 2003/02/24 22:23: /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int cuddZddCountStep ARGS((DdNode *P, st_table *table, DdNode *base, DdNode *empty)); -static double cuddZddCountDoubleStep ARGS((DdNode *P, st_table *table, DdNode *base, DdNode *empty)); -static enum st_retval st_zdd_countfree ARGS((char *key, char *value, char *arg)); -static enum st_retval st_zdd_count_dbl_free ARGS((char *key, char *value, char *arg)); +static int cuddZddCountStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty); +static double cuddZddCountDoubleStep (DdNode *P, st_table *table, DdNode *base, DdNode *empty); +static enum st_retval st_zdd_countfree (char *key, char *value, char *arg); +static enum st_retval st_zdd_count_dbl_free (char *key, char *value, char *arg); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -105,8 +139,8 @@ Cudd_zddCount( DdNode * P) { st_table *table; - int res; - DdNode *base, *empty; + int res; + DdNode *base, *empty; base = DD_ONE(zdd); empty = DD_ZERO(zdd); @@ -114,9 +148,9 @@ Cudd_zddCount( if (table == NULL) return(CUDD_OUT_OF_MEM); res = cuddZddCountStep(P, table, base, empty); if (res == CUDD_OUT_OF_MEM) { - zdd->errorCode = CUDD_MEMORY_OUT; + zdd->errorCode = CUDD_MEMORY_OUT; } - st_foreach(table, (ST_PFSR)st_zdd_countfree, NIL(char)); + st_foreach(table, st_zdd_countfree, NIL(char)); st_free_table(table); return(res); @@ -144,8 +178,8 @@ Cudd_zddCountDouble( DdNode * P) { st_table *table; - double res; - DdNode *base, *empty; + double res; + DdNode *base, *empty; base = DD_ONE(zdd); empty = DD_ZERO(zdd); @@ -153,9 +187,9 @@ Cudd_zddCountDouble( if (table == NULL) return((double)CUDD_OUT_OF_MEM); res = cuddZddCountDoubleStep(P, table, base, empty); if (res == (double)CUDD_OUT_OF_MEM) { - zdd->errorCode = CUDD_MEMORY_OUT; + zdd->errorCode = CUDD_MEMORY_OUT; } - st_foreach(table, (ST_PFSR)st_zdd_count_dbl_free, NIL(char)); + st_foreach(table, st_zdd_count_dbl_free, NIL(char)); st_free_table(table); return(res); @@ -191,31 +225,31 @@ cuddZddCountStep( DdNode * base, DdNode * empty) { - int res; - int *dummy; + int res; + int *dummy; if (P == empty) - return(0); + return(0); if (P == base) - return(1); + return(1); /* Check cache. */ - if (st_lookup(table, (char *)P, (char **)(&dummy))) { - res = *dummy; - return(res); + if (st_lookup(table, (const char *)P, (char **)&dummy)) { + res = *dummy; + return(res); } res = cuddZddCountStep(cuddE(P), table, base, empty) + - cuddZddCountStep(cuddT(P), table, base, empty); + cuddZddCountStep(cuddT(P), table, base, empty); dummy = ABC_ALLOC(int, 1); if (dummy == NULL) { - return(CUDD_OUT_OF_MEM); + return(CUDD_OUT_OF_MEM); } *dummy = res; if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) { - ABC_FREE(dummy); - return(CUDD_OUT_OF_MEM); + ABC_FREE(dummy); + return(CUDD_OUT_OF_MEM); } return(res); @@ -241,31 +275,31 @@ cuddZddCountDoubleStep( DdNode * base, DdNode * empty) { - double res; - double *dummy; + double res; + double *dummy; if (P == empty) - return((double)0.0); + return((double)0.0); if (P == base) - return((double)1.0); + return((double)1.0); /* Check cache */ - if (st_lookup(table, (char *)P, (char **)(&dummy))) { - res = *dummy; - return(res); + if (st_lookup(table, (const char *)P, (char **)&dummy)) { + res = *dummy; + return(res); } res = cuddZddCountDoubleStep(cuddE(P), table, base, empty) + - cuddZddCountDoubleStep(cuddT(P), table, base, empty); + cuddZddCountDoubleStep(cuddT(P), table, base, empty); dummy = ABC_ALLOC(double, 1); if (dummy == NULL) { - return((double)CUDD_OUT_OF_MEM); + return((double)CUDD_OUT_OF_MEM); } *dummy = res; if (st_insert(table, (char *)P, (char *)dummy) == ST_OUT_OF_MEM) { - ABC_FREE(dummy); - return((double)CUDD_OUT_OF_MEM); + ABC_FREE(dummy); + return((double)CUDD_OUT_OF_MEM); } return(res); @@ -291,7 +325,7 @@ st_zdd_countfree( char * value, char * arg) { - int *d; + int *d; d = (int *)value; ABC_FREE(d); @@ -318,12 +352,14 @@ st_zdd_count_dbl_free( char * value, char * arg) { - double *d; + double *d; d = (double *)value; ABC_FREE(d); return(ST_CONTINUE); } /* end of st_zdd_count_dbl_free */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddZddFuncs.c b/src/bdd/cudd/cuddZddFuncs.c index 2560159c..41f7c64c 100644 --- a/src/bdd/cudd/cuddZddFuncs.c +++ b/src/bdd/cudd/cuddZddFuncs.c @@ -7,53 +7,81 @@ Synopsis [Functions to manipulate covers represented as ZDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddProduct(); - <li> Cudd_zddUnateProduct(); - <li> Cudd_zddWeakDiv(); - <li> Cudd_zddWeakDivF(); - <li> Cudd_zddDivide(); - <li> Cudd_zddDivideF(); - <li> Cudd_zddComplement(); - </ul> - Internal procedures included in this module: - <ul> - <li> cuddZddProduct(); - <li> cuddZddUnateProduct(); - <li> cuddZddWeakDiv(); - <li> cuddZddWeakDivF(); - <li> cuddZddDivide(); - <li> cuddZddDivideF(); - <li> cuddZddGetCofactors3() - <li> cuddZddGetCofactors2() - <li> cuddZddComplement(); - <li> cuddZddGetPosVarIndex(); - <li> cuddZddGetNegVarIndex(); - <li> cuddZddGetPosVarLevel(); - <li> cuddZddGetNegVarLevel(); - </ul> - Static procedures included in this module: - <ul> - </ul> - ] + <ul> + <li> Cudd_zddProduct(); + <li> Cudd_zddUnateProduct(); + <li> Cudd_zddWeakDiv(); + <li> Cudd_zddWeakDivF(); + <li> Cudd_zddDivide(); + <li> Cudd_zddDivideF(); + <li> Cudd_zddComplement(); + </ul> + Internal procedures included in this module: + <ul> + <li> cuddZddProduct(); + <li> cuddZddUnateProduct(); + <li> cuddZddWeakDiv(); + <li> cuddZddWeakDivF(); + <li> cuddZddDivide(); + <li> cuddZddDivideF(); + <li> cuddZddGetCofactors3() + <li> cuddZddGetCofactors2() + <li> cuddZddComplement(); + <li> cuddZddGetPosVarIndex(); + <li> cuddZddGetNegVarIndex(); + <li> cuddZddGetPosVarLevel(); + <li> cuddZddGetNegVarLevel(); + </ul> + Static procedures included in this module: + <ul> + </ul> + ] SeeAlso [] Author [In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -74,7 +102,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddFuncs.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddFuncs.c,v 1.16 2008/04/25 07:39:33 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -113,17 +141,17 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddFuncs.c,v 1.1.1.1 2003/02/24 22:23: SeeAlso [Cudd_zddUnateProduct] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddProduct( DdManager * dd, DdNode * f, DdNode * g) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddZddProduct(dd, f, g); + dd->reordered = 0; + res = cuddZddProduct(dd, f, g); } while (dd->reordered == 1); return(res); @@ -144,17 +172,17 @@ Cudd_zddProduct( SeeAlso [Cudd_zddProduct] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddUnateProduct( DdManager * dd, DdNode * f, DdNode * g) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddZddUnateProduct(dd, f, g); + dd->reordered = 0; + res = cuddZddUnateProduct(dd, f, g); } while (dd->reordered == 1); return(res); @@ -178,17 +206,17 @@ Cudd_zddUnateProduct( SeeAlso [Cudd_zddDivide] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddWeakDiv( DdManager * dd, DdNode * f, DdNode * g) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddZddWeakDiv(dd, f, g); + dd->reordered = 0; + res = cuddZddWeakDiv(dd, f, g); } while (dd->reordered == 1); return(res); @@ -209,17 +237,17 @@ Cudd_zddWeakDiv( SeeAlso [Cudd_zddWeakDiv] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddDivide( DdManager * dd, DdNode * f, DdNode * g) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddZddDivide(dd, f, g); + dd->reordered = 0; + res = cuddZddDivide(dd, f, g); } while (dd->reordered == 1); return(res); @@ -238,17 +266,17 @@ Cudd_zddDivide( SeeAlso [Cudd_zddWeakDiv] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddWeakDivF( DdManager * dd, DdNode * f, DdNode * g) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddZddWeakDivF(dd, f, g); + dd->reordered = 0; + res = cuddZddWeakDivF(dd, f, g); } while (dd->reordered == 1); return(res); @@ -267,17 +295,17 @@ Cudd_zddWeakDivF( SeeAlso [] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddDivideF( DdManager * dd, DdNode * f, DdNode * g) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddZddDivideF(dd, f, g); + dd->reordered = 0; + res = cuddZddDivideF(dd, f, g); } while (dd->reordered == 1); return(res); @@ -300,26 +328,26 @@ Cudd_zddDivideF( SeeAlso [] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddComplement( DdManager *dd, DdNode *node) { - DdNode *b, *isop, *zdd_I; + DdNode *b, *isop, *zdd_I; /* Check cache */ zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node); if (zdd_I) - return(zdd_I); + return(zdd_I); b = Cudd_MakeBddFromZddCover(dd, node); if (!b) - return(NULL); + return(NULL); Cudd_Ref(b); isop = Cudd_zddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I); if (!isop) { - Cudd_RecursiveDeref(dd, b); - return(NULL); + Cudd_RecursiveDeref(dd, b); + return(NULL); } Cudd_Ref(isop); Cudd_Ref(zdd_I); @@ -348,21 +376,21 @@ Cudd_zddComplement( SeeAlso [Cudd_zddProduct] ******************************************************************************/ -DdNode * +DdNode * cuddZddProduct( DdManager * dd, DdNode * f, DdNode * g) { - int v, top_f, top_g; - DdNode *tmp, *term1, *term2, *term3; - DdNode *f0, *f1, *fd, *g0, *g1, *gd; - DdNode *R0, *R1, *Rd, *N0, *N1; - DdNode *r; - DdNode *one = DD_ONE(dd); - DdNode *zero = DD_ZERO(dd); - int flag; - int pv, nv; + int v, top_f, top_g; + DdNode *tmp, *term1, *term2, *term3; + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *R0, *R1, *Rd, *N0, *N1; + DdNode *r; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + int flag; + int pv, nv; statLine(dd); if (f == zero || g == zero) @@ -376,26 +404,26 @@ cuddZddProduct( top_g = dd->permZ[g->index]; if (top_f > top_g) - return(cuddZddProduct(dd, g, f)); + return(cuddZddProduct(dd, g, f)); /* Check cache */ r = cuddCacheLookup2Zdd(dd, cuddZddProduct, f, g); if (r) - return(r); + return(r); - v = f->index; /* either yi or zi */ + v = f->index; /* either yi or zi */ flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); if (flag == 1) - return(NULL); + return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); Cudd_Ref(fd); flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); if (flag == 1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); } Cudd_Ref(g1); Cudd_Ref(g0); @@ -405,95 +433,95 @@ cuddZddProduct( Rd = cuddZddProduct(dd, fd, gd); if (Rd == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); } Cudd_Ref(Rd); term1 = cuddZddProduct(dd, f0, g0); if (term1 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, Rd); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + return(NULL); } Cudd_Ref(term1); term2 = cuddZddProduct(dd, f0, gd); if (term2 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, Rd); - Cudd_RecursiveDerefZdd(dd, term1); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); } Cudd_Ref(term2); term3 = cuddZddProduct(dd, fd, g0); if (term3 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, Rd); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); } Cudd_Ref(term3); Cudd_RecursiveDerefZdd(dd, f0); Cudd_RecursiveDerefZdd(dd, g0); tmp = cuddZddUnion(dd, term1, term2); if (tmp == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, Rd); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - Cudd_RecursiveDerefZdd(dd, term3); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); } Cudd_Ref(tmp); Cudd_RecursiveDerefZdd(dd, term1); Cudd_RecursiveDerefZdd(dd, term2); R0 = cuddZddUnion(dd, tmp, term3); if (R0 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, Rd); - Cudd_RecursiveDerefZdd(dd, term3); - Cudd_RecursiveDerefZdd(dd, tmp); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); } Cudd_Ref(R0); Cudd_RecursiveDerefZdd(dd, tmp); Cudd_RecursiveDerefZdd(dd, term3); N0 = cuddZddGetNode(dd, nv, R0, Rd); /* nv = zi */ if (N0 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, Rd); - Cudd_RecursiveDerefZdd(dd, R0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, Rd); + Cudd_RecursiveDerefZdd(dd, R0); + return(NULL); } Cudd_Ref(N0); Cudd_RecursiveDerefZdd(dd, R0); @@ -501,35 +529,35 @@ cuddZddProduct( term1 = cuddZddProduct(dd, f1, g1); if (term1 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, N0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + return(NULL); } Cudd_Ref(term1); term2 = cuddZddProduct(dd, f1, gd); if (term2 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, N0); - Cudd_RecursiveDerefZdd(dd, term1); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); } Cudd_Ref(term2); term3 = cuddZddProduct(dd, fd, g1); if (term3 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, gd); - Cudd_RecursiveDerefZdd(dd, N0); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); } Cudd_Ref(term3); Cudd_RecursiveDerefZdd(dd, f1); @@ -538,30 +566,30 @@ cuddZddProduct( Cudd_RecursiveDerefZdd(dd, gd); tmp = cuddZddUnion(dd, term1, term2); if (tmp == NULL) { - Cudd_RecursiveDerefZdd(dd, N0); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - Cudd_RecursiveDerefZdd(dd, term3); - return(NULL); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); } Cudd_Ref(tmp); Cudd_RecursiveDerefZdd(dd, term1); Cudd_RecursiveDerefZdd(dd, term2); R1 = cuddZddUnion(dd, tmp, term3); if (R1 == NULL) { - Cudd_RecursiveDerefZdd(dd, N0); - Cudd_RecursiveDerefZdd(dd, term3); - Cudd_RecursiveDerefZdd(dd, tmp); - return(NULL); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); } Cudd_Ref(R1); Cudd_RecursiveDerefZdd(dd, tmp); Cudd_RecursiveDerefZdd(dd, term3); N1 = cuddZddGetNode(dd, pv, R1, N0); /* pv = yi */ if (N1 == NULL) { - Cudd_RecursiveDerefZdd(dd, N0); - Cudd_RecursiveDerefZdd(dd, R1); - return(NULL); + Cudd_RecursiveDerefZdd(dd, N0); + Cudd_RecursiveDerefZdd(dd, R1); + return(NULL); } Cudd_Ref(N1); Cudd_RecursiveDerefZdd(dd, R1); @@ -585,20 +613,20 @@ cuddZddProduct( SeeAlso [Cudd_zddUnateProduct] ******************************************************************************/ -DdNode * +DdNode * cuddZddUnateProduct( DdManager * dd, DdNode * f, DdNode * g) { - int v, top_f, top_g; - DdNode *term1, *term2, *term3, *term4; - DdNode *sum1, *sum2; - DdNode *f0, *f1, *g0, *g1; - DdNode *r; - DdNode *one = DD_ONE(dd); - DdNode *zero = DD_ZERO(dd); - int flag; + int v, top_f, top_g; + DdNode *term1, *term2, *term3, *term4; + DdNode *sum1, *sum2; + DdNode *f0, *f1, *g0, *g1; + DdNode *r; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + int flag; statLine(dd); if (f == zero || g == zero) @@ -612,68 +640,68 @@ cuddZddUnateProduct( top_g = dd->permZ[g->index]; if (top_f > top_g) - return(cuddZddUnateProduct(dd, g, f)); + return(cuddZddUnateProduct(dd, g, f)); /* Check cache */ r = cuddCacheLookup2Zdd(dd, cuddZddUnateProduct, f, g); if (r) - return(r); + return(r); - v = f->index; /* either yi or zi */ + v = f->index; /* either yi or zi */ flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); if (flag == 1) - return(NULL); + return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); if (flag == 1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); } Cudd_Ref(g1); Cudd_Ref(g0); term1 = cuddZddUnateProduct(dd, f1, g1); if (term1 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); } Cudd_Ref(term1); term2 = cuddZddUnateProduct(dd, f1, g0); if (term2 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, term1); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); } Cudd_Ref(term2); term3 = cuddZddUnateProduct(dd, f0, g1); if (term3 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + return(NULL); } Cudd_Ref(term3); term4 = cuddZddUnateProduct(dd, f0, g0); if (term4 == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - Cudd_RecursiveDerefZdd(dd, term3); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + return(NULL); } Cudd_Ref(term4); Cudd_RecursiveDerefZdd(dd, f1); @@ -682,30 +710,30 @@ cuddZddUnateProduct( Cudd_RecursiveDerefZdd(dd, g0); sum1 = cuddZddUnion(dd, term1, term2); if (sum1 == NULL) { - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term2); - Cudd_RecursiveDerefZdd(dd, term3); - Cudd_RecursiveDerefZdd(dd, term4); - return(NULL); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term2); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, term4); + return(NULL); } Cudd_Ref(sum1); Cudd_RecursiveDerefZdd(dd, term1); Cudd_RecursiveDerefZdd(dd, term2); sum2 = cuddZddUnion(dd, sum1, term3); if (sum2 == NULL) { - Cudd_RecursiveDerefZdd(dd, term3); - Cudd_RecursiveDerefZdd(dd, term4); - Cudd_RecursiveDerefZdd(dd, sum1); - return(NULL); + Cudd_RecursiveDerefZdd(dd, term3); + Cudd_RecursiveDerefZdd(dd, term4); + Cudd_RecursiveDerefZdd(dd, sum1); + return(NULL); } Cudd_Ref(sum2); Cudd_RecursiveDerefZdd(dd, sum1); Cudd_RecursiveDerefZdd(dd, term3); r = cuddZddGetNode(dd, v, sum2, term4); if (r == NULL) { - Cudd_RecursiveDerefZdd(dd, term4); - Cudd_RecursiveDerefZdd(dd, sum2); - return(NULL); + Cudd_RecursiveDerefZdd(dd, term4); + Cudd_RecursiveDerefZdd(dd, sum2); + return(NULL); } Cudd_Ref(r); Cudd_RecursiveDerefZdd(dd, sum2); @@ -729,47 +757,47 @@ cuddZddUnateProduct( SeeAlso [Cudd_zddWeakDiv] ******************************************************************************/ -DdNode * +DdNode * cuddZddWeakDiv( DdManager * dd, DdNode * f, DdNode * g) { - int v; - DdNode *one = DD_ONE(dd); - DdNode *zero = DD_ZERO(dd); - DdNode *f0, *f1, *fd, *g0, *g1, *gd; - DdNode *q, *tmp; - DdNode *r; - int flag; + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *q, *tmp; + DdNode *r; + int flag; statLine(dd); if (g == one) - return(f); + return(f); if (f == zero || f == one) - return(zero); + return(zero); if (f == g) - return(one); + return(one); /* Check cache. */ r = cuddCacheLookup2Zdd(dd, cuddZddWeakDiv, f, g); if (r) - return(r); + return(r); v = g->index; flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); if (flag == 1) - return(NULL); + return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); Cudd_Ref(fd); flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); if (flag == 1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); } Cudd_Ref(g1); Cudd_Ref(g0); @@ -778,98 +806,98 @@ cuddZddWeakDiv( q = g; if (g0 != zero) { - q = cuddZddWeakDiv(dd, f0, g0); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); - } - Cudd_Ref(q); + q = cuddZddWeakDiv(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); } else - Cudd_Ref(q); + Cudd_Ref(q); Cudd_RecursiveDerefZdd(dd, f0); Cudd_RecursiveDerefZdd(dd, g0); if (q == zero) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); - Cudd_Deref(q); - return(zero); - } - - if (g1 != zero) { - Cudd_RecursiveDerefZdd(dd, q); - tmp = cuddZddWeakDiv(dd, f1, g1); - if (tmp == NULL) { Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, g1); Cudd_RecursiveDerefZdd(dd, fd); Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); + Cudd_Deref(q); + return(zero); } - Cudd_Ref(tmp); - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, g1); - if (q == g) - q = tmp; - else { - q = cuddZddIntersect(dd, q, tmp); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); + + if (g1 != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDiv(dd, f1, g1); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); } - Cudd_Ref(q); - Cudd_RecursiveDerefZdd(dd, tmp); - } } else { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); } if (q == zero) { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); - Cudd_Deref(q); - return(zero); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero); + Cudd_Deref(q); + return(zero); } if (gd != zero) { - Cudd_RecursiveDerefZdd(dd, q); - tmp = cuddZddWeakDiv(dd, fd, gd); - if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDiv(dd, fd, gd); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); Cudd_RecursiveDerefZdd(dd, fd); Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); - } - Cudd_Ref(tmp); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - if (q == g) - q = tmp; - else { - q = cuddZddIntersect(dd, q, tmp); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, tmp); - return(NULL); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); } - Cudd_Ref(q); - Cudd_RecursiveDerefZdd(dd, tmp); - } } else { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); } cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, q); @@ -890,34 +918,34 @@ cuddZddWeakDiv( SeeAlso [Cudd_zddWeakDivF] ******************************************************************************/ -DdNode * +DdNode * cuddZddWeakDivF( DdManager * dd, DdNode * f, DdNode * g) { - int v, top_f, top_g, vf, vg; - DdNode *one = DD_ONE(dd); - DdNode *zero = DD_ZERO(dd); - DdNode *f0, *f1, *fd, *g0, *g1, *gd; - DdNode *q, *tmp; - DdNode *r; - DdNode *term1, *term0, *termd; - int flag; - int pv, nv; + int v, top_f, top_g, vf, vg; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *fd, *g0, *g1, *gd; + DdNode *q, *tmp; + DdNode *r; + DdNode *term1, *term0, *termd; + int flag; + int pv, nv; statLine(dd); if (g == one) - return(f); + return(f); if (f == zero || f == one) - return(zero); + return(zero); if (f == g) - return(one); + return(one); /* Check cache. */ r = cuddCacheLookup2Zdd(dd, cuddZddWeakDivF, f, g); if (r) - return(r); + return(r); top_f = dd->permZ[f->index]; top_g = dd->permZ[g->index]; @@ -926,87 +954,87 @@ cuddZddWeakDivF( v = ddMin(top_f, top_g); if (v == top_f && vf < vg) { - v = f->index; - flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); - if (flag == 1) - return(NULL); - Cudd_Ref(f1); - Cudd_Ref(f0); - Cudd_Ref(fd); - - pv = cuddZddGetPosVarIndex(dd, v); - nv = cuddZddGetNegVarIndex(dd, v); - - term1 = cuddZddWeakDivF(dd, f1, g); - if (term1 == NULL) { + v = f->index; + flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); + if (flag == 1) + return(NULL); + Cudd_Ref(f1); + Cudd_Ref(f0); + Cudd_Ref(fd); + + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + term1 = cuddZddWeakDivF(dd, f1, g); + if (term1 == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); + } + Cudd_Ref(term1); Cudd_RecursiveDerefZdd(dd, f1); + term0 = cuddZddWeakDivF(dd, f0, g); + if (term0 == NULL) { + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, term1); + return(NULL); + } + Cudd_Ref(term0); Cudd_RecursiveDerefZdd(dd, f0); + termd = cuddZddWeakDivF(dd, fd, g); + if (termd == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term0); + return(NULL); + } + Cudd_Ref(termd); Cudd_RecursiveDerefZdd(dd, fd); - return(NULL); - } - Cudd_Ref(term1); - Cudd_RecursiveDerefZdd(dd, f1); - term0 = cuddZddWeakDivF(dd, f0, g); - if (term0 == NULL) { - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, term1); - return(NULL); - } - Cudd_Ref(term0); - Cudd_RecursiveDerefZdd(dd, f0); - termd = cuddZddWeakDivF(dd, fd, g); - if (termd == NULL) { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, term0); - return(NULL); - } - Cudd_Ref(termd); - Cudd_RecursiveDerefZdd(dd, fd); - tmp = cuddZddGetNode(dd, nv, term0, termd); /* nv = zi */ - if (tmp == NULL) { - Cudd_RecursiveDerefZdd(dd, term1); + tmp = cuddZddGetNode(dd, nv, term0, termd); /* nv = zi */ + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, term0); + Cudd_RecursiveDerefZdd(dd, termd); + return(NULL); + } + Cudd_Ref(tmp); Cudd_RecursiveDerefZdd(dd, term0); Cudd_RecursiveDerefZdd(dd, termd); - return(NULL); - } - Cudd_Ref(tmp); - Cudd_RecursiveDerefZdd(dd, term0); - Cudd_RecursiveDerefZdd(dd, termd); - q = cuddZddGetNode(dd, pv, term1, tmp); /* pv = yi */ - if (q == NULL) { + q = cuddZddGetNode(dd, pv, term1, tmp); /* pv = yi */ + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, term1); + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); Cudd_RecursiveDerefZdd(dd, term1); Cudd_RecursiveDerefZdd(dd, tmp); - return(NULL); - } - Cudd_Ref(q); - Cudd_RecursiveDerefZdd(dd, term1); - Cudd_RecursiveDerefZdd(dd, tmp); - cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q); - Cudd_Deref(q); - return(q); + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q); + Cudd_Deref(q); + return(q); } if (v == top_f) - v = f->index; + v = f->index; else - v = g->index; + v = g->index; flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd); if (flag == 1) - return(NULL); + return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); Cudd_Ref(fd); flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd); if (flag == 1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); } Cudd_Ref(g1); Cudd_Ref(g0); @@ -1015,98 +1043,98 @@ cuddZddWeakDivF( q = g; if (g0 != zero) { - q = cuddZddWeakDivF(dd, f0, g0); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); - } - Cudd_Ref(q); + q = cuddZddWeakDivF(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); } else - Cudd_Ref(q); + Cudd_Ref(q); Cudd_RecursiveDerefZdd(dd, f0); Cudd_RecursiveDerefZdd(dd, g0); if (q == zero) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); - Cudd_Deref(q); - return(zero); - } - - if (g1 != zero) { - Cudd_RecursiveDerefZdd(dd, q); - tmp = cuddZddWeakDivF(dd, f1, g1); - if (tmp == NULL) { Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, g1); Cudd_RecursiveDerefZdd(dd, fd); Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); + Cudd_Deref(q); + return(zero); } - Cudd_Ref(tmp); - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, g1); - if (q == g) - q = tmp; - else { - q = cuddZddIntersect(dd, q, tmp); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); + + if (g1 != zero) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDivF(dd, f1, g1); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); } - Cudd_Ref(q); - Cudd_RecursiveDerefZdd(dd, tmp); - } } else { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, g1); } if (q == zero) { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); - Cudd_Deref(q); - return(zero); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero); + Cudd_Deref(q); + return(zero); } if (gd != zero) { - Cudd_RecursiveDerefZdd(dd, q); - tmp = cuddZddWeakDivF(dd, fd, gd); - if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, q); + tmp = cuddZddWeakDivF(dd, fd, gd); + if (tmp == NULL) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); + return(NULL); + } + Cudd_Ref(tmp); Cudd_RecursiveDerefZdd(dd, fd); Cudd_RecursiveDerefZdd(dd, gd); - return(NULL); - } - Cudd_Ref(tmp); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); - if (q == g) - q = tmp; - else { - q = cuddZddIntersect(dd, q, tmp); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, tmp); - return(NULL); + if (q == g) + q = tmp; + else { + q = cuddZddIntersect(dd, q, tmp); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, tmp); + return(NULL); + } + Cudd_Ref(q); + Cudd_RecursiveDerefZdd(dd, tmp); } - Cudd_Ref(q); - Cudd_RecursiveDerefZdd(dd, tmp); - } } else { - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDerefZdd(dd, gd); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDerefZdd(dd, gd); } cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q); @@ -1127,81 +1155,81 @@ cuddZddWeakDivF( SeeAlso [Cudd_zddDivide] ******************************************************************************/ -DdNode * +DdNode * cuddZddDivide( DdManager * dd, DdNode * f, DdNode * g) { - int v; - DdNode *one = DD_ONE(dd); - DdNode *zero = DD_ZERO(dd); - DdNode *f0, *f1, *g0, *g1; - DdNode *q, *r, *tmp; - int flag; + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *g0, *g1; + DdNode *q, *r, *tmp; + int flag; statLine(dd); if (g == one) - return(f); + return(f); if (f == zero || f == one) - return(zero); + return(zero); if (f == g) - return(one); + return(one); /* Check cache. */ r = cuddCacheLookup2Zdd(dd, cuddZddDivide, f, g); if (r) - return(r); + return(r); v = g->index; flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); if (flag == 1) - return(NULL); + return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */ if (flag == 1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); } Cudd_Ref(g1); Cudd_Ref(g0); r = cuddZddDivide(dd, f1, g1); if (r == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - return(NULL); - } - Cudd_Ref(r); - - if (r != zero && g0 != zero) { - tmp = r; - q = cuddZddDivide(dd, f0, g0); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - return(NULL); - } - Cudd_Ref(q); - r = cuddZddIntersect(dd, r, q); - if (r == NULL) { Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, f0); Cudd_RecursiveDerefZdd(dd, g1); Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, q); return(NULL); } Cudd_Ref(r); - Cudd_RecursiveDerefZdd(dd, q); - Cudd_RecursiveDerefZdd(dd, tmp); + + if (r != zero && g0 != zero) { + tmp = r; + q = cuddZddDivide(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(q); + r = cuddZddIntersect(dd, r, q); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, q); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, q); + Cudd_RecursiveDerefZdd(dd, tmp); } Cudd_RecursiveDerefZdd(dd, f1); @@ -1227,81 +1255,81 @@ cuddZddDivide( SeeAlso [Cudd_zddDivideF] ******************************************************************************/ -DdNode * +DdNode * cuddZddDivideF( DdManager * dd, DdNode * f, DdNode * g) { - int v; - DdNode *one = DD_ONE(dd); - DdNode *zero = DD_ZERO(dd); - DdNode *f0, *f1, *g0, *g1; - DdNode *q, *r, *tmp; - int flag; + int v; + DdNode *one = DD_ONE(dd); + DdNode *zero = DD_ZERO(dd); + DdNode *f0, *f1, *g0, *g1; + DdNode *q, *r, *tmp; + int flag; statLine(dd); if (g == one) - return(f); + return(f); if (f == zero || f == one) - return(zero); + return(zero); if (f == g) - return(one); + return(one); /* Check cache. */ r = cuddCacheLookup2Zdd(dd, cuddZddDivideF, f, g); if (r) - return(r); + return(r); v = g->index; flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0); if (flag == 1) - return(NULL); + return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */ if (flag == 1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + return(NULL); } Cudd_Ref(g1); Cudd_Ref(g0); r = cuddZddDivideF(dd, f1, g1); if (r == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - return(NULL); - } - Cudd_Ref(r); - - if (r != zero && g0 != zero) { - tmp = r; - q = cuddZddDivideF(dd, f0, g0); - if (q == NULL) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, g1); - Cudd_RecursiveDerefZdd(dd, g0); - return(NULL); - } - Cudd_Ref(q); - r = cuddZddIntersect(dd, r, q); - if (r == NULL) { Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, f0); Cudd_RecursiveDerefZdd(dd, g1); Cudd_RecursiveDerefZdd(dd, g0); - Cudd_RecursiveDerefZdd(dd, q); return(NULL); } Cudd_Ref(r); - Cudd_RecursiveDerefZdd(dd, q); - Cudd_RecursiveDerefZdd(dd, tmp); + + if (r != zero && g0 != zero) { + tmp = r; + q = cuddZddDivideF(dd, f0, g0); + if (q == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + return(NULL); + } + Cudd_Ref(q); + r = cuddZddIntersect(dd, r, q); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, g1); + Cudd_RecursiveDerefZdd(dd, g0); + Cudd_RecursiveDerefZdd(dd, q); + return(NULL); + } + Cudd_Ref(r); + Cudd_RecursiveDerefZdd(dd, q); + Cudd_RecursiveDerefZdd(dd, tmp); } Cudd_RecursiveDerefZdd(dd, f1); @@ -1321,7 +1349,7 @@ cuddZddDivideF( Synopsis [Computes the three-way decomposition of f w.r.t. v.] Description [Computes the three-way decomposition of function f (represented - by a ZDD) wit respect to variable v.] + by a ZDD) wit respect to variable v. Returns 0 if successful; 1 otherwise.] SideEffects [The results are returned in f1, f0, and fd.] @@ -1337,10 +1365,10 @@ cuddZddGetCofactors3( DdNode ** f0, DdNode ** fd) { - DdNode *pc, *nc; - DdNode *zero = DD_ZERO(dd); - int top, hv, ht, pv, nv; - int level; + DdNode *pc, *nc; + DdNode *zero = DD_ZERO(dd); + int top, hv, ht, pv, nv; + int level; top = dd->permZ[f->index]; level = dd->permZ[v]; @@ -1348,96 +1376,96 @@ cuddZddGetCofactors3( ht = top >> 1; if (hv < ht) { - *f1 = zero; - *f0 = zero; - *fd = f; + *f1 = zero; + *f0 = zero; + *fd = f; } else { - pv = cuddZddGetPosVarIndex(dd, v); - nv = cuddZddGetNegVarIndex(dd, v); - - /* not to create intermediate ZDD node */ - if (cuddZddGetPosVarLevel(dd, v) < cuddZddGetNegVarLevel(dd, v)) { - pc = cuddZddSubset1(dd, f, pv); - if (pc == NULL) - return(1); - Cudd_Ref(pc); - nc = cuddZddSubset0(dd, f, pv); - if (nc == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - return(1); - } - Cudd_Ref(nc); - - *f1 = cuddZddSubset0(dd, pc, nv); - if (*f1 == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - Cudd_RecursiveDerefZdd(dd, nc); - return(1); - } - Cudd_Ref(*f1); - *f0 = cuddZddSubset1(dd, nc, nv); - if (*f0 == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - Cudd_RecursiveDerefZdd(dd, nc); - Cudd_RecursiveDerefZdd(dd, *f1); - return(1); + pv = cuddZddGetPosVarIndex(dd, v); + nv = cuddZddGetNegVarIndex(dd, v); + + /* not to create intermediate ZDD node */ + if (cuddZddGetPosVarLevel(dd, v) < cuddZddGetNegVarLevel(dd, v)) { + pc = cuddZddSubset1(dd, f, pv); + if (pc == NULL) + return(1); + Cudd_Ref(pc); + nc = cuddZddSubset0(dd, f, pv); + if (nc == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + return(1); + } + Cudd_Ref(nc); + + *f1 = cuddZddSubset0(dd, pc, nv); + if (*f1 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + return(1); + } + Cudd_Ref(*f1); + *f0 = cuddZddSubset1(dd, nc, nv); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + return(1); + } + Cudd_Ref(*f0); + + *fd = cuddZddSubset0(dd, nc, nv); + if (*fd == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*fd); + } else { + pc = cuddZddSubset1(dd, f, nv); + if (pc == NULL) + return(1); + Cudd_Ref(pc); + nc = cuddZddSubset0(dd, f, nv); + if (nc == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + return(1); + } + Cudd_Ref(nc); + + *f0 = cuddZddSubset0(dd, pc, pv); + if (*f0 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + return(1); + } + Cudd_Ref(*f0); + *f1 = cuddZddSubset1(dd, nc, pv); + if (*f1 == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*f1); + + *fd = cuddZddSubset0(dd, nc, pv); + if (*fd == NULL) { + Cudd_RecursiveDerefZdd(dd, pc); + Cudd_RecursiveDerefZdd(dd, nc); + Cudd_RecursiveDerefZdd(dd, *f1); + Cudd_RecursiveDerefZdd(dd, *f0); + return(1); + } + Cudd_Ref(*fd); } - Cudd_Ref(*f0); - *fd = cuddZddSubset0(dd, nc, nv); - if (*fd == NULL) { Cudd_RecursiveDerefZdd(dd, pc); Cudd_RecursiveDerefZdd(dd, nc); - Cudd_RecursiveDerefZdd(dd, *f1); - Cudd_RecursiveDerefZdd(dd, *f0); - return(1); - } - Cudd_Ref(*fd); - } else { - pc = cuddZddSubset1(dd, f, nv); - if (pc == NULL) - return(1); - Cudd_Ref(pc); - nc = cuddZddSubset0(dd, f, nv); - if (nc == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - return(1); - } - Cudd_Ref(nc); - - *f0 = cuddZddSubset0(dd, pc, pv); - if (*f0 == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - Cudd_RecursiveDerefZdd(dd, nc); - return(1); - } - Cudd_Ref(*f0); - *f1 = cuddZddSubset1(dd, nc, pv); - if (*f1 == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - Cudd_RecursiveDerefZdd(dd, nc); - Cudd_RecursiveDerefZdd(dd, *f1); - return(1); - } - Cudd_Ref(*f1); - - *fd = cuddZddSubset0(dd, nc, pv); - if (*fd == NULL) { - Cudd_RecursiveDerefZdd(dd, pc); - Cudd_RecursiveDerefZdd(dd, nc); - Cudd_RecursiveDerefZdd(dd, *f1); - Cudd_RecursiveDerefZdd(dd, *f0); - return(1); - } - Cudd_Ref(*fd); - } - - Cudd_RecursiveDerefZdd(dd, pc); - Cudd_RecursiveDerefZdd(dd, nc); - Cudd_Deref(*f1); - Cudd_Deref(*f0); - Cudd_Deref(*fd); + Cudd_Deref(*f1); + Cudd_Deref(*f0); + Cudd_Deref(*fd); } return(0); @@ -1465,11 +1493,11 @@ cuddZddGetCofactors2( { *f1 = cuddZddSubset1(dd, f, v); if (*f1 == NULL) - return(1); + return(1); *f0 = cuddZddSubset0(dd, f, v); if (*f0 == NULL) { - Cudd_RecursiveDerefZdd(dd, *f1); - return(1); + Cudd_RecursiveDerefZdd(dd, *f1); + return(1); } return(0); @@ -1490,26 +1518,26 @@ cuddZddGetCofactors2( SeeAlso [] ******************************************************************************/ -DdNode * +DdNode * cuddZddComplement( DdManager * dd, DdNode *node) { - DdNode *b, *isop, *zdd_I; + DdNode *b, *isop, *zdd_I; /* Check cache */ zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node); if (zdd_I) - return(zdd_I); + return(zdd_I); b = cuddMakeBddFromZddCover(dd, node); if (!b) - return(NULL); + return(NULL); cuddRef(b); isop = cuddZddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I); if (!isop) { - Cudd_RecursiveDeref(dd, b); - return(NULL); + Cudd_RecursiveDeref(dd, b); + return(NULL); } cuddRef(isop); cuddRef(zdd_I); @@ -1538,7 +1566,7 @@ cuddZddGetPosVarIndex( DdManager * dd, int index) { - int pv = (index >> 1) << 1; + int pv = (index >> 1) << 1; return(pv); } /* end of cuddZddGetPosVarIndex */ @@ -1559,7 +1587,7 @@ cuddZddGetNegVarIndex( DdManager * dd, int index) { - int nv = index | 0x1; + int nv = index | 0x1; return(nv); } /* end of cuddZddGetPosVarIndex */ @@ -1580,7 +1608,7 @@ cuddZddGetPosVarLevel( DdManager * dd, int index) { - int pv = cuddZddGetPosVarIndex(dd, index); + int pv = cuddZddGetPosVarIndex(dd, index); return(dd->permZ[pv]); } /* end of cuddZddGetPosVarLevel */ @@ -1601,8 +1629,10 @@ cuddZddGetNegVarLevel( DdManager * dd, int index) { - int nv = cuddZddGetNegVarIndex(dd, index); + int nv = cuddZddGetNegVarIndex(dd, index); return(dd->permZ[nv]); } /* end of cuddZddGetNegVarLevel */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddZddGroup.c b/src/bdd/cudd/cuddZddGroup.c index 0bf611e5..5d0409de 100644 --- a/src/bdd/cudd/cuddZddGroup.c +++ b/src/bdd/cudd/cuddZddGroup.c @@ -7,36 +7,63 @@ Synopsis [Functions for ZDD group sifting.] Description [External procedures included in this file: - <ul> - <li> Cudd_MakeZddTreeNode() - </ul> - Internal procedures included in this file: - <ul> - <li> cuddZddTreeSifting() - </ul> - Static procedures included in this module: - <ul> - <li> zddTreeSiftingAux() - <li> zddCountInternalMtrNodes() - <li> zddReorderChildren() - <li> zddFindNodeHiLo() - <li> zddUniqueCompareGroup() - <li> zddGroupSifting() - <li> zddGroupSiftingAux() - <li> zddGroupSiftingUp() - <li> zddGroupSiftingDown() - <li> zddGroupMove() - <li> zddGroupMoveBackward() - <li> zddGroupSiftingBackward() - <li> zddMergeGroups() - </ul>] + <ul> + <li> Cudd_MakeZddTreeNode() + </ul> + Internal procedures included in this file: + <ul> + <li> cuddZddTreeSifting() + </ul> + Static procedures included in this module: + <ul> + <li> zddTreeSiftingAux() + <li> zddCountInternalMtrNodes() + <li> zddReorderChildren() + <li> zddFindNodeHiLo() + <li> zddUniqueCompareGroup() + <li> zddGroupSifting() + <li> zddGroupSiftingAux() + <li> zddGroupSiftingUp() + <li> zddGroupSiftingDown() + <li> zddGroupMove() + <li> zddGroupMoveBackward() + <li> zddGroupSiftingBackward() + <li> zddMergeGroups() + </ul>] Author [Fabio Somenzi] - Copyright [This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ @@ -46,6 +73,7 @@ ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -63,11 +91,11 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddGroup.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddGroup.c,v 1.20 2009/02/19 16:25:36 fabio Exp $"; #endif -static int *entry; -extern int zddTotalNumberSwapping; +static int *entry; +extern int zddTotalNumberSwapping; #ifdef DD_STATS static int extsymmcalls; static int extsymm; @@ -76,8 +104,8 @@ static int secdiff; static int secdiffmisfire; #endif #ifdef DD_DEBUG -static int pr = 0; /* flag to enable printing while debugging */ - /* by depositing a 1 into it */ +static int pr = 0; /* flag to enable printing while debugging */ + /* by depositing a 1 into it */ #endif /*---------------------------------------------------------------------------*/ @@ -90,21 +118,21 @@ static int pr = 0; /* flag to enable printing while debugging */ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int zddTreeSiftingAux ARGS((DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)); +static int zddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); #ifdef DD_STATS -static int zddCountInternalMtrNodes ARGS((DdManager *table, MtrNode *treenode)); +static int zddCountInternalMtrNodes (DdManager *table, MtrNode *treenode); #endif -static int zddReorderChildren ARGS((DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)); -static void zddFindNodeHiLo ARGS((DdManager *table, MtrNode *treenode, int *lower, int *upper)); -static int zddUniqueCompareGroup ARGS((int *ptrX, int *ptrY)); -static int zddGroupSifting ARGS((DdManager *table, int lower, int upper)); -static int zddGroupSiftingAux ARGS((DdManager *table, int x, int xLow, int xHigh)); -static int zddGroupSiftingUp ARGS((DdManager *table, int y, int xLow, Move **moves)); -static int zddGroupSiftingDown ARGS((DdManager *table, int x, int xHigh, Move **moves)); -static int zddGroupMove ARGS((DdManager *table, int x, int y, Move **moves)); -static int zddGroupMoveBackward ARGS((DdManager *table, int x, int y)); -static int zddGroupSiftingBackward ARGS((DdManager *table, Move *moves, int size)); -static void zddMergeGroups ARGS((DdManager *table, MtrNode *treenode, int low, int high)); +static int zddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method); +static void zddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper); +static int zddUniqueCompareGroup (int *ptrX, int *ptrY); +static int zddGroupSifting (DdManager *table, int lower, int upper); +static int zddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh); +static int zddGroupSiftingUp (DdManager *table, int y, int xLow, Move **moves); +static int zddGroupSiftingDown (DdManager *table, int x, int xHigh, Move **moves); +static int zddGroupMove (DdManager *table, int x, int y, Move **moves); +static int zddGroupMoveBackward (DdManager *table, int x, int y); +static int zddGroupSiftingBackward (DdManager *table, Move *moves, int size); +static void zddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high); /**AutomaticEnd***************************************************************/ @@ -150,15 +178,15 @@ Cudd_MakeZddTreeNode( level = (low < (unsigned int) dd->sizeZ) ? dd->permZ[low] : low; if (level + size - 1> (int) MTR_MAXHIGH) - return(NULL); + return(NULL); /* If the tree does not exist yet, create it. */ tree = dd->treeZ; if (tree == NULL) { - dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ); - if (tree == NULL) - return(NULL); - tree->index = dd->invpermZ[0]; + dd->treeZ = tree = Mtr_InitGroupTree(0, dd->sizeZ); + if (tree == NULL) + return(NULL); + tree->index = dd->invpermZ[0]; } /* Extend the upper bound of the tree if necessary. This allows the @@ -169,7 +197,7 @@ Cudd_MakeZddTreeNode( /* Create the group. */ group = Mtr_MakeGroup(tree, level, size, type); if (group == NULL) - return(NULL); + return(NULL); /* Initialize the index field to the index of the variable currently ** in position low. This field will be updated by the reordering @@ -216,44 +244,44 @@ cuddZddTreeSifting( */ tempTree = table->treeZ == NULL; if (tempTree) { - table->treeZ = Mtr_InitGroupTree(0,table->sizeZ); - table->treeZ->index = table->invpermZ[0]; + table->treeZ = Mtr_InitGroupTree(0,table->sizeZ); + table->treeZ->index = table->invpermZ[0]; } nvars = table->sizeZ; #ifdef DD_DEBUG if (pr > 0 && !tempTree) - (void) fprintf(table->out,"cuddZddTreeSifting:"); + (void) fprintf(table->out,"cuddZddTreeSifting:"); Mtr_PrintGroups(table->treeZ,pr <= 0); #endif #if 0 /* Debugging code. */ if (table->tree && table->treeZ) { - (void) fprintf(table->out,"\n"); - Mtr_PrintGroups(table->tree, 0); - cuddPrintVarGroups(table,table->tree,0,0); - for (i = 0; i < table->size; i++) { - (void) fprintf(table->out,"%s%d", - (i == 0) ? "" : ",", table->invperm[i]); - } - (void) fprintf(table->out,"\n"); - for (i = 0; i < table->size; i++) { - (void) fprintf(table->out,"%s%d", - (i == 0) ? "" : ",", table->perm[i]); - } - (void) fprintf(table->out,"\n\n"); - Mtr_PrintGroups(table->treeZ,0); - cuddPrintVarGroups(table,table->treeZ,1,0); - for (i = 0; i < table->sizeZ; i++) { - (void) fprintf(table->out,"%s%d", - (i == 0) ? "" : ",", table->invpermZ[i]); - } - (void) fprintf(table->out,"\n"); - for (i = 0; i < table->sizeZ; i++) { - (void) fprintf(table->out,"%s%d", - (i == 0) ? "" : ",", table->permZ[i]); - } - (void) fprintf(table->out,"\n"); + (void) fprintf(table->out,"\n"); + Mtr_PrintGroups(table->tree, 0); + cuddPrintVarGroups(table,table->tree,0,0); + for (i = 0; i < table->size; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->invperm[i]); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < table->size; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->perm[i]); + } + (void) fprintf(table->out,"\n\n"); + Mtr_PrintGroups(table->treeZ,0); + cuddPrintVarGroups(table,table->treeZ,1,0); + for (i = 0; i < table->sizeZ; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->invpermZ[i]); + } + (void) fprintf(table->out,"\n"); + for (i = 0; i < table->sizeZ; i++) { + (void) fprintf(table->out,"%s%d", + (i == 0) ? "" : ",", table->permZ[i]); + } + (void) fprintf(table->out,"\n"); } /* End of debugging code. */ #endif @@ -266,8 +294,8 @@ cuddZddTreeSifting( (void) fprintf(table->out,"\n"); if (!tempTree) - (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", - zddCountInternalMtrNodes(table,table->treeZ)); + (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n", + zddCountInternalMtrNodes(table,table->treeZ)); #endif /* Initialize the group of each subtable to itself. Initially @@ -280,23 +308,23 @@ cuddZddTreeSifting( /* Reorder. */ result = zddTreeSiftingAux(table, table->treeZ, method); -#ifdef DD_STATS /* print stats */ +#ifdef DD_STATS /* print stats */ if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && - (table->groupcheck == CUDD_GROUP_CHECK7 || - table->groupcheck == CUDD_GROUP_CHECK5)) { - (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); - (void) fprintf(table->out,"extsymm = %d",extsymm); + (table->groupcheck == CUDD_GROUP_CHECK7 || + table->groupcheck == CUDD_GROUP_CHECK5)) { + (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls); + (void) fprintf(table->out,"extsymm = %d",extsymm); } if (!tempTree && method == CUDD_REORDER_GROUP_SIFT && - table->groupcheck == CUDD_GROUP_CHECK7) { - (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); - (void) fprintf(table->out,"secdiff = %d\n",secdiff); - (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); + table->groupcheck == CUDD_GROUP_CHECK7) { + (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls); + (void) fprintf(table->out,"secdiff = %d\n",secdiff); + (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire); } #endif if (tempTree) - Cudd_FreeZddTree(table); + Cudd_FreeZddTree(table); return(result); } /* end of cuddZddTreeSifting */ @@ -332,17 +360,17 @@ zddTreeSiftingAux( auxnode = treenode; while (auxnode != NULL) { - if (auxnode->child != NULL) { - if (!zddTreeSiftingAux(table, auxnode->child, method)) - return(0); - res = zddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); - if (res == 0) - return(0); - } else if (auxnode->size > 1) { - if (!zddReorderChildren(table, auxnode, method)) - return(0); - } - auxnode = auxnode->younger; + if (auxnode->child != NULL) { + if (!zddTreeSiftingAux(table, auxnode->child, method)) + return(0); + res = zddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT); + if (res == 0) + return(0); + } else if (auxnode->size > 1) { + if (!zddReorderChildren(table, auxnode, method)) + return(0); + } + auxnode = auxnode->younger; } return(1); @@ -373,12 +401,12 @@ zddCountInternalMtrNodes( nodeCount = 0; auxnode = treenode; while (auxnode != NULL) { - if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { - nodeCount++; - count = zddCountInternalMtrNodes(table,auxnode->child); - nodeCount += count; - } - auxnode = auxnode->younger; + if (!(MTR_TEST(auxnode,MTR_TERMINAL))) { + nodeCount++; + count = zddCountInternalMtrNodes(table,auxnode->child); + nodeCount += count; + } + auxnode = auxnode->younger; } return(nodeCount); @@ -415,61 +443,61 @@ zddReorderChildren( zddFindNodeHiLo(table,treenode,&lower,&upper); /* If upper == -1 these variables do not exist yet. */ if (upper == -1) - return(1); + return(1); if (treenode->flags == MTR_FIXED) { - result = 1; + result = 1; } else { #ifdef DD_STATS - (void) fprintf(table->out," "); + (void) fprintf(table->out," "); #endif - switch (method) { - case CUDD_REORDER_RANDOM: - case CUDD_REORDER_RANDOM_PIVOT: - result = cuddZddSwapping(table,lower,upper,method); - break; - case CUDD_REORDER_SIFT: - result = cuddZddSifting(table,lower,upper); - break; - case CUDD_REORDER_SIFT_CONVERGE: - do { - initialSize = table->keysZ; - result = cuddZddSifting(table,lower,upper); - if (initialSize <= table->keysZ) + switch (method) { + case CUDD_REORDER_RANDOM: + case CUDD_REORDER_RANDOM_PIVOT: + result = cuddZddSwapping(table,lower,upper,method); break; + case CUDD_REORDER_SIFT: + result = cuddZddSifting(table,lower,upper); + break; + case CUDD_REORDER_SIFT_CONVERGE: + do { + initialSize = table->keysZ; + result = cuddZddSifting(table,lower,upper); + if (initialSize <= table->keysZ) + break; #ifdef DD_STATS - else - (void) fprintf(table->out,"\n"); + else + (void) fprintf(table->out,"\n"); #endif - } while (result != 0); - break; - case CUDD_REORDER_SYMM_SIFT: - result = cuddZddSymmSifting(table,lower,upper); - break; - case CUDD_REORDER_SYMM_SIFT_CONV: - result = cuddZddSymmSiftingConv(table,lower,upper); - break; - case CUDD_REORDER_GROUP_SIFT: - result = zddGroupSifting(table,lower,upper); - break; - case CUDD_REORDER_LINEAR: - result = cuddZddLinearSifting(table,lower,upper); - break; - case CUDD_REORDER_LINEAR_CONVERGE: - do { - initialSize = table->keysZ; - result = cuddZddLinearSifting(table,lower,upper); - if (initialSize <= table->keysZ) + } while (result != 0); + break; + case CUDD_REORDER_SYMM_SIFT: + result = cuddZddSymmSifting(table,lower,upper); + break; + case CUDD_REORDER_SYMM_SIFT_CONV: + result = cuddZddSymmSiftingConv(table,lower,upper); + break; + case CUDD_REORDER_GROUP_SIFT: + result = zddGroupSifting(table,lower,upper); break; + case CUDD_REORDER_LINEAR: + result = cuddZddLinearSifting(table,lower,upper); + break; + case CUDD_REORDER_LINEAR_CONVERGE: + do { + initialSize = table->keysZ; + result = cuddZddLinearSifting(table,lower,upper); + if (initialSize <= table->keysZ) + break; #ifdef DD_STATS - else - (void) fprintf(table->out,"\n"); + else + (void) fprintf(table->out,"\n"); #endif - } while (result != 0); - break; - default: - return(0); - } + } while (result != 0); + break; + default: + return(0); + } } /* Create a single group for all the variables that were sifted, @@ -517,42 +545,42 @@ zddFindNodeHiLo( ** the values of upper that no reordering is needed. */ if ((int) treenode->low >= table->sizeZ) { - *lower = table->sizeZ; - *upper = -1; - return; + *lower = table->sizeZ; + *upper = -1; + return; } *lower = low = (unsigned int) table->permZ[treenode->index]; high = (int) (low + treenode->size - 1); if (high >= table->sizeZ) { - /* This is the case of a partially existing group. The aim is to - ** reorder as many variables as safely possible. If the tree - ** node is terminal, we just reorder the subset of the group - ** that is currently in existence. If the group has - ** subgroups, then we only reorder those subgroups that are - ** fully instantiated. This way we avoid breaking up a group. - */ - MtrNode *auxnode = treenode->child; - if (auxnode == NULL) { - *upper = (unsigned int) table->sizeZ - 1; - } else { - /* Search the subgroup that strands the table->sizeZ line. - ** If the first group starts at 0 and goes past table->sizeZ - ** upper will get -1, thus correctly signaling that no reordering - ** should take place. + /* This is the case of a partially existing group. The aim is to + ** reorder as many variables as safely possible. If the tree + ** node is terminal, we just reorder the subset of the group + ** that is currently in existence. If the group has + ** subgroups, then we only reorder those subgroups that are + ** fully instantiated. This way we avoid breaking up a group. */ - while (auxnode != NULL) { - int thisLower = table->permZ[auxnode->low]; - int thisUpper = thisLower + auxnode->size - 1; - if (thisUpper >= table->sizeZ && thisLower < table->sizeZ) - *upper = (unsigned int) thisLower - 1; - auxnode = auxnode->younger; + MtrNode *auxnode = treenode->child; + if (auxnode == NULL) { + *upper = (unsigned int) table->sizeZ - 1; + } else { + /* Search the subgroup that strands the table->sizeZ line. + ** If the first group starts at 0 and goes past table->sizeZ + ** upper will get -1, thus correctly signaling that no reordering + ** should take place. + */ + while (auxnode != NULL) { + int thisLower = table->permZ[auxnode->low]; + int thisUpper = thisLower + auxnode->size - 1; + if (thisUpper >= table->sizeZ && thisLower < table->sizeZ) + *upper = (unsigned int) thisLower - 1; + auxnode = auxnode->younger; + } } - } } else { - /* Normal case: All the variables of the group exist. */ - *upper = (unsigned int) high; + /* Normal case: All the variables of the group exist. */ + *upper = (unsigned int) high; } #ifdef DD_DEBUG @@ -584,7 +612,7 @@ zddUniqueCompareGroup( { #if 0 if (entry[*ptrY] == entry[*ptrX]) { - return((*ptrX) - (*ptrY)); + return((*ptrX) - (*ptrY)); } #endif return(entry[*ptrY] - entry[*ptrX]); @@ -611,16 +639,16 @@ zddGroupSifting( int lower, int upper) { - int *var; - int i,j,x,xInit; - int nvars; - int classes; - int result; - int *sifted; + int *var; + int i,j,x,xInit; + int nvars; + int classes; + int result; + int *sifted; #ifdef DD_STATS unsigned previousSize; #endif - int xindex; + int xindex; nvars = table->sizeZ; @@ -629,77 +657,77 @@ zddGroupSifting( sifted = NULL; var = ABC_ALLOC(int,nvars); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto zddGroupSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; } entry = ABC_ALLOC(int,nvars); if (entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto zddGroupSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; } sifted = ABC_ALLOC(int,nvars); if (sifted == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto zddGroupSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto zddGroupSiftingOutOfMem; } /* Here we consider only one representative for each group. */ for (i = 0, classes = 0; i < nvars; i++) { - sifted[i] = 0; - x = table->permZ[i]; - if ((unsigned) x >= table->subtableZ[x].next) { - entry[i] = table->subtableZ[x].keys; - var[classes] = i; - classes++; - } + sifted[i] = 0; + x = table->permZ[i]; + if ((unsigned) x >= table->subtableZ[x].next) { + entry[i] = table->subtableZ[x].keys; + var[classes] = i; + classes++; + } } - qsort((void *)var,classes,sizeof(int),(int (*)(const void *, const void *))zddUniqueCompareGroup); + qsort((void *)var,classes,sizeof(int),(DD_QSFP)zddUniqueCompareGroup); /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) { - if (zddTotalNumberSwapping >= table->siftMaxSwap) - break; - xindex = var[i]; - if (sifted[xindex] == 1) /* variable already sifted as part of group */ - continue; + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + xindex = var[i]; + if (sifted[xindex] == 1) /* variable already sifted as part of group */ + continue; x = table->permZ[xindex]; /* find current level of this variable */ - if (x < lower || x > upper) - continue; + if (x < lower || x > upper) + continue; #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif #ifdef DD_DEBUG - /* x is bottom of group */ + /* x is bottom of group */ assert((unsigned) x >= table->subtableZ[x].next); #endif - result = zddGroupSiftingAux(table,x,lower,upper); - if (!result) goto zddGroupSiftingOutOfMem; + result = zddGroupSiftingAux(table,x,lower,upper); + if (!result) goto zddGroupSiftingOutOfMem; #ifdef DD_STATS - if (table->keysZ < previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > previousSize) { - (void) fprintf(table->out,"+"); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keysZ < previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > previousSize) { + (void) fprintf(table->out,"+"); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - /* Mark variables in the group just sifted. */ - x = table->permZ[xindex]; - if ((unsigned) x != table->subtableZ[x].next) { - xInit = x; - do { - j = table->invpermZ[x]; - sifted[j] = 1; - x = table->subtableZ[x].next; - } while (x != xInit); - } + /* Mark variables in the group just sifted. */ + x = table->permZ[xindex]; + if ((unsigned) x != table->subtableZ[x].next) { + xInit = x; + do { + j = table->invpermZ[x]; + sifted[j] = 1; + x = table->subtableZ[x].next; + } while (x != xInit); + } #ifdef DD_DEBUG - if (pr > 0) (void) fprintf(table->out,"zddGroupSifting:"); + if (pr > 0) (void) fprintf(table->out,"zddGroupSifting:"); #endif } /* for */ @@ -710,9 +738,9 @@ zddGroupSifting( return(1); zddGroupSiftingOutOfMem: - if (entry != NULL) ABC_FREE(entry); + if (entry != NULL) ABC_FREE(entry); if (var != NULL) ABC_FREE(var); - if (sifted != NULL) ABC_FREE(sifted); + if (sifted != NULL) ABC_FREE(sifted); return(0); @@ -742,7 +770,7 @@ zddGroupSiftingAux( int xHigh) { Move *move; - Move *moves; /* list of moves */ + Move *moves; /* list of moves */ int initialSize; int result; @@ -757,25 +785,25 @@ zddGroupSiftingAux( if (x == xLow) { /* Sift down */ #ifdef DD_DEBUG - /* x must be a singleton */ - assert((unsigned) x == table->subtableZ[x].next); + /* x must be a singleton */ + assert((unsigned) x == table->subtableZ[x].next); #endif - if (x == xHigh) return(1); /* just one variable */ + if (x == xHigh) return(1); /* just one variable */ if (!zddGroupSiftingDown(table,x,xHigh,&moves)) goto zddGroupSiftingAuxOutOfMem; - /* at this point x == xHigh, unless early term */ + /* at this point x == xHigh, unless early term */ - /* move backward and stop at best position */ - result = zddGroupSiftingBackward(table,moves,initialSize); + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); #ifdef DD_DEBUG - assert(table->keysZ <= (unsigned) initialSize); + assert(table->keysZ <= (unsigned) initialSize); #endif if (!result) goto zddGroupSiftingAuxOutOfMem; } else if (cuddZddNextHigh(table,x) > xHigh) { /* Sift up */ #ifdef DD_DEBUG - /* x is bottom of group */ + /* x is bottom of group */ assert((unsigned) x >= table->subtableZ[x].next); #endif /* Find top of x's group */ @@ -783,27 +811,27 @@ zddGroupSiftingAux( if (!zddGroupSiftingUp(table,x,xLow,&moves)) goto zddGroupSiftingAuxOutOfMem; - /* at this point x == xLow, unless early term */ + /* at this point x == xLow, unless early term */ - /* move backward and stop at best position */ - result = zddGroupSiftingBackward(table,moves,initialSize); + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); #ifdef DD_DEBUG - assert(table->keysZ <= (unsigned) initialSize); + assert(table->keysZ <= (unsigned) initialSize); #endif if (!result) goto zddGroupSiftingAuxOutOfMem; } else if (x - xLow > xHigh - x) { /* must go down first: shorter */ if (!zddGroupSiftingDown(table,x,xHigh,&moves)) goto zddGroupSiftingAuxOutOfMem; - /* at this point x == xHigh, unless early term */ + /* at this point x == xHigh, unless early term */ /* Find top of group */ - if (moves) { - x = moves->y; - } - while ((unsigned) x < table->subtableZ[x].next) + if (moves) { + x = moves->y; + } + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; x = table->subtableZ[x].next; - x = table->subtableZ[x].next; #ifdef DD_DEBUG /* x should be the top of a group */ assert((unsigned) x <= table->subtableZ[x].next); @@ -812,10 +840,10 @@ zddGroupSiftingAux( if (!zddGroupSiftingUp(table,x,xLow,&moves)) goto zddGroupSiftingAuxOutOfMem; - /* move backward and stop at best position */ - result = zddGroupSiftingBackward(table,moves,initialSize); + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); #ifdef DD_DEBUG - assert(table->keysZ <= (unsigned) initialSize); + assert(table->keysZ <= (unsigned) initialSize); #endif if (!result) goto zddGroupSiftingAuxOutOfMem; @@ -825,13 +853,13 @@ zddGroupSiftingAux( if (!zddGroupSiftingUp(table,x,xLow,&moves)) goto zddGroupSiftingAuxOutOfMem; - /* at this point x == xHigh, unless early term */ + /* at this point x == xHigh, unless early term */ if (moves) { - x = moves->x; - } - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; + x = moves->x; + } + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; #ifdef DD_DEBUG /* x is bottom of a group */ assert((unsigned) x >= table->subtableZ[x].next); @@ -840,17 +868,17 @@ zddGroupSiftingAux( if (!zddGroupSiftingDown(table,x,xHigh,&moves)) goto zddGroupSiftingAuxOutOfMem; - /* move backward and stop at best position */ - result = zddGroupSiftingBackward(table,moves,initialSize); + /* move backward and stop at best position */ + result = zddGroupSiftingBackward(table,moves,initialSize); #ifdef DD_DEBUG - assert(table->keysZ <= (unsigned) initialSize); + assert(table->keysZ <= (unsigned) initialSize); #endif if (!result) goto zddGroupSiftingAuxOutOfMem; } while (moves != NULL) { move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); + cuddDeallocMove(table, moves); moves = move; } @@ -859,7 +887,7 @@ zddGroupSiftingAux( zddGroupSiftingAuxOutOfMem: while (moves != NULL) { move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); + cuddDeallocMove(table, moves); moves = move; } @@ -895,9 +923,6 @@ zddGroupSiftingUp( int size; int gxtop; int limitSize; - int xindex, yindex; - - yindex = table->invpermZ[y]; limitSize = table->keysZ; @@ -905,9 +930,8 @@ zddGroupSiftingUp( while (x >= xLow) { gxtop = table->subtableZ[x].next; if (table->subtableZ[x].next == (unsigned) x && - table->subtableZ[y].next == (unsigned) y) { + table->subtableZ[y].next == (unsigned) y) { /* x and y are self groups */ - xindex = table->invpermZ[x]; size = cuddZddSwapInPlace(table,x,y); #ifdef DD_DEBUG assert(table->subtableZ[x].next == (unsigned) x); @@ -918,22 +942,22 @@ zddGroupSiftingUp( if (move == NULL) goto zddGroupSiftingUpOutOfMem; move->x = x; move->y = y; - move->flags = MTR_DEFAULT; + move->flags = MTR_DEFAULT; move->size = size; move->next = *moves; *moves = move; #ifdef DD_DEBUG - if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingUp (2 single groups):\n"); + if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingUp (2 single groups):\n"); #endif if ((double) size > (double) limitSize * table->maxGrowth) - return(1); + return(1); if (size < limitSize) limitSize = size; } else { /* group move */ size = zddGroupMove(table,x,y,moves); - if (size == 0) goto zddGroupSiftingUpOutOfMem; + if (size == 0) goto zddGroupSiftingUpOutOfMem; if ((double) size > (double) limitSize * table->maxGrowth) - return(1); + return(1); if (size < limitSize) limitSize = size; } y = gxtop; @@ -945,7 +969,7 @@ zddGroupSiftingUp( zddGroupSiftingUpOutOfMem: while (*moves != NULL) { move = (*moves)->next; - cuddDeallocNode(table, (DdNode *) *moves); + cuddDeallocMove(table, *moves); *moves = move; } return(0); @@ -975,23 +999,20 @@ zddGroupSiftingDown( int y; int size; int limitSize; - int gxtop,gybot; - int xindex; + int gybot; /* Initialize R */ - xindex = table->invpermZ[x]; - gxtop = table->subtableZ[x].next; limitSize = size = table->keysZ; y = cuddZddNextHigh(table,x); while (y <= xHigh) { - /* Find bottom of y group. */ + /* Find bottom of y group. */ gybot = table->subtableZ[y].next; while (table->subtableZ[gybot].next != (unsigned) y) gybot = table->subtableZ[gybot].next; if (table->subtableZ[x].next == (unsigned) x && - table->subtableZ[y].next == (unsigned) y) { + table->subtableZ[y].next == (unsigned) y) { /* x and y are self groups */ size = cuddZddSwapInPlace(table,x,y); #ifdef DD_DEBUG @@ -1000,12 +1021,12 @@ zddGroupSiftingDown( #endif if (size == 0) goto zddGroupSiftingDownOutOfMem; - /* Record move. */ + /* Record move. */ move = (Move *) cuddDynamicAllocNode(table); if (move == NULL) goto zddGroupSiftingDownOutOfMem; move->x = x; move->y = y; - move->flags = MTR_DEFAULT; + move->flags = MTR_DEFAULT; move->size = size; move->next = *moves; *moves = move; @@ -1022,7 +1043,7 @@ zddGroupSiftingDown( size = zddGroupMove(table,x,y,moves); if (size == 0) goto zddGroupSiftingDownOutOfMem; if ((double) size > (double) limitSize * table->maxGrowth) - return(1); + return(1); if (size < limitSize) limitSize = size; } x = gybot; @@ -1034,7 +1055,7 @@ zddGroupSiftingDown( zddGroupSiftingDownOutOfMem: while (*moves != NULL) { move = (*moves)->next; - cuddDeallocNode(table, (DdNode *) *moves); + cuddDeallocMove(table, *moves); *moves = move; } @@ -1063,12 +1084,12 @@ zddGroupMove( Move *move; int size; int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; - int swapx = 0,swapy = 0; // Suppress "might be used uninitialized" + int swapx,swapy; #if defined(DD_DEBUG) && defined(DD_VERBOSE) int initialSize,bestSize; #endif -#if DD_DEBUG +#ifdef DD_DEBUG /* We assume that x < y */ assert(x < y); #endif @@ -1091,8 +1112,8 @@ zddGroupMove( size = cuddZddSwapInPlace(table,x,y); if (size == 0) goto zddGroupMoveOutOfMem; #if defined(DD_DEBUG) && defined(DD_VERBOSE) - if (size < bestSize) - bestSize = size; + if (size < bestSize) + bestSize = size; #endif swapx = x; swapy = y; y = x; @@ -1103,7 +1124,7 @@ zddGroupMove( } #if defined(DD_DEBUG) && defined(DD_VERBOSE) if ((bestSize < initialSize) && (bestSize < size)) - (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); + (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size); #endif /* fix groups */ @@ -1141,7 +1162,7 @@ zddGroupMove( zddGroupMoveOutOfMem: while (*moves != NULL) { move = (*moves)->next; - cuddDeallocNode(table, (DdNode *) *moves); + cuddDeallocMove(table, *moves); *moves = move; } return(0); @@ -1169,7 +1190,7 @@ zddGroupMoveBackward( int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop; -#if DD_DEBUG +#ifdef DD_DEBUG /* We assume that x < y */ assert(x < y); #endif @@ -1252,7 +1273,7 @@ zddGroupSiftingBackward( for (move = moves; move != NULL; move = move->next) { if (move->size == size) return(1); if ((table->subtableZ[move->x].next == move->x) && - (table->subtableZ[move->y].next == move->y)) { + (table->subtableZ[move->y].next == move->y)) { res = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); if (!res) return(0); #ifdef DD_DEBUG @@ -1261,8 +1282,8 @@ zddGroupSiftingBackward( assert(table->subtableZ[move->y].next == move->y); #endif } else { /* Group move necessary */ - res = zddGroupMoveBackward(table,(int)move->x,(int)move->y); - if (!res) return(0); + res = zddGroupMoveBackward(table,(int)move->x,(int)move->y); + if (!res) return(0); } } @@ -1297,9 +1318,9 @@ zddMergeGroups( ** this is the topmost group. In such a case we do not merge lest ** we lose the symmetry information. */ if (treenode != table->treeZ) { - for (i = low; i < high; i++) - table->subtableZ[i].next = i+1; - table->subtableZ[high].next = low; + for (i = low; i < high; i++) + table->subtableZ[i].next = i+1; + table->subtableZ[high].next = low; } /* Adjust the index fields of the tree nodes. If a node is the @@ -1308,15 +1329,16 @@ zddMergeGroups( newindex = table->invpermZ[low]; auxnode = treenode; do { - auxnode->index = newindex; - if (auxnode->parent == NULL || - (int) auxnode->parent->index != saveindex) - break; - auxnode = auxnode->parent; + auxnode->index = newindex; + if (auxnode->parent == NULL || + (int) auxnode->parent->index != saveindex) + break; + auxnode = auxnode->parent; } while (1); return; } /* end of zddMergeGroups */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddZddIsop.c b/src/bdd/cudd/cuddZddIsop.c index cd7c16bf..1de9110a 100644 --- a/src/bdd/cudd/cuddZddIsop.c +++ b/src/bdd/cudd/cuddZddIsop.c @@ -7,39 +7,67 @@ Synopsis [Functions to find irredundant SOP covers as ZDDs from BDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_bddIsop() - <li> Cudd_zddIsop() - <li> Cudd_MakeBddFromZddCover() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddBddIsop() - <li> cuddZddIsop() - <li> cuddMakeBddFromZddCover() - </ul> - Static procedures included in this module: - <ul> - </ul> - ] + <ul> + <li> Cudd_bddIsop() + <li> Cudd_zddIsop() + <li> Cudd_MakeBddFromZddCover() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddBddIsop() + <li> cuddZddIsop() + <li> cuddMakeBddFromZddCover() + </ul> + Static procedures included in this module: + <ul> + </ul> + ] SeeAlso [] Author [In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -60,7 +88,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddIsop.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddIsop.c,v 1.20 2009/02/19 16:26:12 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -104,22 +132,22 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddIsop.c,v 1.1.1.1 2003/02/24 22:23:5 SeeAlso [Cudd_bddIsop Cudd_zddVarsFromBddVars] ******************************************************************************/ -DdNode * +DdNode * Cudd_zddIsop( DdManager * dd, DdNode * L, DdNode * U, DdNode ** zdd_I) { - DdNode *res; - int autoDynZ; + DdNode *res; + int autoDynZ; autoDynZ = dd->autoDynZ; dd->autoDynZ = 0; do { - dd->reordered = 0; - res = cuddZddIsop(dd, L, U, zdd_I); + dd->reordered = 0; + res = cuddZddIsop(dd, L, U, zdd_I); } while (dd->reordered == 1); dd->autoDynZ = autoDynZ; return(res); @@ -142,17 +170,17 @@ Cudd_zddIsop( SeeAlso [Cudd_zddIsop] ******************************************************************************/ -DdNode * +DdNode * Cudd_bddIsop( DdManager * dd, DdNode * L, DdNode * U) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddBddIsop(dd, L, U); + dd->reordered = 0; + res = cuddBddIsop(dd, L, U); } while (dd->reordered == 1); return(res); @@ -171,16 +199,16 @@ Cudd_bddIsop( SeeAlso [cuddMakeBddFromZddCover] ******************************************************************************/ -DdNode * +DdNode * Cudd_MakeBddFromZddCover( DdManager * dd, DdNode * node) { - DdNode *res; + DdNode *res; do { - dd->reordered = 0; - res = cuddMakeBddFromZddCover(dd, node); + dd->reordered = 0; + res = cuddMakeBddFromZddCover(dd, node); } while (dd->reordered == 1); return(res); } /* end of Cudd_MakeBddFromZddCover */ @@ -202,42 +230,42 @@ Cudd_MakeBddFromZddCover( SeeAlso [Cudd_zddIsop] ******************************************************************************/ -DdNode * +DdNode * cuddZddIsop( DdManager * dd, DdNode * L, DdNode * U, DdNode ** zdd_I) { - DdNode *one = DD_ONE(dd); - DdNode *zero = Cudd_Not(one); - DdNode *zdd_one = DD_ONE(dd); - DdNode *zdd_zero = DD_ZERO(dd); - int v, top_l, top_u; - DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; - DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; - DdNode *Isub0, *Isub1, *Id; - DdNode *zdd_Isub0, *zdd_Isub1, *zdd_Id; - DdNode *x; - DdNode *term0, *term1, *sum; - DdNode *Lv, *Uv, *Lnv, *Unv; - DdNode *r, *y, *z; - int index; - DdNode *(*cacheOp)(DdManager *, DdNode *, DdNode *); + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + DdNode *zdd_one = DD_ONE(dd); + DdNode *zdd_zero = DD_ZERO(dd); + int v, top_l, top_u; + DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; + DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; + DdNode *Isub0, *Isub1, *Id; + DdNode *zdd_Isub0, *zdd_Isub1, *zdd_Id; + DdNode *x; + DdNode *term0, *term1, *sum; + DdNode *Lv, *Uv, *Lnv, *Unv; + DdNode *r, *y, *z; + int index; + DD_CTFP cacheOp; statLine(dd); if (L == zero) { - *zdd_I = zdd_zero; + *zdd_I = zdd_zero; return(zero); } if (U == one) { - *zdd_I = zdd_one; + *zdd_I = zdd_one; return(one); } if (U == zero || L == one) { - printf("*** ERROR : illegal condition for ISOP (U < L).\n"); - exit(1); + printf("*** ERROR : illegal condition for ISOP (U < L).\n"); + exit(1); } /* Check the cache. We store two results for each recursive call. @@ -245,19 +273,19 @@ cuddZddIsop( ** Hence we need a double hit in the cache to terminate the ** recursion. Clearly, collisions may evict only one of the two ** results. */ - cacheOp = (DdNode *(*)(DdManager *, DdNode *, DdNode *)) cuddZddIsop; + cacheOp = (DD_CTFP) cuddZddIsop; r = cuddCacheLookup2(dd, cuddBddIsop, L, U); if (r) { - *zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U); - if (*zdd_I) - return(r); - else { - /* The BDD result may have been dead. In that case - ** cuddCacheLookup2 would have called cuddReclaim, - ** whose effects we now have to undo. */ - cuddRef(r); - Cudd_RecursiveDeref(dd, r); - } + *zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U); + if (*zdd_I) + return(r); + else { + /* The BDD result may have been dead. In that case + ** cuddCacheLookup2 would have called cuddReclaim, + ** whose effects we now have to undo. */ + cuddRef(r); + Cudd_RecursiveDeref(dd, r); + } } top_l = dd->perm[Cudd_Regular(L)->index]; @@ -266,7 +294,7 @@ cuddZddIsop( /* Compute cofactors. */ if (top_l == v) { - index = Cudd_Regular(L)->index; + index = Cudd_Regular(L)->index; Lv = Cudd_T(L); Lnv = Cudd_E(L); if (Cudd_IsComplement(L)) { @@ -275,7 +303,7 @@ cuddZddIsop( } } else { - index = Cudd_Regular(U)->index; + index = Cudd_Regular(U)->index; Lv = Lnv = L; } @@ -293,45 +321,45 @@ cuddZddIsop( Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv)); if (Lsub0 == NULL) - return(NULL); + return(NULL); Cudd_Ref(Lsub0); Usub0 = Unv; Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv)); if (Lsub1 == NULL) { - Cudd_RecursiveDeref(dd, Lsub0); - return(NULL); + Cudd_RecursiveDeref(dd, Lsub0); + return(NULL); } Cudd_Ref(Lsub1); Usub1 = Uv; Isub0 = cuddZddIsop(dd, Lsub0, Usub0, &zdd_Isub0); if (Isub0 == NULL) { - Cudd_RecursiveDeref(dd, Lsub0); - Cudd_RecursiveDeref(dd, Lsub1); - return(NULL); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + return(NULL); } /* if ((!cuddIsConstant(Cudd_Regular(Isub0))) && - (Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 || - dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) { - printf("*** ERROR : illegal permutation in ZDD. ***\n"); + (Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); } */ Cudd_Ref(Isub0); Cudd_Ref(zdd_Isub0); Isub1 = cuddZddIsop(dd, Lsub1, Usub1, &zdd_Isub1); if (Isub1 == NULL) { - Cudd_RecursiveDeref(dd, Lsub0); - Cudd_RecursiveDeref(dd, Lsub1); - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - return(NULL); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + return(NULL); } /* if ((!cuddIsConstant(Cudd_Regular(Isub1))) && - (Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 || - dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) { - printf("*** ERROR : illegal permutation in ZDD. ***\n"); + (Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); } */ Cudd_Ref(Isub1); @@ -341,21 +369,21 @@ cuddZddIsop( Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0)); if (Lsuper0 == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + return(NULL); } Cudd_Ref(Lsuper0); Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1)); if (Lsuper1 == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Lsuper0); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + return(NULL); } Cudd_Ref(Lsuper1); Usuper0 = Unv; @@ -364,27 +392,27 @@ cuddZddIsop( /* Ld = Lsuper0 + Lsuper1 */ Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1)); if (Ld == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Lsuper0); - Cudd_RecursiveDeref(dd, Lsuper1); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + return(NULL); } Ld = Cudd_Not(Ld); Cudd_Ref(Ld); /* Ud = Usuper0 * Usuper1 */ Ud = cuddBddAndRecur(dd, Usuper0, Usuper1); if (Ud == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Lsuper0); - Cudd_RecursiveDeref(dd, Lsuper1); - Cudd_RecursiveDeref(dd, Ld); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + Cudd_RecursiveDeref(dd, Ld); + return(NULL); } Cudd_Ref(Ud); Cudd_RecursiveDeref(dd, Lsuper0); @@ -392,19 +420,19 @@ cuddZddIsop( Id = cuddZddIsop(dd, Ld, Ud, &zdd_Id); if (Id == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Ld); - Cudd_RecursiveDeref(dd, Ud); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + return(NULL); } /* if ((!cuddIsConstant(Cudd_Regular(Id))) && - (Cudd_Regular(Id)->index != zdd_Id->index / 2 || - dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) { - printf("*** ERROR : illegal permutation in ZDD. ***\n"); + (Cudd_Regular(Id)->index != zdd_Id->index / 2 || + dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) { + printf("*** ERROR : illegal permutation in ZDD. ***\n"); } */ Cudd_Ref(Id); @@ -414,40 +442,40 @@ cuddZddIsop( x = cuddUniqueInter(dd, index, one, zero); if (x == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + return(NULL); } Cudd_Ref(x); /* term0 = x * Isub0 */ term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0); if (term0 == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - Cudd_RecursiveDeref(dd, x); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, x); + return(NULL); } Cudd_Ref(term0); Cudd_RecursiveDeref(dd, Isub0); /* term1 = x * Isub1 */ term1 = cuddBddAndRecur(dd, x, Isub1); if (term1 == NULL) { - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - Cudd_RecursiveDeref(dd, x); - Cudd_RecursiveDeref(dd, term0); - return(NULL); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, term0); + return(NULL); } Cudd_Ref(term1); Cudd_RecursiveDeref(dd, x); @@ -455,13 +483,13 @@ cuddZddIsop( /* sum = term0 + term1 */ sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1)); if (sum == NULL) { - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - Cudd_RecursiveDeref(dd, term0); - Cudd_RecursiveDeref(dd, term1); - return(NULL); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + return(NULL); } sum = Cudd_Not(sum); Cudd_Ref(sum); @@ -471,44 +499,44 @@ cuddZddIsop( r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id)); r = Cudd_NotCond(r, r != NULL); if (r == NULL) { - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - Cudd_RecursiveDeref(dd, sum); - return(NULL); + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, sum); + return(NULL); } Cudd_Ref(r); Cudd_RecursiveDeref(dd, sum); Cudd_RecursiveDeref(dd, Id); if (zdd_Isub0 != zdd_zero) { - z = cuddZddGetNodeIVO(dd, index * 2 + 1, zdd_Isub0, zdd_Id); - if (z == NULL) { - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - Cudd_RecursiveDeref(dd, r); - return(NULL); - } + z = cuddZddGetNodeIVO(dd, index * 2 + 1, zdd_Isub0, zdd_Id); + if (z == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, r); + return(NULL); + } } else { - z = zdd_Id; + z = zdd_Id; } Cudd_Ref(z); if (zdd_Isub1 != zdd_zero) { - y = cuddZddGetNodeIVO(dd, index * 2, zdd_Isub1, z); - if (y == NULL) { - Cudd_RecursiveDerefZdd(dd, zdd_Isub0); - Cudd_RecursiveDerefZdd(dd, zdd_Isub1); - Cudd_RecursiveDerefZdd(dd, zdd_Id); - Cudd_RecursiveDeref(dd, r); - Cudd_RecursiveDerefZdd(dd, z); - return(NULL); - } + y = cuddZddGetNodeIVO(dd, index * 2, zdd_Isub1, z); + if (y == NULL) { + Cudd_RecursiveDerefZdd(dd, zdd_Isub0); + Cudd_RecursiveDerefZdd(dd, zdd_Isub1); + Cudd_RecursiveDerefZdd(dd, zdd_Id); + Cudd_RecursiveDeref(dd, r); + Cudd_RecursiveDerefZdd(dd, z); + return(NULL); + } } else - y = z; + y = z; Cudd_Ref(y); Cudd_RecursiveDerefZdd(dd, zdd_Isub0); @@ -524,7 +552,7 @@ cuddZddIsop( *zdd_I = y; /* if (Cudd_Regular(r)->index != y->index / 2) { - printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n"); + printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n"); } */ return(r); @@ -543,23 +571,23 @@ cuddZddIsop( SeeAlso [Cudd_bddIsop] ******************************************************************************/ -DdNode * +DdNode * cuddBddIsop( DdManager * dd, DdNode * L, DdNode * U) { - DdNode *one = DD_ONE(dd); - DdNode *zero = Cudd_Not(one); - int v, top_l, top_u; - DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; - DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; - DdNode *Isub0, *Isub1, *Id; - DdNode *x; - DdNode *term0, *term1, *sum; - DdNode *Lv, *Uv, *Lnv, *Unv; - DdNode *r; - int index; + DdNode *one = DD_ONE(dd); + DdNode *zero = Cudd_Not(one); + int v, top_l, top_u; + DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud; + DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1; + DdNode *Isub0, *Isub1, *Id; + DdNode *x; + DdNode *term0, *term1, *sum; + DdNode *Lv, *Uv, *Lnv, *Unv; + DdNode *r; + int index; statLine(dd); if (L == zero) @@ -578,7 +606,7 @@ cuddBddIsop( /* Compute cofactors */ if (top_l == v) { - index = Cudd_Regular(L)->index; + index = Cudd_Regular(L)->index; Lv = Cudd_T(L); Lnv = Cudd_E(L); if (Cudd_IsComplement(L)) { @@ -587,7 +615,7 @@ cuddBddIsop( } } else { - index = Cudd_Regular(U)->index; + index = Cudd_Regular(U)->index; Lv = Lnv = L; } @@ -605,30 +633,30 @@ cuddBddIsop( Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv)); if (Lsub0 == NULL) - return(NULL); + return(NULL); Cudd_Ref(Lsub0); Usub0 = Unv; Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv)); if (Lsub1 == NULL) { - Cudd_RecursiveDeref(dd, Lsub0); - return(NULL); + Cudd_RecursiveDeref(dd, Lsub0); + return(NULL); } Cudd_Ref(Lsub1); Usub1 = Uv; Isub0 = cuddBddIsop(dd, Lsub0, Usub0); if (Isub0 == NULL) { - Cudd_RecursiveDeref(dd, Lsub0); - Cudd_RecursiveDeref(dd, Lsub1); - return(NULL); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + return(NULL); } Cudd_Ref(Isub0); Isub1 = cuddBddIsop(dd, Lsub1, Usub1); if (Isub1 == NULL) { - Cudd_RecursiveDeref(dd, Lsub0); - Cudd_RecursiveDeref(dd, Lsub1); - Cudd_RecursiveDeref(dd, Isub0); - return(NULL); + Cudd_RecursiveDeref(dd, Lsub0); + Cudd_RecursiveDeref(dd, Lsub1); + Cudd_RecursiveDeref(dd, Isub0); + return(NULL); } Cudd_Ref(Isub1); Cudd_RecursiveDeref(dd, Lsub0); @@ -636,17 +664,17 @@ cuddBddIsop( Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0)); if (Lsuper0 == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + return(NULL); } Cudd_Ref(Lsuper0); Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1)); if (Lsuper1 == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Lsuper0); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + return(NULL); } Cudd_Ref(Lsuper1); Usuper0 = Unv; @@ -656,21 +684,21 @@ cuddBddIsop( Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1)); Ld = Cudd_NotCond(Ld, Ld != NULL); if (Ld == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Lsuper0); - Cudd_RecursiveDeref(dd, Lsuper1); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + return(NULL); } Cudd_Ref(Ld); Ud = cuddBddAndRecur(dd, Usuper0, Usuper1); if (Ud == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Lsuper0); - Cudd_RecursiveDeref(dd, Lsuper1); - Cudd_RecursiveDeref(dd, Ld); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Lsuper0); + Cudd_RecursiveDeref(dd, Lsuper1); + Cudd_RecursiveDeref(dd, Ld); + return(NULL); } Cudd_Ref(Ud); Cudd_RecursiveDeref(dd, Lsuper0); @@ -678,11 +706,11 @@ cuddBddIsop( Id = cuddBddIsop(dd, Ld, Ud); if (Id == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Ld); - Cudd_RecursiveDeref(dd, Ud); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Ld); + Cudd_RecursiveDeref(dd, Ud); + return(NULL); } Cudd_Ref(Id); Cudd_RecursiveDeref(dd, Ld); @@ -690,29 +718,29 @@ cuddBddIsop( x = cuddUniqueInter(dd, index, one, zero); if (x == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Id); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + return(NULL); } Cudd_Ref(x); term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0); if (term0 == NULL) { - Cudd_RecursiveDeref(dd, Isub0); - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDeref(dd, x); - return(NULL); + Cudd_RecursiveDeref(dd, Isub0); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, x); + return(NULL); } Cudd_Ref(term0); Cudd_RecursiveDeref(dd, Isub0); term1 = cuddBddAndRecur(dd, x, Isub1); if (term1 == NULL) { - Cudd_RecursiveDeref(dd, Isub1); - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDeref(dd, x); - Cudd_RecursiveDeref(dd, term0); - return(NULL); + Cudd_RecursiveDeref(dd, Isub1); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, x); + Cudd_RecursiveDeref(dd, term0); + return(NULL); } Cudd_Ref(term1); Cudd_RecursiveDeref(dd, x); @@ -721,10 +749,10 @@ cuddBddIsop( sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1)); sum = Cudd_NotCond(sum, sum != NULL); if (sum == NULL) { - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDeref(dd, term0); - Cudd_RecursiveDeref(dd, term1); - return(NULL); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, term0); + Cudd_RecursiveDeref(dd, term1); + return(NULL); } Cudd_Ref(sum); Cudd_RecursiveDeref(dd, term0); @@ -733,9 +761,9 @@ cuddBddIsop( r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id)); r = Cudd_NotCond(r, r != NULL); if (r == NULL) { - Cudd_RecursiveDeref(dd, Id); - Cudd_RecursiveDeref(dd, sum); - return(NULL); + Cudd_RecursiveDeref(dd, Id); + Cudd_RecursiveDeref(dd, sum); + return(NULL); } Cudd_Ref(r); Cudd_RecursiveDeref(dd, sum); @@ -768,108 +796,108 @@ cuddBddIsop( SeeAlso [Cudd_MakeBddFromZddCover] ******************************************************************************/ -DdNode * +DdNode * cuddMakeBddFromZddCover( DdManager * dd, DdNode * node) { - DdNode *neW; - int v; - DdNode *f1, *f0, *fd; - DdNode *b1, *b0, *bd; - DdNode *T, *E; + DdNode *neW; + int v; + DdNode *f1, *f0, *fd; + DdNode *b1, *b0, *bd; + DdNode *T, *E; statLine(dd); if (node == dd->one) - return(dd->one); + return(dd->one); if (node == dd->zero) - return(Cudd_Not(dd->one)); + return(Cudd_Not(dd->one)); /* Check cache */ neW = cuddCacheLookup1(dd, cuddMakeBddFromZddCover, node); if (neW) - return(neW); + return(neW); - v = Cudd_Regular(node)->index; /* either yi or zi */ - cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd); + v = Cudd_Regular(node)->index; /* either yi or zi */ + if (cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd)) return(NULL); Cudd_Ref(f1); Cudd_Ref(f0); Cudd_Ref(fd); b1 = cuddMakeBddFromZddCover(dd, f1); if (!b1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - return(NULL); + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + return(NULL); } Cudd_Ref(b1); b0 = cuddMakeBddFromZddCover(dd, f0); - if (!b1) { - Cudd_RecursiveDerefZdd(dd, f1); - Cudd_RecursiveDerefZdd(dd, f0); - Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDeref(dd, b1); - return(NULL); + if (!b0) { + Cudd_RecursiveDerefZdd(dd, f1); + Cudd_RecursiveDerefZdd(dd, f0); + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDeref(dd, b1); + return(NULL); } Cudd_Ref(b0); Cudd_RecursiveDerefZdd(dd, f1); Cudd_RecursiveDerefZdd(dd, f0); if (fd != dd->zero) { - bd = cuddMakeBddFromZddCover(dd, fd); - if (!bd) { + bd = cuddMakeBddFromZddCover(dd, fd); + if (!bd) { + Cudd_RecursiveDerefZdd(dd, fd); + Cudd_RecursiveDeref(dd, b1); + Cudd_RecursiveDeref(dd, b0); + return(NULL); + } + Cudd_Ref(bd); Cudd_RecursiveDerefZdd(dd, fd); - Cudd_RecursiveDeref(dd, b1); - Cudd_RecursiveDeref(dd, b0); - return(NULL); - } - Cudd_Ref(bd); - Cudd_RecursiveDerefZdd(dd, fd); - T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd)); - if (!T) { + T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd)); + if (!T) { + Cudd_RecursiveDeref(dd, b1); + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + return(NULL); + } + T = Cudd_NotCond(T, T != NULL); + Cudd_Ref(T); Cudd_RecursiveDeref(dd, b1); + E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd)); + if (!E) { + Cudd_RecursiveDeref(dd, b0); + Cudd_RecursiveDeref(dd, bd); + Cudd_RecursiveDeref(dd, T); + return(NULL); + } + E = Cudd_NotCond(E, E != NULL); + Cudd_Ref(E); Cudd_RecursiveDeref(dd, b0); Cudd_RecursiveDeref(dd, bd); - return(NULL); - } - T = Cudd_NotCond(T, T != NULL); - Cudd_Ref(T); - Cudd_RecursiveDeref(dd, b1); - E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd)); - if (!E) { - Cudd_RecursiveDeref(dd, b0); - Cudd_RecursiveDeref(dd, bd); - Cudd_RecursiveDeref(dd, T); - return(NULL); - } - E = Cudd_NotCond(E, E != NULL); - Cudd_Ref(E); - Cudd_RecursiveDeref(dd, b0); - Cudd_RecursiveDeref(dd, bd); } else { - Cudd_RecursiveDerefZdd(dd, fd); - T = b1; - E = b0; + Cudd_RecursiveDerefZdd(dd, fd); + T = b1; + E = b0; } if (Cudd_IsComplement(T)) { - neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E)); - if (!neW) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } - neW = Cudd_Not(neW); + neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E)); + if (!neW) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } + neW = Cudd_Not(neW); } else { - neW = cuddUniqueInterIVO(dd, v / 2, T, E); - if (!neW) { - Cudd_RecursiveDeref(dd, T); - Cudd_RecursiveDeref(dd, E); - return(NULL); - } + neW = cuddUniqueInterIVO(dd, v / 2, T, E); + if (!neW) { + Cudd_RecursiveDeref(dd, T); + Cudd_RecursiveDeref(dd, E); + return(NULL); + } } Cudd_Ref(neW); Cudd_RecursiveDeref(dd, T); @@ -886,5 +914,6 @@ cuddMakeBddFromZddCover( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddZddLin.c b/src/bdd/cudd/cuddZddLin.c index 14cad0b1..0c364413 100644 --- a/src/bdd/cudd/cuddZddLin.c +++ b/src/bdd/cudd/cuddZddLin.c @@ -7,37 +7,65 @@ Synopsis [Procedures for dynamic variable ordering of ZDDs.] Description [Internal procedures included in this module: - <ul> - <li> cuddZddLinearSifting() - </ul> - Static procedures included in this module: - <ul> - <li> cuddZddLinearInPlace() - <li> cuddZddLinerAux() - <li> cuddZddLinearUp() - <li> cuddZddLinearDown() - <li> cuddZddLinearBackward() - <li> cuddZddUndoMoves() - </ul> - ] + <ul> + <li> cuddZddLinearSifting() + </ul> + Static procedures included in this module: + <ul> + <li> cuddZddLinearInPlace() + <li> cuddZddLinerAux() + <li> cuddZddLinearUp() + <li> cuddZddLinearDown() + <li> cuddZddLinearBackward() + <li> cuddZddUndoMoves() + </ul> + ] SeeAlso [cuddLinear.c cuddZddReord.c] Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -61,13 +89,13 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddLin.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddLin.c,v 1.14 2004/08/13 18:04:53 fabio Exp $"; #endif -extern int *zdd_entry; -extern int zddTotalNumberSwapping; -static int zddTotalNumberLinearTr; -static DdNode *empty; +extern int *zdd_entry; +extern int zddTotalNumberSwapping; +static int zddTotalNumberLinearTr; +static DdNode *empty; /*---------------------------------------------------------------------------*/ @@ -81,11 +109,12 @@ static DdNode *empty; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int cuddZddLinearAux ARGS((DdManager *table, int x, int xLow, int xHigh)); -static Move * cuddZddLinearUp ARGS((DdManager *table, int y, int xLow, Move *prevMoves)); -static Move * cuddZddLinearDown ARGS((DdManager *table, int x, int xHigh, Move *prevMoves)); -static int cuddZddLinearBackward ARGS((DdManager *table, int size, Move *moves)); -static Move* cuddZddUndoMoves ARGS((DdManager *table, Move *moves)); +static int cuddZddLinearInPlace (DdManager * table, int x, int y); +static int cuddZddLinearAux (DdManager *table, int x, int xLow, int xHigh); +static Move * cuddZddLinearUp (DdManager *table, int y, int xLow, Move *prevMoves); +static Move * cuddZddLinearDown (DdManager *table, int x, int xHigh, Move *prevMoves); +static int cuddZddLinearBackward (DdManager *table, int size, Move *moves); +static Move* cuddZddUndoMoves (DdManager *table, Move *moves); /**AutomaticEnd***************************************************************/ @@ -129,13 +158,13 @@ cuddZddLinearSifting( int lower, int upper) { - int i; - int *var; - int size; - int x; - int result; + int i; + int *var; + int size; + int x; + int result; #ifdef DD_STATS - int previousSize; + int previousSize; #endif size = table->sizeZ; @@ -145,45 +174,45 @@ cuddZddLinearSifting( var = NULL; zdd_entry = ABC_ALLOC(int, size); if (zdd_entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; } var = ABC_ALLOC(int, size); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; } for (i = 0; i < size; i++) { - x = table->permZ[i]; - zdd_entry[i] = table->subtableZ[x].keys; - var[i] = i; + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; } - qsort((void *)var, size, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare); + qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { - if (zddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->permZ[var[i]]; - if (x < lower || x > upper) continue; + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif - result = cuddZddLinearAux(table, x, lower, upper); - if (!result) - goto cuddZddSiftingOutOfMem; + result = cuddZddLinearAux(table, x, lower, upper); + if (!result) + goto cuddZddSiftingOutOfMem; #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); /* should never happen */ - (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } @@ -222,23 +251,23 @@ cuddZddSiftingOutOfMem: SeeAlso [cuddZddSwapInPlace cuddLinearInPlace] ******************************************************************************/ -int +static int cuddZddLinearInPlace( DdManager * table, int x, int y) { DdNodePtr *xlist, *ylist; - int xindex, yindex; - int xslots, yslots; - int xshift, yshift; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; int oldxkeys, oldykeys; int newxkeys, newykeys; - int i; - int posn; - DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; - DdNode *newf1, *newf0, *g, *next, *previous; - DdNode *special; + int i; + int posn; + DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; + DdNode *newf1, *newf0, *g, *next, *previous; + DdNode *special; #ifdef DD_DEBUG assert(x < y); @@ -274,61 +303,61 @@ cuddZddLinearInPlace( */ g = special = NULL; for (i = 0; i < xslots; i++) { - f = xlist[i]; - if (f == NULL) continue; - xlist[i] = NULL; - while (f != NULL) { - next = f->next; - f1 = cuddT(f); - /* if (f1->index == yindex) */ cuddSatDec(f1->ref); - f0 = cuddE(f); - /* if (f0->index == yindex) */ cuddSatDec(f0->ref); - if ((int) f1->index == yindex && cuddE(f1) == empty && - (int) f0->index != yindex) { - f->next = special; - special = f; - } else { - f->next = g; - g = f; - } - f = next; - } /* while there are elements in the collision chain */ + f = xlist[i]; + if (f == NULL) continue; + xlist[i] = NULL; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); + /* if (f1->index == yindex) */ cuddSatDec(f1->ref); + f0 = cuddE(f); + /* if (f0->index == yindex) */ cuddSatDec(f0->ref); + if ((int) f1->index == yindex && cuddE(f1) == empty && + (int) f0->index != yindex) { + f->next = special; + special = f; + } else { + f->next = g; + g = f; + } + f = next; + } /* while there are elements in the collision chain */ } /* for each slot of the x subtable */ /* Mark y nodes with pointers from above x. We mark them by ** changing their index to x. */ for (i = 0; i < yslots; i++) { - f = ylist[i]; - while (f != NULL) { - if (f->ref != 0) { - f->index = xindex; - } - f = f->next; - } /* while there are elements in the collision chain */ + f = ylist[i]; + while (f != NULL) { + if (f->ref != 0) { + f->index = xindex; + } + f = f->next; + } /* while there are elements in the collision chain */ } /* for each slot of the y subtable */ /* Move special nodes to the y list. */ f = special; while (f != NULL) { - next = f->next; - f1 = cuddT(f); - f11 = cuddT(f1); - cuddT(f) = f11; - cuddSatInc(f11->ref); - f0 = cuddE(f); - cuddSatInc(f0->ref); - f->index = yindex; - /* Insert at the beginning of the list so that it will be - ** found first if there is a duplicate. The duplicate will - ** eventually be moved or garbage collected. No node - ** re-expression will add a pointer to it. - */ - posn = ddHash(f11, f0, yshift); - f->next = ylist[posn]; - ylist[posn] = f; - newykeys++; - f = next; + next = f->next; + f1 = cuddT(f); + f11 = cuddT(f1); + cuddT(f) = f11; + cuddSatInc(f11->ref); + f0 = cuddE(f); + cuddSatInc(f0->ref); + f->index = yindex; + /* Insert at the beginning of the list so that it will be + ** found first if there is a duplicate. The duplicate will + ** eventually be moved or garbage collected. No node + ** re-expression will add a pointer to it. + */ + posn = ddHash(f11, f0, yshift); + f->next = ylist[posn]; + ylist[posn] = f; + newykeys++; + f = next; } /* Take care of the remaining x nodes that must be re-expressed. @@ -337,172 +366,172 @@ cuddZddLinearInPlace( f = g; while (f != NULL) { #ifdef DD_COUNT - table->swapSteps++; + table->swapSteps++; #endif - next = f->next; - /* Find f1, f0, f11, f10, f01, f00. */ - f1 = cuddT(f); - if ((int) f1->index == yindex || (int) f1->index == xindex) { - f11 = cuddT(f1); f10 = cuddE(f1); - } else { - f11 = empty; f10 = f1; - } - f0 = cuddE(f); - if ((int) f0->index == yindex || (int) f0->index == xindex) { - f01 = cuddT(f0); f00 = cuddE(f0); - } else { - f01 = empty; f00 = f0; - } - /* Create the new T child. */ - if (f01 == empty) { - newf1 = f10; - cuddSatInc(newf1->ref); - } else { - /* Check ylist for triple (yindex, f01, f10). */ - posn = ddHash(f01, f10, yshift); - /* For each element newf1 in collision list ylist[posn]. */ - newf1 = ylist[posn]; - /* Search the collision chain skipping the marked nodes. */ - while (newf1 != NULL) { - if (cuddT(newf1) == f01 && cuddE(newf1) == f10 && - (int) newf1->index == yindex) { - cuddSatInc(newf1->ref); - break; /* match */ + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + if ((int) f1->index == yindex || (int) f1->index == xindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = empty; f10 = f1; } - newf1 = newf1->next; - } /* while newf1 */ - if (newf1 == NULL) { /* no match */ - newf1 = cuddDynamicAllocNode(table); - if (newf1 == NULL) - goto zddSwapOutOfMem; - newf1->index = yindex; newf1->ref = 1; - cuddT(newf1) = f01; - cuddE(newf1) = f10; - /* Insert newf1 in the collision list ylist[pos]; - ** increase the ref counts of f01 and f10 - */ - newykeys++; - newf1->next = ylist[posn]; - ylist[posn] = newf1; - cuddSatInc(f01->ref); - cuddSatInc(f10->ref); + f0 = cuddE(f); + if ((int) f0->index == yindex || (int) f0->index == xindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = empty; f00 = f0; } - } - cuddT(f) = newf1; + /* Create the new T child. */ + if (f01 == empty) { + newf1 = f10; + cuddSatInc(newf1->ref); + } else { + /* Check ylist for triple (yindex, f01, f10). */ + posn = ddHash(f01, f10, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + newf1 = ylist[posn]; + /* Search the collision chain skipping the marked nodes. */ + while (newf1 != NULL) { + if (cuddT(newf1) == f01 && cuddE(newf1) == f10 && + (int) newf1->index == yindex) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f01; + cuddE(newf1) = f10; + /* Insert newf1 in the collision list ylist[pos]; + ** increase the ref counts of f01 and f10 + */ + newykeys++; + newf1->next = ylist[posn]; + ylist[posn] = newf1; + cuddSatInc(f01->ref); + cuddSatInc(f10->ref); + } + } + cuddT(f) = newf1; - /* Do the same for f0. */ - /* Create the new E child. */ - if (f11 == empty) { - newf0 = f00; - cuddSatInc(newf0->ref); - } else { - /* Check ylist for triple (yindex, f11, f00). */ - posn = ddHash(f11, f00, yshift); - /* For each element newf0 in collision list ylist[posn]. */ - newf0 = ylist[posn]; - while (newf0 != NULL) { - if (cuddT(newf0) == f11 && cuddE(newf0) == f00 && - (int) newf0->index == yindex) { + /* Do the same for f0. */ + /* Create the new E child. */ + if (f11 == empty) { + newf0 = f00; cuddSatInc(newf0->ref); - break; /* match */ - } - newf0 = newf0->next; - } /* while newf0 */ - if (newf0 == NULL) { /* no match */ - newf0 = cuddDynamicAllocNode(table); - if (newf0 == NULL) - goto zddSwapOutOfMem; - newf0->index = yindex; newf0->ref = 1; - cuddT(newf0) = f11; cuddE(newf0) = f00; - /* Insert newf0 in the collision list ylist[posn]; - ** increase the ref counts of f11 and f00. - */ - newykeys++; - newf0->next = ylist[posn]; - ylist[posn] = newf0; - cuddSatInc(f11->ref); - cuddSatInc(f00->ref); + } else { + /* Check ylist for triple (yindex, f11, f00). */ + posn = ddHash(f11, f00, yshift); + /* For each element newf0 in collision list ylist[posn]. */ + newf0 = ylist[posn]; + while (newf0 != NULL) { + if (cuddT(newf0) == f11 && cuddE(newf0) == f00 && + (int) newf0->index == yindex) { + cuddSatInc(newf0->ref); + break; /* match */ + } + newf0 = newf0->next; + } /* while newf0 */ + if (newf0 == NULL) { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto zddSwapOutOfMem; + newf0->index = yindex; newf0->ref = 1; + cuddT(newf0) = f11; cuddE(newf0) = f00; + /* Insert newf0 in the collision list ylist[posn]; + ** increase the ref counts of f11 and f00. + */ + newykeys++; + newf0->next = ylist[posn]; + ylist[posn] = newf0; + cuddSatInc(f11->ref); + cuddSatInc(f00->ref); + } } - } - cuddE(f) = newf0; + cuddE(f) = newf0; - /* Re-insert the modified f in xlist. - ** The modified f does not already exists in xlist. - ** (Because of the uniqueness of the cofactors.) - */ - posn = ddHash(newf1, newf0, xshift); - newxkeys++; - f->next = xlist[posn]; - xlist[posn] = f; - f = next; + /* Re-insert the modified f in xlist. + ** The modified f does not already exists in xlist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, xshift); + newxkeys++; + f->next = xlist[posn]; + xlist[posn] = f; + f = next; } /* while f != NULL */ /* GC the y layer and move the marked nodes to the x list. */ /* For each node f in ylist. */ for (i = 0; i < yslots; i++) { - previous = NULL; - f = ylist[i]; - while (f != NULL) { - next = f->next; - if (f->ref == 0) { - cuddSatDec(cuddT(f)->ref); - cuddSatDec(cuddE(f)->ref); - cuddDeallocNode(table, f); - newykeys--; - if (previous == NULL) - ylist[i] = next; - else - previous->next = next; - } else if ((int) f->index == xindex) { /* move marked node */ - if (previous == NULL) - ylist[i] = next; - else - previous->next = next; - f1 = cuddT(f); - cuddSatDec(f1->ref); - /* Check ylist for triple (yindex, f1, empty). */ - posn = ddHash(f1, empty, yshift); - /* For each element newf1 in collision list ylist[posn]. */ - newf1 = ylist[posn]; - while (newf1 != NULL) { - if (cuddT(newf1) == f1 && cuddE(newf1) == empty && - (int) newf1->index == yindex) { - cuddSatInc(newf1->ref); - break; /* match */ + previous = NULL; + f = ylist[i]; + while (f != NULL) { + next = f->next; + if (f->ref == 0) { + cuddSatDec(cuddT(f)->ref); + cuddSatDec(cuddE(f)->ref); + cuddDeallocNode(table, f); + newykeys--; + if (previous == NULL) + ylist[i] = next; + else + previous->next = next; + } else if ((int) f->index == xindex) { /* move marked node */ + if (previous == NULL) + ylist[i] = next; + else + previous->next = next; + f1 = cuddT(f); + cuddSatDec(f1->ref); + /* Check ylist for triple (yindex, f1, empty). */ + posn = ddHash(f1, empty, yshift); + /* For each element newf1 in collision list ylist[posn]. */ + newf1 = ylist[posn]; + while (newf1 != NULL) { + if (cuddT(newf1) == f1 && cuddE(newf1) == empty && + (int) newf1->index == yindex) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = yindex; newf1->ref = 1; + cuddT(newf1) = f1; cuddE(newf1) = empty; + /* Insert newf1 in the collision list ylist[posn]; + ** increase the ref counts of f1 and empty. + */ + newykeys++; + newf1->next = ylist[posn]; + ylist[posn] = newf1; + if (posn == i && previous == NULL) + previous = newf1; + cuddSatInc(f1->ref); + cuddSatInc(empty->ref); + } + cuddT(f) = newf1; + f0 = cuddE(f); + /* Insert f in x list. */ + posn = ddHash(newf1, f0, xshift); + newxkeys++; + newykeys--; + f->next = xlist[posn]; + xlist[posn] = f; + } else { + previous = f; } - newf1 = newf1->next; - } /* while newf1 */ - if (newf1 == NULL) { /* no match */ - newf1 = cuddDynamicAllocNode(table); - if (newf1 == NULL) - goto zddSwapOutOfMem; - newf1->index = yindex; newf1->ref = 1; - cuddT(newf1) = f1; cuddE(newf1) = empty; - /* Insert newf1 in the collision list ylist[posn]; - ** increase the ref counts of f1 and empty. - */ - newykeys++; - newf1->next = ylist[posn]; - ylist[posn] = newf1; - if (posn == i && previous == NULL) - previous = newf1; - cuddSatInc(f1->ref); - cuddSatInc(empty->ref); - } - cuddT(f) = newf1; - f0 = cuddE(f); - /* Insert f in x list. */ - posn = ddHash(newf1, f0, xshift); - newxkeys++; - newykeys--; - f->next = xlist[posn]; - xlist[posn] = f; - } else { - previous = f; - } - f = next; - } /* while f */ + f = next; + } /* while f */ } /* for i */ /* Set the appropriate fields in table. */ @@ -551,12 +580,12 @@ cuddZddLinearAux( int xLow, int xHigh) { - Move *move; - Move *moveUp; /* list of up move */ - Move *moveDown; /* list of down move */ + Move *move; + Move *moveUp; /* list of up move */ + Move *moveDown; /* list of down move */ - int initial_size; - int result; + int initial_size; + int result; initial_size = table->keysZ; @@ -568,88 +597,88 @@ cuddZddLinearAux( moveUp = NULL; if (x == xLow) { - moveDown = cuddZddLinearDown(table, x, xHigh, NULL); - /* At this point x --> xHigh. */ - if (moveDown == (Move *) CUDD_OUT_OF_MEM) - goto cuddZddLinearAuxOutOfMem; - /* Move backward and stop at best position. */ - result = cuddZddLinearBackward(table, initial_size, moveDown); - if (!result) - goto cuddZddLinearAuxOutOfMem; + moveDown = cuddZddLinearDown(table, x, xHigh, NULL); + /* At this point x --> xHigh. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveDown); + if (!result) + goto cuddZddLinearAuxOutOfMem; } else if (x == xHigh) { - moveUp = cuddZddLinearUp(table, x, xLow, NULL); - /* At this point x --> xLow. */ - if (moveUp == (Move *) CUDD_OUT_OF_MEM) - goto cuddZddLinearAuxOutOfMem; - /* Move backward and stop at best position. */ - result = cuddZddLinearBackward(table, initial_size, moveUp); - if (!result) - goto cuddZddLinearAuxOutOfMem; + moveUp = cuddZddLinearUp(table, x, xLow, NULL); + /* At this point x --> xLow. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveUp); + if (!result) + goto cuddZddLinearAuxOutOfMem; } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */ - moveDown = cuddZddLinearDown(table, x, xHigh, NULL); - /* At this point x --> xHigh. */ - if (moveDown == (Move *) CUDD_OUT_OF_MEM) - goto cuddZddLinearAuxOutOfMem; - moveUp = cuddZddUndoMoves(table,moveDown); + moveDown = cuddZddLinearDown(table, x, xHigh, NULL); + /* At this point x --> xHigh. */ + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + moveUp = cuddZddUndoMoves(table,moveDown); #ifdef DD_DEBUG - assert(moveUp == NULL || moveUp->x == x); + assert(moveUp == NULL || moveUp->x == x); #endif - moveUp = cuddZddLinearUp(table, x, xLow, moveUp); - if (moveUp == (Move *) CUDD_OUT_OF_MEM) - goto cuddZddLinearAuxOutOfMem; - /* Move backward and stop at best position. */ - result = cuddZddLinearBackward(table, initial_size, moveUp); - if (!result) - goto cuddZddLinearAuxOutOfMem; + moveUp = cuddZddLinearUp(table, x, xLow, moveUp); + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveUp); + if (!result) + goto cuddZddLinearAuxOutOfMem; } else { - moveUp = cuddZddLinearUp(table, x, xLow, NULL); - /* At this point x --> xHigh. */ - if (moveUp == (Move *) CUDD_OUT_OF_MEM) - goto cuddZddLinearAuxOutOfMem; - /* Then move up. */ - moveDown = cuddZddUndoMoves(table,moveUp); + moveUp = cuddZddLinearUp(table, x, xLow, NULL); + /* At this point x --> xHigh. */ + if (moveUp == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Then move up. */ + moveDown = cuddZddUndoMoves(table,moveUp); #ifdef DD_DEBUG - assert(moveDown == NULL || moveDown->y == x); + assert(moveDown == NULL || moveDown->y == x); #endif - moveDown = cuddZddLinearDown(table, x, xHigh, moveDown); - if (moveDown == (Move *) CUDD_OUT_OF_MEM) - goto cuddZddLinearAuxOutOfMem; - /* Move backward and stop at best position. */ - result = cuddZddLinearBackward(table, initial_size, moveDown); - if (!result) - goto cuddZddLinearAuxOutOfMem; + moveDown = cuddZddLinearDown(table, x, xHigh, moveDown); + if (moveDown == (Move *) CUDD_OUT_OF_MEM) + goto cuddZddLinearAuxOutOfMem; + /* Move backward and stop at best position. */ + result = cuddZddLinearBackward(table, initial_size, moveDown); + if (!result) + goto cuddZddLinearAuxOutOfMem; } while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *)moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *)moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(1); cuddZddLinearAuxOutOfMem: if (moveDown != (Move *) CUDD_OUT_OF_MEM) { - while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *)moveDown); - moveDown = move; - } + while (moveDown != NULL) { + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; + } } if (moveUp != (Move *) CUDD_OUT_OF_MEM) { - while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *)moveUp); - moveUp = move; - } + while (moveUp != NULL) { + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; + } } return(0); @@ -678,64 +707,64 @@ cuddZddLinearUp( int xLow, Move * prevMoves) { - Move *moves; - Move *move; - int x; - int size, newsize; - int limitSize; + Move *moves; + Move *move; + int x; + int size, newsize; + int limitSize; moves = prevMoves; limitSize = table->keysZ; x = cuddZddNextLow(table, y); while (x >= xLow) { - size = cuddZddSwapInPlace(table, x, y); - if (size == 0) - goto cuddZddLinearUpOutOfMem; - newsize = cuddZddLinearInPlace(table, x, y); - if (newsize == 0) - goto cuddZddLinearUpOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) - goto cuddZddLinearUpOutOfMem; - move->x = x; - move->y = y; - move->next = moves; - moves = move; - move->flags = CUDD_SWAP_MOVE; - if (newsize > size) { - /* Undo transformation. The transformation we apply is - ** its own inverse. Hence, we just apply the transformation - ** again. - */ - newsize = cuddZddLinearInPlace(table,x,y); - if (newsize == 0) goto cuddZddLinearUpOutOfMem; + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddLinearUpOutOfMem; + newsize = cuddZddLinearInPlace(table, x, y); + if (newsize == 0) + goto cuddZddLinearUpOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddLinearUpOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize > size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddZddLinearInPlace(table,x,y); + if (newsize == 0) goto cuddZddLinearUpOutOfMem; #ifdef DD_DEBUG - if (newsize != size) { - (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); - } + if (newsize != size) { + (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } #endif - } else { - size = newsize; - move->flags = CUDD_LINEAR_TRANSFORM_MOVE; - } - move->size = size; + } else { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; + } + move->size = size; - if ((double)size > (double)limitSize * table->maxGrowth) - break; + if ((double)size > (double)limitSize * table->maxGrowth) + break; if (size < limitSize) - limitSize = size; + limitSize = size; - y = x; - x = cuddZddNextLow(table, y); + y = x; + x = cuddZddNextLow(table, y); } return(moves); cuddZddLinearUpOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return((Move *) CUDD_OUT_OF_MEM); @@ -763,62 +792,62 @@ cuddZddLinearDown( int xHigh, Move * prevMoves) { - Move *moves; - Move *move; - int y; - int size, newsize; - int limitSize; + Move *moves; + Move *move; + int y; + int size, newsize; + int limitSize; moves = prevMoves; limitSize = table->keysZ; y = cuddZddNextHigh(table, x); while (y <= xHigh) { - size = cuddZddSwapInPlace(table, x, y); - if (size == 0) - goto cuddZddLinearDownOutOfMem; - newsize = cuddZddLinearInPlace(table, x, y); - if (newsize == 0) - goto cuddZddLinearDownOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) - goto cuddZddLinearDownOutOfMem; - move->x = x; - move->y = y; - move->next = moves; - moves = move; - move->flags = CUDD_SWAP_MOVE; - if (newsize > size) { - /* Undo transformation. The transformation we apply is - ** its own inverse. Hence, we just apply the transformation - ** again. - */ - newsize = cuddZddLinearInPlace(table,x,y); - if (newsize == 0) goto cuddZddLinearDownOutOfMem; - if (newsize != size) { - (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddLinearDownOutOfMem; + newsize = cuddZddLinearInPlace(table, x, y); + if (newsize == 0) + goto cuddZddLinearDownOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddLinearDownOutOfMem; + move->x = x; + move->y = y; + move->next = moves; + moves = move; + move->flags = CUDD_SWAP_MOVE; + if (newsize > size) { + /* Undo transformation. The transformation we apply is + ** its own inverse. Hence, we just apply the transformation + ** again. + */ + newsize = cuddZddLinearInPlace(table,x,y); + if (newsize == 0) goto cuddZddLinearDownOutOfMem; + if (newsize != size) { + (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize); + } + } else { + size = newsize; + move->flags = CUDD_LINEAR_TRANSFORM_MOVE; } - } else { - size = newsize; - move->flags = CUDD_LINEAR_TRANSFORM_MOVE; - } - move->size = size; + move->size = size; - if ((double)size > (double)limitSize * table->maxGrowth) - break; + if ((double)size > (double)limitSize * table->maxGrowth) + break; if (size < limitSize) - limitSize = size; + limitSize = size; - x = y; - y = cuddZddNextHigh(table, x); + x = y; + y = cuddZddNextHigh(table, x); } return(moves); cuddZddLinearDownOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return((Move *) CUDD_OUT_OF_MEM); @@ -846,29 +875,29 @@ cuddZddLinearBackward( int size, Move * moves) { - Move *move; - int res; + Move *move; + int res; /* Find the minimum size among moves. */ for (move = moves; move != NULL; move = move->next) { - if (move->size < size) { - size = move->size; - } + if (move->size < size) { + size = move->size; + } } for (move = moves; move != NULL; move = move->next) { - if (move->size == size) return(1); - if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { - res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); - if (!res) return(0); - } - res = cuddZddSwapInPlace(table, move->x, move->y); - if (!res) - return(0); - if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { - res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); - if (!res) return(0); - } + if (move->size == size) return(1); + if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) + return(0); + if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) { + res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!res) return(0); + } } return(1); @@ -896,49 +925,51 @@ cuddZddUndoMoves( Move *invmoves = NULL; Move *move; Move *invmove; - int size; + int size; for (move = moves; move != NULL; move = move->next) { - invmove = (Move *) cuddDynamicAllocNode(table); - if (invmove == NULL) goto cuddZddUndoMovesOutOfMem; - invmove->x = move->x; - invmove->y = move->y; - invmove->next = invmoves; - invmoves = invmove; - if (move->flags == CUDD_SWAP_MOVE) { - invmove->flags = CUDD_SWAP_MOVE; - size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); - if (!size) goto cuddZddUndoMovesOutOfMem; - } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { - invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; - size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); - if (!size) goto cuddZddUndoMovesOutOfMem; - size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); - if (!size) goto cuddZddUndoMovesOutOfMem; - } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ + invmove = (Move *) cuddDynamicAllocNode(table); + if (invmove == NULL) goto cuddZddUndoMovesOutOfMem; + invmove->x = move->x; + invmove->y = move->y; + invmove->next = invmoves; + invmoves = invmove; + if (move->flags == CUDD_SWAP_MOVE) { + invmove->flags = CUDD_SWAP_MOVE; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) { + invmove->flags = CUDD_INVERSE_TRANSFORM_MOVE; + size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */ #ifdef DD_DEBUG - (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); + (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n"); #endif - invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; - size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); - if (!size) goto cuddZddUndoMovesOutOfMem; - size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); - if (!size) goto cuddZddUndoMovesOutOfMem; - } - invmove->size = size; + invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE; + size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y); + if (!size) goto cuddZddUndoMovesOutOfMem; + } + invmove->size = size; } return(invmoves); cuddZddUndoMovesOutOfMem: while (invmoves != NULL) { - move = invmoves->next; - cuddDeallocNode(table, (DdNode *) invmoves); - invmoves = move; + move = invmoves->next; + cuddDeallocMove(table, invmoves); + invmoves = move; } return((Move *) CUDD_OUT_OF_MEM); } /* end of cuddZddUndoMoves */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddZddMisc.c b/src/bdd/cudd/cuddZddMisc.c index b78faea1..4d28f6a7 100644 --- a/src/bdd/cudd/cuddZddMisc.c +++ b/src/bdd/cudd/cuddZddMisc.c @@ -4,41 +4,69 @@ PackageName [cudd] - Synopsis [.] + Synopsis [Miscellaneous utility functions for ZDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddDagSize() - <li> Cudd_zddCountMinterm() - <li> Cudd_zddPrintSubtable() - </ul> - Internal procedures included in this module: - <ul> - </ul> - Static procedures included in this module: - <ul> - <li> cuddZddDagInt() - </ul> - ] + <ul> + <li> Cudd_zddDagSize() + <li> Cudd_zddCountMinterm() + <li> Cudd_zddPrintSubtable() + </ul> + Internal procedures included in this module: + <ul> + </ul> + Static procedures included in this module: + <ul> + <li> cuddZddDagInt() + </ul> + ] SeeAlso [] Author [Hyong-Kyoon Shin, In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include <math.h> -#include "util_hack.h" -#include "cuddInt.h" +#include <math.h> +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -59,7 +87,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.16 2009/02/20 02:14:58 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -73,7 +101,7 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddMisc.c,v 1.1.1.1 2003/02/24 22:23:5 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int cuddZddDagInt ARGS((DdNode *n, st_table *tab)); +static int cuddZddDagInt (DdNode *n, st_table *tab); /**AutomaticEnd***************************************************************/ @@ -100,7 +128,7 @@ Cudd_zddDagSize( DdNode * p_node) { - int i; + int i; st_table *table; table = st_init_table(st_ptrcmp, st_ptrhash); @@ -132,7 +160,7 @@ Cudd_zddCountMinterm( DdNode * node, int path) { - double dc_var, minterms; + double dc_var, minterms; dc_var = (double)((double)(zdd->sizeZ) - (double)path); minterms = Cudd_zddCountDouble(zdd, node) / pow(2.0, dc_var); @@ -156,61 +184,61 @@ void Cudd_zddPrintSubtable( DdManager * table) { - int i, j; - DdNode *z1, *z1_next, *base; - DdSubtable *ZSubTable; + int i, j; + DdNode *z1, *z1_next, *base; + DdSubtable *ZSubTable; base = table->one; for (i = table->sizeZ - 1; i >= 0; i--) { - ZSubTable = &(table->subtableZ[i]); - printf("subtable[%d]:\n", i); - for (j = ZSubTable->slots - 1; j >= 0; j--) { - z1 = ZSubTable->nodelist[j]; - while (z1 != NIL(DdNode)) { - (void) fprintf(table->out, + ZSubTable = &(table->subtableZ[i]); + printf("subtable[%d]:\n", i); + for (j = ZSubTable->slots - 1; j >= 0; j--) { + z1 = ZSubTable->nodelist[j]; + while (z1 != NIL(DdNode)) { + (void) fprintf(table->out, #if SIZEOF_VOID_P == 8 - "ID = 0x%lx\tindex = %d\tr = %d\t", - (unsigned long) z1 / (unsigned long) sizeof(DdNode), - z1->index, z1->ref); + "ID = 0x%lx\tindex = %u\tr = %u\t", + (ptruint) z1 / (ptruint) sizeof(DdNode), + z1->index, z1->ref); #else - "ID = 0x%x\tindex = %d\tr = %d\t", - (unsigned) z1 / (unsigned) sizeof(DdNode), - z1->index, z1->ref); + "ID = 0x%x\tindex = %hu\tr = %hu\t", + (ptruint) z1 / (ptruint) sizeof(DdNode), + z1->index, z1->ref); #endif - z1_next = cuddT(z1); - if (Cudd_IsConstant(z1_next)) { - (void) fprintf(table->out, "T = %d\t\t", - (z1_next == base)); - } - else { + z1_next = cuddT(z1); + if (Cudd_IsConstant(z1_next)) { + (void) fprintf(table->out, "T = %d\t\t", + (z1_next == base)); + } + else { #if SIZEOF_VOID_P == 8 - (void) fprintf(table->out, "T = 0x%lx\t", - (unsigned long) z1_next / (unsigned long) sizeof(DdNode)); + (void) fprintf(table->out, "T = 0x%lx\t", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); #else - (void) fprintf(table->out, "T = 0x%x\t", - (unsigned) z1_next / (unsigned) sizeof(DdNode)); + (void) fprintf(table->out, "T = 0x%x\t", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); #endif - } - z1_next = cuddE(z1); - if (Cudd_IsConstant(z1_next)) { - (void) fprintf(table->out, "E = %d\n", - (z1_next == base)); - } - else { + } + z1_next = cuddE(z1); + if (Cudd_IsConstant(z1_next)) { + (void) fprintf(table->out, "E = %d\n", + (z1_next == base)); + } + else { #if SIZEOF_VOID_P == 8 - (void) fprintf(table->out, "E = 0x%lx\n", - (unsigned long) z1_next / (unsigned long) sizeof(DdNode)); + (void) fprintf(table->out, "E = 0x%lx\n", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); #else - (void) fprintf(table->out, "E = 0x%x\n", - (unsigned) z1_next / (unsigned) sizeof(DdNode)); + (void) fprintf(table->out, "E = 0x%x\n", + (ptruint) z1_next / (ptruint) sizeof(DdNode)); #endif - } + } - z1_next = z1->next; - z1 = z1_next; + z1_next = z1->next; + z1 = z1_next; + } } } - } putchar('\n'); } /* Cudd_zddPrintSubtable */ @@ -239,19 +267,20 @@ cuddZddDagInt( st_table * tab) { if (n == NIL(DdNode)) - return(0); + return(0); if (st_is_member(tab, (char *)n) == 1) - return(0); + return(0); if (Cudd_IsConstant(n)) - return(0); + return(0); (void)st_insert(tab, (char *)n, NIL(char)); return(1 + cuddZddDagInt(cuddT(n), tab) + - cuddZddDagInt(cuddE(n), tab)); + cuddZddDagInt(cuddE(n), tab)); } /* cuddZddDagInt */ + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/cuddZddPort.c b/src/bdd/cudd/cuddZddPort.c index dfefece1..76b46ca5 100644 --- a/src/bdd/cudd/cuddZddPort.c +++ b/src/bdd/cudd/cuddZddPort.c @@ -7,37 +7,65 @@ Synopsis [Functions that translate BDDs to ZDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddPortFromBdd() - <li> Cudd_zddPortToBdd() - </ul> - Internal procedures included in this module: - <ul> - </ul> - Static procedures included in this module: - <ul> - <li> zddPortFromBddStep() - <li> zddPortToBddStep() - </ul> - ] + <ul> + <li> Cudd_zddPortFromBdd() + <li> Cudd_zddPortToBdd() + </ul> + Internal procedures included in this module: + <ul> + </ul> + Static procedures included in this module: + <ul> + <li> zddPortFromBddStep() + <li> zddPortToBddStep() + </ul> + ] SeeAlso [] Author [Hyong-kyoon Shin, In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -58,7 +86,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.13 2004/08/13 18:04:53 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -72,8 +100,8 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddPort.c,v 1.1.1.1 2003/02/24 22:23:5 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * zddPortFromBddStep ARGS((DdManager *dd, DdNode *B, int expected)); -static DdNode * zddPortToBddStep ARGS((DdManager *dd, DdNode *f, int depth)); +static DdNode * zddPortFromBddStep (DdManager *dd, DdNode *B, int expected); +static DdNode * zddPortToBddStep (DdManager *dd, DdNode *f, int depth); /**AutomaticEnd***************************************************************/ @@ -107,8 +135,8 @@ Cudd_zddPortFromBdd( DdNode *res; do { - dd->reordered = 0; - res = zddPortFromBddStep(dd,B,0); + dd->reordered = 0; + res = zddPortFromBddStep(dd,B,0); } while (dd->reordered == 1); return(res); @@ -136,8 +164,8 @@ Cudd_zddPortToBdd( DdNode *res; do { - dd->reordered = 0; - res = zddPortToBddStep(dd,f,0); + dd->reordered = 0; + res = zddPortToBddStep(dd,f,0); } while (dd->reordered == 1); return(res); @@ -171,20 +199,20 @@ zddPortFromBddStep( DdNode * B, int expected) { - DdNode *res, *prevZdd, *t, *e; - DdNode *Breg, *Bt, *Be; - int id, level; + DdNode *res, *prevZdd, *t, *e; + DdNode *Breg, *Bt, *Be; + int id, level; statLine(dd); /* Terminal cases. */ if (B == Cudd_Not(DD_ONE(dd))) - return(DD_ZERO(dd)); + return(DD_ZERO(dd)); if (B == DD_ONE(dd)) { - if (expected >= dd->sizeZ) { - return(DD_ONE(dd)); - } else { - return(dd->univ[expected]); - } + if (expected >= dd->sizeZ) { + return(DD_ONE(dd)); + } else { + return(dd->univ[expected]); + } } Breg = Cudd_Regular(B); @@ -192,33 +220,33 @@ zddPortFromBddStep( /* Computed table look-up. */ res = cuddCacheLookup1Zdd(dd,Cudd_zddPortFromBdd,B); if (res != NULL) { - level = cuddI(dd,Breg->index); - /* Adding DC vars. */ - if (expected < level) { - /* Add suppressed variables. */ - cuddRef(res); - for (level--; level >= expected; level--) { - prevZdd = res; - id = dd->invperm[level]; - res = cuddZddGetNode(dd, id, prevZdd, prevZdd); - if (res == NULL) { - Cudd_RecursiveDerefZdd(dd, prevZdd); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDerefZdd(dd, prevZdd); + level = cuddI(dd,Breg->index); + /* Adding DC vars. */ + if (expected < level) { + /* Add suppressed variables. */ + cuddRef(res); + for (level--; level >= expected; level--) { + prevZdd = res; + id = dd->invperm[level]; + res = cuddZddGetNode(dd, id, prevZdd, prevZdd); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, prevZdd); + return(NULL); + } + cuddRef(res); + Cudd_RecursiveDerefZdd(dd, prevZdd); + } + cuddDeref(res); } - cuddDeref(res); - } - return(res); - } /* end of cache look-up */ + return(res); + } /* end of cache look-up */ if (Cudd_IsComplement(B)) { - Bt = Cudd_Not(cuddT(Breg)); - Be = Cudd_Not(cuddE(Breg)); + Bt = Cudd_Not(cuddT(Breg)); + Be = Cudd_Not(cuddE(Breg)); } else { - Bt = cuddT(Breg); - Be = cuddE(Breg); + Bt = cuddT(Breg); + Be = cuddE(Breg); } id = Breg->index; @@ -228,15 +256,15 @@ zddPortFromBddStep( cuddRef(t); e = zddPortFromBddStep(dd, Be, level+1); if (e == NULL) { - Cudd_RecursiveDerefZdd(dd, t); - return(NULL); + Cudd_RecursiveDerefZdd(dd, t); + return(NULL); } cuddRef(e); res = cuddZddGetNode(dd, id, t, e); if (res == NULL) { - Cudd_RecursiveDerefZdd(dd, t); - Cudd_RecursiveDerefZdd(dd, e); - return(NULL); + Cudd_RecursiveDerefZdd(dd, t); + Cudd_RecursiveDerefZdd(dd, e); + return(NULL); } cuddRef(res); Cudd_RecursiveDerefZdd(dd, t); @@ -245,15 +273,15 @@ zddPortFromBddStep( cuddCacheInsert1(dd,Cudd_zddPortFromBdd,B,res); for (level--; level >= expected; level--) { - prevZdd = res; - id = dd->invperm[level]; - res = cuddZddGetNode(dd, id, prevZdd, prevZdd); - if (res == NULL) { + prevZdd = res; + id = dd->invperm[level]; + res = cuddZddGetNode(dd, id, prevZdd, prevZdd); + if (res == NULL) { + Cudd_RecursiveDerefZdd(dd, prevZdd); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDerefZdd(dd, prevZdd); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDerefZdd(dd, prevZdd); } cuddDeref(res); @@ -297,51 +325,51 @@ zddPortToBddStep( cuddRef(var); if (level > (unsigned) depth) { - E = zddPortToBddStep(dd,f,depth+1); - if (E == NULL) { - Cudd_RecursiveDeref(dd,var); - return(NULL); - } - cuddRef(E); - res = cuddBddIteRecur(dd,var,Cudd_Not(one),E); - if (res == NULL) { + E = zddPortToBddStep(dd,f,depth+1); + if (E == NULL) { + Cudd_RecursiveDeref(dd,var); + return(NULL); + } + cuddRef(E); + res = cuddBddIteRecur(dd,var,Cudd_Not(one),E); + if (res == NULL) { + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,E); + return(NULL); + } + cuddRef(res); Cudd_RecursiveDeref(dd,var); Cudd_RecursiveDeref(dd,E); - return(NULL); - } - cuddRef(res); - Cudd_RecursiveDeref(dd,var); - Cudd_RecursiveDeref(dd,E); - cuddDeref(res); - return(res); + cuddDeref(res); + return(res); } res = cuddCacheLookup1(dd,Cudd_zddPortToBdd,f); if (res != NULL) { - Cudd_RecursiveDeref(dd,var); - return(res); + Cudd_RecursiveDeref(dd,var); + return(res); } T = zddPortToBddStep(dd,cuddT(f),depth+1); if (T == NULL) { - Cudd_RecursiveDeref(dd,var); - return(NULL); + Cudd_RecursiveDeref(dd,var); + return(NULL); } cuddRef(T); E = zddPortToBddStep(dd,cuddE(f),depth+1); if (E == NULL) { - Cudd_RecursiveDeref(dd,var); - Cudd_RecursiveDeref(dd,T); - return(NULL); + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + return(NULL); } cuddRef(E); res = cuddBddIteRecur(dd,var,T,E); if (res == NULL) { - Cudd_RecursiveDeref(dd,var); - Cudd_RecursiveDeref(dd,T); - Cudd_RecursiveDeref(dd,E); - return(NULL); + Cudd_RecursiveDeref(dd,var); + Cudd_RecursiveDeref(dd,T); + Cudd_RecursiveDeref(dd,E); + return(NULL); } cuddRef(res); Cudd_RecursiveDeref(dd,var); @@ -355,5 +383,7 @@ zddPortToBddStep( } /* end of zddPortToBddStep */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddZddReord.c b/src/bdd/cudd/cuddZddReord.c index 1d73721c..80e3601c 100644 --- a/src/bdd/cudd/cuddZddReord.c +++ b/src/bdd/cudd/cuddZddReord.c @@ -7,51 +7,79 @@ Synopsis [Procedures for dynamic variable ordering of ZDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddReduceHeap() - <li> Cudd_zddShuffleHeap() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddZddAlignToBdd() - <li> cuddZddNextHigh() - <li> cuddZddNextLow() - <li> cuddZddUniqueCompare() - <li> cuddZddSwapInPlace() - <li> cuddZddSwapping() - <li> cuddZddSifting() - </ul> - Static procedures included in this module: - <ul> - <li> zddSwapAny() - <li> cuddZddSiftingAux() - <li> cuddZddSiftingUp() - <li> cuddZddSiftingDown() - <li> cuddZddSiftingBackward() - <li> zddReorderPreprocess() - <li> zddReorderPostprocess() - <li> zddShuffle() - <li> zddSiftUp() - </ul> - ] + <ul> + <li> Cudd_zddReduceHeap() + <li> Cudd_zddShuffleHeap() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddZddAlignToBdd() + <li> cuddZddNextHigh() + <li> cuddZddNextLow() + <li> cuddZddUniqueCompare() + <li> cuddZddSwapInPlace() + <li> cuddZddSwapping() + <li> cuddZddSifting() + </ul> + Static procedures included in this module: + <ul> + <li> zddSwapAny() + <li> cuddZddSiftingAux() + <li> cuddZddSiftingUp() + <li> cuddZddSiftingDown() + <li> cuddZddSiftingBackward() + <li> zddReorderPreprocess() + <li> zddReorderPostprocess() + <li> zddShuffle() + <li> zddSiftUp() + </ul> + ] SeeAlso [] Author [Hyong-Kyoon Shin, In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -74,14 +102,14 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddReord.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddReord.c,v 1.47 2004/08/13 18:04:53 fabio Exp $"; #endif -int *zdd_entry; +int *zdd_entry; -int zddTotalNumberSwapping; +int zddTotalNumberSwapping; -static DdNode *empty; +static DdNode *empty; /*---------------------------------------------------------------------------*/ @@ -95,16 +123,16 @@ static DdNode *empty; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static Move * zddSwapAny ARGS((DdManager *table, int x, int y)); -static int cuddZddSiftingAux ARGS((DdManager *table, int x, int x_low, int x_high)); -static Move * cuddZddSiftingUp ARGS((DdManager *table, int x, int x_low, int initial_size)); -static Move * cuddZddSiftingDown ARGS((DdManager *table, int x, int x_high, int initial_size)); -static int cuddZddSiftingBackward ARGS((DdManager *table, Move *moves, int size)); -static void zddReorderPreprocess ARGS((DdManager *table)); -static int zddReorderPostprocess ARGS((DdManager *table)); -static int zddShuffle ARGS((DdManager *table, int *permutation)); -static int zddSiftUp ARGS((DdManager *table, int x, int xLow)); -static void zddFixTree ARGS((DdManager *table, MtrNode *treenode)); +static Move * zddSwapAny (DdManager *table, int x, int y); +static int cuddZddSiftingAux (DdManager *table, int x, int x_low, int x_high); +static Move * cuddZddSiftingUp (DdManager *table, int x, int x_low, int initial_size); +static Move * cuddZddSiftingDown (DdManager *table, int x, int x_high, int initial_size); +static int cuddZddSiftingBackward (DdManager *table, Move *moves, int size); +static void zddReorderPreprocess (DdManager *table); +static int zddReorderPostprocess (DdManager *table); +static int zddShuffle (DdManager *table, int *permutation); +static int zddSiftUp (DdManager *table, int x, int xLow); +static void zddFixTree (DdManager *table, MtrNode *treenode); /**AutomaticEnd***************************************************************/ @@ -145,24 +173,24 @@ Cudd_zddReduceHeap( Cudd_ReorderingType heuristic /* method used for reordering */, int minsize /* bound below which no reordering occurs */) { - DdHook *hook; - int result; + DdHook *hook; + int result; unsigned int nextDyn; #ifdef DD_STATS unsigned int initialSize; unsigned int finalSize; #endif - long localTime; + long localTime; /* Don't reorder if there are too many dead nodes. */ if (table->keysZ - table->deadZ < (unsigned) minsize) - return(1); + return(1); if (heuristic == CUDD_REORDER_SAME) { - heuristic = table->autoMethodZ; + heuristic = table->autoMethodZ; } if (heuristic == CUDD_REORDER_NONE) { - return(1); + return(1); } /* This call to Cudd_zddReduceHeap does initiate reordering. Therefore @@ -176,9 +204,9 @@ Cudd_zddReduceHeap( /* Run the hook functions. */ hook = table->preReorderingHook; while (hook != NULL) { - int res = (hook->f)(table, "ZDD", (void *)heuristic); - if (res == 0) return(0); - hook = hook->next; + int res = (hook->f)(table, "ZDD", (void *)heuristic); + if (res == 0) return(0); + hook = hook->next; } /* Clear the cache and collect garbage. */ @@ -191,21 +219,21 @@ Cudd_zddReduceHeap( switch(heuristic) { case CUDD_REORDER_RANDOM: case CUDD_REORDER_RANDOM_PIVOT: - (void) fprintf(table->out,"#:I_RANDOM "); - break; + (void) fprintf(table->out,"#:I_RANDOM "); + break; case CUDD_REORDER_SIFT: case CUDD_REORDER_SIFT_CONVERGE: case CUDD_REORDER_SYMM_SIFT: case CUDD_REORDER_SYMM_SIFT_CONV: - (void) fprintf(table->out,"#:I_SIFTING "); - break; + (void) fprintf(table->out,"#:I_SIFTING "); + break; case CUDD_REORDER_LINEAR: case CUDD_REORDER_LINEAR_CONVERGE: - (void) fprintf(table->out,"#:I_LINSIFT "); - break; + (void) fprintf(table->out,"#:I_LINSIFT "); + break; default: - (void) fprintf(table->err,"Unsupported ZDD reordering method\n"); - return(0); + (void) fprintf(table->err,"Unsupported ZDD reordering method\n"); + return(0); } (void) fprintf(table->out,"%8d: initial size",initialSize); #endif @@ -217,36 +245,36 @@ Cudd_zddReduceHeap( finalSize = table->keysZ; (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize); (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n", - ((double)(util_cpu_time() - localTime)/1000.0)); + ((double)(util_cpu_time() - localTime)/1000.0)); (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n", - zddTotalNumberSwapping); + zddTotalNumberSwapping); #endif if (result == 0) - return(0); + return(0); if (!zddReorderPostprocess(table)) - return(0); + return(0); if (table->realignZ) { - if (!cuddBddAlignToZdd(table)) - return(0); + if (!cuddBddAlignToZdd(table)) + return(0); } nextDyn = table->keysZ * DD_DYN_RATIO; if (table->reorderings < 20 || nextDyn > table->nextDyn) - table->nextDyn = nextDyn; + table->nextDyn = nextDyn; else - table->nextDyn += 20; + table->nextDyn += 20; table->reordered = 1; /* Run hook functions. */ hook = table->postReorderingHook; while (hook != NULL) { - int res = (hook->f)(table, "ZDD", (void *)localTime); - if (res == 0) return(0); - hook = hook->next; + int res = (hook->f)(table, "ZDD", (void *)localTime); + if (res == 0) return(0); + hook = hook->next; } /* Update cumulative reordering time. */ table->reordTime += util_cpu_time() - localTime; @@ -278,7 +306,7 @@ Cudd_zddShuffleHeap( int * permutation /* required variable permutation */) { - int result; + int result; empty = table->zero; zddReorderPreprocess(table); @@ -324,14 +352,14 @@ int cuddZddAlignToBdd( DdManager * table /* DD manager */) { - int *invpermZ; /* permutation array */ - int M; /* ratio of ZDD variables to BDD variables */ - int i,j; /* loop indices */ - int result; /* return value */ + int *invpermZ; /* permutation array */ + int M; /* ratio of ZDD variables to BDD variables */ + int i,j; /* loop indices */ + int result; /* return value */ /* We assume that a ratio of 0 is OK. */ if (table->sizeZ == 0) - return(1); + return(1); empty = table->zero; M = table->sizeZ / table->size; @@ -339,26 +367,26 @@ cuddZddAlignToBdd( ** number of BDD variables. */ if (M * table->size != table->sizeZ) - return(0); + return(0); /* Create and initialize the inverse permutation array. */ invpermZ = ABC_ALLOC(int,table->sizeZ); if (invpermZ == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - return(0); + table->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < table->size; i++) { - int index = table->invperm[i]; - int indexZ = index * M; - int levelZ = table->permZ[indexZ]; - levelZ = (levelZ / M) * M; - for (j = 0; j < M; j++) { - invpermZ[M * i + j] = table->invpermZ[levelZ + j]; - } + int index = table->invperm[i]; + int indexZ = index * M; + int levelZ = table->permZ[indexZ]; + levelZ = (levelZ / M) * M; + for (j = 0; j < M; j++) { + invpermZ[M * i + j] = table->invpermZ[levelZ + j]; + } } /* Eliminate dead nodes. Do not scan the cache again, because we ** assume that Cudd_ReduceHeap has already cleared it. */ - cuddGarbageCollectZdd(table,0); + cuddGarbageCollect(table,0); result = zddShuffle(table, invpermZ); ABC_FREE(invpermZ); @@ -458,18 +486,17 @@ cuddZddSwapInPlace( int x, int y) { - DdNodePtr *xlist, *ylist; - int xindex, yindex; - int xslots, yslots; - int xshift, yshift; + DdNodePtr *xlist, *ylist; + int xindex, yindex; + int xslots, yslots; + int xshift, yshift; int oldxkeys, oldykeys; int newxkeys, newykeys; - int i; - int posn; - DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; - DdNode *newf1 = NULL; // Suppress "might be used uninitialized" - DdNode *newf0, *next; - DdNodePtr g, *lastP, *previousP; + int i; + int posn; + DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00; + DdNode *newf1, *newf0, *next; + DdNodePtr g, *lastP, *previousP; #ifdef DD_DEBUG assert(x < y); @@ -506,24 +533,24 @@ cuddZddSwapInPlace( g = NULL; lastP = &g; for (i = 0; i < xslots; i++) { - previousP = &(xlist[i]); - f = *previousP; - while (f != NULL) { - next = f->next; - f1 = cuddT(f); f0 = cuddE(f); - if ((f1->index != (DdHalfWord) yindex) && - (f0->index != (DdHalfWord) yindex)) { /* stays */ - newxkeys++; - *previousP = f; - previousP = &(f->next); - } else { - f->index = yindex; - *lastP = f; - lastP = &(f->next); - } - f = next; - } /* while there are elements in the collision chain */ - *previousP = NULL; + previousP = &(xlist[i]); + f = *previousP; + while (f != NULL) { + next = f->next; + f1 = cuddT(f); f0 = cuddE(f); + if ((f1->index != (DdHalfWord) yindex) && + (f0->index != (DdHalfWord) yindex)) { /* stays */ + newxkeys++; + *previousP = f; + previousP = &(f->next); + } else { + f->index = yindex; + *lastP = f; + lastP = &(f->next); + } + f = next; + } /* while there are elements in the collision chain */ + *previousP = NULL; } /* for each slot of the x subtable */ *lastP = NULL; @@ -537,131 +564,131 @@ cuddZddSwapInPlace( */ f = g; while (f != NULL) { - next = f->next; - /* Find f1, f0, f11, f10, f01, f00. */ - f1 = cuddT(f); - if ((int) f1->index == yindex) { - f11 = cuddT(f1); f10 = cuddE(f1); - } else { - f11 = empty; f10 = f1; - } - f0 = cuddE(f); - if ((int) f0->index == yindex) { - f01 = cuddT(f0); f00 = cuddE(f0); - } else { - f01 = empty; f00 = f0; - } - - /* Decrease ref count of f1. */ - cuddSatDec(f1->ref); - /* Create the new T child. */ - if (f11 == empty) { - if (f01 != empty) { - newf1 = f01; - cuddSatInc(newf1->ref); + next = f->next; + /* Find f1, f0, f11, f10, f01, f00. */ + f1 = cuddT(f); + if ((int) f1->index == yindex) { + f11 = cuddT(f1); f10 = cuddE(f1); + } else { + f11 = empty; f10 = f1; } - /* else case was already handled when finding nodes - ** with both children below level y - */ - } else { - /* Check xlist for triple (xindex, f11, f01). */ - posn = ddHash(f11, f01, xshift); - /* For each element newf1 in collision list xlist[posn]. */ - newf1 = xlist[posn]; - while (newf1 != NULL) { - if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { - cuddSatInc(newf1->ref); - break; /* match */ + f0 = cuddE(f); + if ((int) f0->index == yindex) { + f01 = cuddT(f0); f00 = cuddE(f0); + } else { + f01 = empty; f00 = f0; } - newf1 = newf1->next; - } /* while newf1 */ - if (newf1 == NULL) { /* no match */ - newf1 = cuddDynamicAllocNode(table); - if (newf1 == NULL) - goto zddSwapOutOfMem; - newf1->index = xindex; newf1->ref = 1; - cuddT(newf1) = f11; - cuddE(newf1) = f01; - /* Insert newf1 in the collision list xlist[pos]; - ** increase the ref counts of f11 and f01 - */ - newxkeys++; - newf1->next = xlist[posn]; - xlist[posn] = newf1; - cuddSatInc(f11->ref); - cuddSatInc(f01->ref); + + /* Decrease ref count of f1. */ + cuddSatDec(f1->ref); + /* Create the new T child. */ + if (f11 == empty) { + if (f01 != empty) { + newf1 = f01; + cuddSatInc(newf1->ref); + } + /* else case was already handled when finding nodes + ** with both children below level y + */ + } else { + /* Check xlist for triple (xindex, f11, f01). */ + posn = ddHash(f11, f01, xshift); + /* For each element newf1 in collision list xlist[posn]. */ + newf1 = xlist[posn]; + while (newf1 != NULL) { + if (cuddT(newf1) == f11 && cuddE(newf1) == f01) { + cuddSatInc(newf1->ref); + break; /* match */ + } + newf1 = newf1->next; + } /* while newf1 */ + if (newf1 == NULL) { /* no match */ + newf1 = cuddDynamicAllocNode(table); + if (newf1 == NULL) + goto zddSwapOutOfMem; + newf1->index = xindex; newf1->ref = 1; + cuddT(newf1) = f11; + cuddE(newf1) = f01; + /* Insert newf1 in the collision list xlist[pos]; + ** increase the ref counts of f11 and f01 + */ + newxkeys++; + newf1->next = xlist[posn]; + xlist[posn] = newf1; + cuddSatInc(f11->ref); + cuddSatInc(f01->ref); + } } - } - cuddT(f) = newf1; - - /* Do the same for f0. */ - /* Decrease ref count of f0. */ - cuddSatDec(f0->ref); - /* Create the new E child. */ - if (f10 == empty) { - newf0 = f00; - cuddSatInc(newf0->ref); - } else { - /* Check xlist for triple (xindex, f10, f00). */ - posn = ddHash(f10, f00, xshift); - /* For each element newf0 in collision list xlist[posn]. */ - newf0 = xlist[posn]; - while (newf0 != NULL) { - if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { + cuddT(f) = newf1; + + /* Do the same for f0. */ + /* Decrease ref count of f0. */ + cuddSatDec(f0->ref); + /* Create the new E child. */ + if (f10 == empty) { + newf0 = f00; cuddSatInc(newf0->ref); - break; /* match */ - } - newf0 = newf0->next; - } /* while newf0 */ - if (newf0 == NULL) { /* no match */ - newf0 = cuddDynamicAllocNode(table); - if (newf0 == NULL) - goto zddSwapOutOfMem; - newf0->index = xindex; newf0->ref = 1; - cuddT(newf0) = f10; cuddE(newf0) = f00; - /* Insert newf0 in the collision list xlist[posn]; - ** increase the ref counts of f10 and f00. - */ - newxkeys++; - newf0->next = xlist[posn]; - xlist[posn] = newf0; - cuddSatInc(f10->ref); - cuddSatInc(f00->ref); + } else { + /* Check xlist for triple (xindex, f10, f00). */ + posn = ddHash(f10, f00, xshift); + /* For each element newf0 in collision list xlist[posn]. */ + newf0 = xlist[posn]; + while (newf0 != NULL) { + if (cuddT(newf0) == f10 && cuddE(newf0) == f00) { + cuddSatInc(newf0->ref); + break; /* match */ + } + newf0 = newf0->next; + } /* while newf0 */ + if (newf0 == NULL) { /* no match */ + newf0 = cuddDynamicAllocNode(table); + if (newf0 == NULL) + goto zddSwapOutOfMem; + newf0->index = xindex; newf0->ref = 1; + cuddT(newf0) = f10; cuddE(newf0) = f00; + /* Insert newf0 in the collision list xlist[posn]; + ** increase the ref counts of f10 and f00. + */ + newxkeys++; + newf0->next = xlist[posn]; + xlist[posn] = newf0; + cuddSatInc(f10->ref); + cuddSatInc(f00->ref); + } } - } - cuddE(f) = newf0; + cuddE(f) = newf0; - /* Insert the modified f in ylist. - ** The modified f does not already exists in ylist. - ** (Because of the uniqueness of the cofactors.) - */ - posn = ddHash(newf1, newf0, yshift); - newykeys++; - f->next = ylist[posn]; - ylist[posn] = f; - f = next; + /* Insert the modified f in ylist. + ** The modified f does not already exists in ylist. + ** (Because of the uniqueness of the cofactors.) + */ + posn = ddHash(newf1, newf0, yshift); + newykeys++; + f->next = ylist[posn]; + ylist[posn] = f; + f = next; } /* while f != NULL */ /* GC the y layer. */ /* For each node f in ylist. */ for (i = 0; i < yslots; i++) { - previousP = &(ylist[i]); - f = *previousP; - while (f != NULL) { - next = f->next; - if (f->ref == 0) { - cuddSatDec(cuddT(f)->ref); - cuddSatDec(cuddE(f)->ref); - cuddDeallocNode(table, f); - newykeys--; - } else { - *previousP = f; - previousP = &(f->next); - } - f = next; - } /* while f */ - *previousP = NULL; + previousP = &(ylist[i]); + f = *previousP; + while (f != NULL) { + next = f->next; + if (f->ref == 0) { + cuddSatDec(cuddT(f)->ref); + cuddSatDec(cuddE(f)->ref); + cuddDeallocNode(table, f); + newykeys--; + } else { + *previousP = f; + previousP = &(f->next); + } + f = next; + } /* while f */ + *previousP = NULL; } /* for i */ /* Set the appropriate fields in table. */ @@ -722,14 +749,14 @@ cuddZddSwapping( int upper, Cudd_ReorderingType heuristic) { - int i, j; + int i, j; int max, keys; int nvars; - int x, y; + int x, y; int iterate; int previousSize; Move *moves, *move; - int pivot = -1; // Suppress "might be used uninitialized" + int pivot; int modulo; int result; @@ -742,63 +769,63 @@ cuddZddSwapping( iterate = nvars; for (i = 0; i < iterate; i++) { - if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { - /* Find pivot <= id with maximum keys. */ - for (max = -1, j = lower; j <= upper; j++) { - if ((keys = table->subtableZ[j].keys) > max) { - max = keys; - pivot = j; - } - } - - modulo = upper - pivot; - if (modulo == 0) { - y = pivot; /* y = nvars-1 */ - } else { - /* y = random # from {pivot+1 .. nvars-1} */ - y = pivot + 1 + (int) (Cudd_Random() % modulo); - } - - modulo = pivot - lower - 1; - if (modulo < 1) { /* if pivot = 1 or 0 */ - x = lower; + if (heuristic == CUDD_REORDER_RANDOM_PIVOT) { + /* Find pivot <= id with maximum keys. */ + for (max = -1, j = lower; j <= upper; j++) { + if ((keys = table->subtableZ[j].keys) > max) { + max = keys; + pivot = j; + } + } + + modulo = upper - pivot; + if (modulo == 0) { + y = pivot; /* y = nvars-1 */ + } else { + /* y = random # from {pivot+1 .. nvars-1} */ + y = pivot + 1 + (int) (Cudd_Random() % modulo); + } + + modulo = pivot - lower - 1; + if (modulo < 1) { /* if pivot = 1 or 0 */ + x = lower; + } else { + do { /* x = random # from {0 .. pivot-2} */ + x = (int) Cudd_Random() % modulo; + } while (x == y); + /* Is this condition really needed, since x and y + are in regions separated by pivot? */ + } } else { - do { /* x = random # from {0 .. pivot-2} */ - x = (int) Cudd_Random() % modulo; - } while (x == y); - /* Is this condition really needed, since x and y - are in regions separated by pivot? */ + x = (int) (Cudd_Random() % nvars) + lower; + do { + y = (int) (Cudd_Random() % nvars) + lower; + } while (x == y); } - } else { - x = (int) (Cudd_Random() % nvars) + lower; - do { - y = (int) (Cudd_Random() % nvars) + lower; - } while (x == y); - } - previousSize = table->keysZ; - moves = zddSwapAny(table, x, y); - if (moves == NULL) - goto cuddZddSwappingOutOfMem; + previousSize = table->keysZ; + moves = zddSwapAny(table, x, y); + if (moves == NULL) + goto cuddZddSwappingOutOfMem; - result = cuddZddSiftingBackward(table, moves, previousSize); - if (!result) - goto cuddZddSwappingOutOfMem; + result = cuddZddSiftingBackward(table, moves, previousSize); + if (!result) + goto cuddZddSwappingOutOfMem; - while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; - } + while (moves != NULL) { + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; + } #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); /* should never happen */ - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } @@ -806,9 +833,9 @@ cuddZddSwapping( cuddZddSwappingOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *) moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(0); @@ -842,13 +869,13 @@ cuddZddSifting( int lower, int upper) { - int i; - int *var; - int size; - int x; - int result; + int i; + int *var; + int size; + int x; + int result; #ifdef DD_STATS - int previousSize; + int previousSize; #endif size = table->sizeZ; @@ -857,45 +884,45 @@ cuddZddSifting( var = NULL; zdd_entry = ABC_ALLOC(int, size); if (zdd_entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; } var = ABC_ALLOC(int, size); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSiftingOutOfMem; } for (i = 0; i < size; i++) { - x = table->permZ[i]; - zdd_entry[i] = table->subtableZ[x].keys; - var[i] = i; + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; } - qsort((void *)var, size, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare); + qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); /* Now sift. */ for (i = 0; i < ddMin(table->siftMaxVar, size); i++) { - if (zddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->permZ[var[i]]; - if (x < lower || x > upper) continue; + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif - result = cuddZddSiftingAux(table, x, lower, upper); - if (!result) - goto cuddZddSiftingOutOfMem; + result = cuddZddSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSiftingOutOfMem; #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); /* should never happen */ - (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } @@ -936,14 +963,14 @@ zddSwapAny( int x, int y) { - Move *move, *moves; - int tmp, size; - int x_ref, y_ref; - int x_next, y_next; - int limit_size; - - if (x > y) { /* make x precede y */ - tmp = x; x = y; y = tmp; + Move *move, *moves; + int tmp, size; + int x_ref, y_ref; + int x_next, y_next; + int limit_size; + + if (x > y) { /* make x precede y */ + tmp = x; x = y; y = tmp; } x_ref = x; y_ref = y; @@ -954,118 +981,118 @@ zddSwapAny( limit_size = table->keysZ; for (;;) { - if (x_next == y_next) { /* x < x_next = y_next < y */ - size = cuddZddSwapInPlace(table, x, x_next); - if (size == 0) - goto zddSwapAnyOutOfMem; - move = (Move *) cuddDynamicAllocNode(table); - if (move == NULL) - goto zddSwapAnyOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; - - size = cuddZddSwapInPlace(table, y_next, y); - if (size == 0) - goto zddSwapAnyOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto zddSwapAnyOutOfMem; - move->x = y_next; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - - size = cuddZddSwapInPlace(table, x, x_next); - if (size == 0) - goto zddSwapAnyOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto zddSwapAnyOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; - - tmp = x; x = y; y = tmp; - - } else if (x == y_next) { /* x = y_next < y = x_next */ - size = cuddZddSwapInPlace(table, x, x_next); - if (size == 0) - goto zddSwapAnyOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto zddSwapAnyOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; + if (x_next == y_next) { /* x < x_next = y_next < y */ + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *) cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + + } else if (x == y_next) { /* x = y_next < y = x_next */ + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + tmp = x; x = y; y = tmp; + } else { + size = cuddZddSwapInPlace(table, x, x_next); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = x; + move->y = x_next; + move->size = size; + move->next = moves; + moves = move; + + size = cuddZddSwapInPlace(table, y_next, y); + if (size == 0) + goto zddSwapAnyOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto zddSwapAnyOutOfMem; + move->x = y_next; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + x = x_next; y = y_next; + } - tmp = x; x = y; y = tmp; - } else { - size = cuddZddSwapInPlace(table, x, x_next); - if (size == 0) - goto zddSwapAnyOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto zddSwapAnyOutOfMem; - move->x = x; - move->y = x_next; - move->size = size; - move->next = moves; - moves = move; + x_next = cuddZddNextHigh(table, x); + y_next = cuddZddNextLow(table, y); + if (x_next > y_ref) + break; /* if x == y_ref */ + if ((double) size > table->maxGrowth * (double) limit_size) + break; + if (size < limit_size) + limit_size = size; + } + if (y_next >= x_ref) { size = cuddZddSwapInPlace(table, y_next, y); if (size == 0) - goto zddSwapAnyOutOfMem; + goto zddSwapAnyOutOfMem; move = (Move *)cuddDynamicAllocNode(table); if (move == NULL) - goto zddSwapAnyOutOfMem; + goto zddSwapAnyOutOfMem; move->x = y_next; move->y = y; move->size = size; move->next = moves; moves = move; - - x = x_next; y = y_next; - } - - x_next = cuddZddNextHigh(table, x); - y_next = cuddZddNextLow(table, y); - if (x_next > y_ref) - break; /* if x == y_ref */ - - if ((double) size > table->maxGrowth * (double) limit_size) - break; - if (size < limit_size) - limit_size = size; - } - if (y_next >= x_ref) { - size = cuddZddSwapInPlace(table, y_next, y); - if (size == 0) - goto zddSwapAnyOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto zddSwapAnyOutOfMem; - move->x = y_next; - move->y = y; - move->size = size; - move->next = moves; - moves = move; } return(moves); zddSwapAnyOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(NULL); @@ -1093,12 +1120,12 @@ cuddZddSiftingAux( int x_low, int x_high) { - Move *move; - Move *moveUp; /* list of up move */ - Move *moveDown; /* list of down move */ + Move *move; + Move *moveUp; /* list of up move */ + Move *moveDown; /* list of down move */ - int initial_size; - int result; + int initial_size; + int result; initial_size = table->keysZ; @@ -1110,82 +1137,82 @@ cuddZddSiftingAux( moveUp = NULL; if (x == x_low) { - moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); - /* after that point x --> x_high */ - if (moveDown == NULL) - goto cuddZddSiftingAuxOutOfMem; - result = cuddZddSiftingBackward(table, moveDown, - initial_size); - /* move backward and stop at best position */ - if (!result) - goto cuddZddSiftingAuxOutOfMem; + moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); + /* after that point x --> x_high */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveDown, + initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; } else if (x == x_high) { - moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); - /* after that point x --> x_low */ - if (moveUp == NULL) - goto cuddZddSiftingAuxOutOfMem; - result = cuddZddSiftingBackward(table, moveUp, initial_size); - /* move backward and stop at best position */ - if (!result) - goto cuddZddSiftingAuxOutOfMem; + moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); + /* after that point x --> x_low */ + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveUp, initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; } else if ((x - x_low) > (x_high - x)) { - /* must go down first:shorter */ - moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); - /* after that point x --> x_high */ - if (moveDown == NULL) - goto cuddZddSiftingAuxOutOfMem; - moveUp = cuddZddSiftingUp(table, moveDown->y, x_low, - initial_size); - if (moveUp == NULL) - goto cuddZddSiftingAuxOutOfMem; - result = cuddZddSiftingBackward(table, moveUp, initial_size); - /* move backward and stop at best position */ - if (!result) - goto cuddZddSiftingAuxOutOfMem; + /* must go down first:shorter */ + moveDown = cuddZddSiftingDown(table, x, x_high, initial_size); + /* after that point x --> x_high */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + moveUp = cuddZddSiftingUp(table, moveDown->y, x_low, + initial_size); + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveUp, initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; } else { - moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); - /* after that point x --> x_high */ - if (moveUp == NULL) - goto cuddZddSiftingAuxOutOfMem; - moveDown = cuddZddSiftingDown(table, moveUp->x, x_high, - initial_size); - /* then move up */ - if (moveDown == NULL) - goto cuddZddSiftingAuxOutOfMem; - result = cuddZddSiftingBackward(table, moveDown, - initial_size); - /* move backward and stop at best position */ - if (!result) - goto cuddZddSiftingAuxOutOfMem; + moveUp = cuddZddSiftingUp(table, x, x_low, initial_size); + /* after that point x --> x_high */ + if (moveUp == NULL) + goto cuddZddSiftingAuxOutOfMem; + moveDown = cuddZddSiftingDown(table, moveUp->x, x_high, + initial_size); + /* then move up */ + if (moveDown == NULL) + goto cuddZddSiftingAuxOutOfMem; + result = cuddZddSiftingBackward(table, moveDown, + initial_size); + /* move backward and stop at best position */ + if (!result) + goto cuddZddSiftingAuxOutOfMem; } while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *)moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *)moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(1); cuddZddSiftingAuxOutOfMem: while (moveDown != NULL) { - move = moveDown->next; - cuddDeallocNode(table, (DdNode *)moveDown); - moveDown = move; + move = moveDown->next; + cuddDeallocMove(table, moveDown); + moveDown = move; } while (moveUp != NULL) { - move = moveUp->next; - cuddDeallocNode(table, (DdNode *)moveUp); - moveUp = move; + move = moveUp->next; + cuddDeallocMove(table, moveUp); + moveUp = move; } return(0); @@ -1213,42 +1240,42 @@ cuddZddSiftingUp( int x_low, int initial_size) { - Move *moves; - Move *move; - int y; - int size; - int limit_size = initial_size; + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; moves = NULL; y = cuddZddNextLow(table, x); while (y >= x_low) { - size = cuddZddSwapInPlace(table, y, x); - if (size == 0) - goto cuddZddSiftingUpOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto cuddZddSiftingUpOutOfMem; - move->x = y; - move->y = x; - move->size = size; - move->next = moves; - moves = move; - - if ((double)size > (double)limit_size * table->maxGrowth) - break; + size = cuddZddSwapInPlace(table, y, x); + if (size == 0) + goto cuddZddSiftingUpOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSiftingUpOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + + if ((double)size > (double)limit_size * table->maxGrowth) + break; if (size < limit_size) - limit_size = size; + limit_size = size; - x = y; - y = cuddZddNextLow(table, x); + x = y; + y = cuddZddNextLow(table, x); } return(moves); cuddZddSiftingUpOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(NULL); @@ -1276,42 +1303,42 @@ cuddZddSiftingDown( int x_high, int initial_size) { - Move *moves; - Move *move; - int y; - int size; - int limit_size = initial_size; + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; moves = NULL; y = cuddZddNextHigh(table, x); while (y <= x_high) { - size = cuddZddSwapInPlace(table, x, y); - if (size == 0) - goto cuddZddSiftingDownOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto cuddZddSiftingDownOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - - if ((double)size > (double)limit_size * table->maxGrowth) - break; + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddSiftingDownOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSiftingDownOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + + if ((double)size > (double)limit_size * table->maxGrowth) + break; if (size < limit_size) - limit_size = size; + limit_size = size; - x = y; - y = cuddZddNextHigh(table, x); + x = y; + y = cuddZddNextHigh(table, x); } return(moves); cuddZddSiftingDownOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(NULL); @@ -1339,28 +1366,28 @@ cuddZddSiftingBackward( Move * moves, int size) { - int i; - int i_best; - Move *move; - int res; + int i; + int i_best; + Move *move; + int res; /* Find the minimum size among moves. */ i_best = -1; for (move = moves, i = 0; move != NULL; move = move->next, i++) { - if (move->size < size) { - i_best = i; - size = move->size; - } + if (move->size < size) { + i_best = i; + size = move->size; + } } for (move = moves, i = 0; move != NULL; move = move->next, i++) { - if (i == i_best) - break; - res = cuddZddSwapInPlace(table, move->x, move->y); - if (!res) - return(0); - if (i_best == -1 && res == size) - break; + if (i == i_best) + break; + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) + return(0); + if (i_best == -1 && res == size) + break; } return(1); @@ -1388,7 +1415,7 @@ zddReorderPreprocess( cuddCacheFlush(table); /* Eliminate dead nodes. Do not scan the cache again. */ - cuddGarbageCollectZdd(table,0); + cuddGarbageCollect(table,0); return; @@ -1416,8 +1443,8 @@ zddReorderPostprocess( DdNodePtr *nodelist, *oldnodelist; DdNode *node, *next; unsigned int slots, oldslots; -// extern void (*MMoutOfMemory)(long); - void (*saveHandler)(long); + extern DD_OOMFP MMoutOfMemory; + DD_OOMFP saveHandler; #ifdef DD_VERBOSE (void) fflush(table->out); @@ -1433,51 +1460,51 @@ zddReorderPostprocess( /* Resize subtables. */ for (i = 0; i < table->sizeZ; i++) { - int shift; - oldslots = table->subtableZ[i].slots; - if (oldslots < table->subtableZ[i].keys * DD_MAX_SUBTABLE_SPARSITY || - oldslots <= table->initSlots) continue; - oldnodelist = table->subtableZ[i].nodelist; - slots = oldslots >> 1; - saveHandler = MMoutOfMemory; - MMoutOfMemory = Cudd_OutOfMem; - nodelist = ABC_ALLOC(DdNodePtr, slots); - MMoutOfMemory = saveHandler; - if (nodelist == NULL) { - return(1); - } - table->subtableZ[i].nodelist = nodelist; - table->subtableZ[i].slots = slots; - table->subtableZ[i].shift++; - table->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; + int shift; + oldslots = table->subtableZ[i].slots; + if (oldslots < table->subtableZ[i].keys * DD_MAX_SUBTABLE_SPARSITY || + oldslots <= table->initSlots) continue; + oldnodelist = table->subtableZ[i].nodelist; + slots = oldslots >> 1; + saveHandler = MMoutOfMemory; + MMoutOfMemory = Cudd_OutOfMem; + nodelist = ABC_ALLOC(DdNodePtr, slots); + MMoutOfMemory = saveHandler; + if (nodelist == NULL) { + return(1); + } + table->subtableZ[i].nodelist = nodelist; + table->subtableZ[i].slots = slots; + table->subtableZ[i].shift++; + table->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY; #ifdef DD_VERBOSE - (void) fprintf(table->err, - "shrunk layer %d (%d keys) from %d to %d slots\n", - i, table->subtableZ[i].keys, oldslots, slots); + (void) fprintf(table->err, + "shrunk layer %d (%d keys) from %d to %d slots\n", + i, table->subtableZ[i].keys, oldslots, slots); #endif - for (j = 0; (unsigned) j < slots; j++) { - nodelist[j] = NULL; - } - shift = table->subtableZ[i].shift; - for (j = 0; (unsigned) j < oldslots; j++) { - node = oldnodelist[j]; - while (node != NULL) { - next = node->next; - posn = ddHash(cuddT(node), cuddE(node), shift); - node->next = nodelist[posn]; - nodelist[posn] = node; - node = next; + for (j = 0; (unsigned) j < slots; j++) { + nodelist[j] = NULL; } - } - ABC_FREE(oldnodelist); - - table->memused += (slots - oldslots) * sizeof(DdNode *); - table->slots += slots - oldslots; - table->minDead = (unsigned) (table->gcFrac * (double) table->slots); - table->cacheSlack = (int) ddMin(table->maxCacheHard, - DD_MAX_CACHE_TO_SLOTS_RATIO*table->slots) - - 2 * (int) table->cacheSlots; + shift = table->subtableZ[i].shift; + for (j = 0; (unsigned) j < oldslots; j++) { + node = oldnodelist[j]; + while (node != NULL) { + next = node->next; + posn = ddHash(cuddT(node), cuddE(node), shift); + node->next = nodelist[posn]; + nodelist[posn] = node; + node = next; + } + } + ABC_FREE(oldnodelist); + + table->memused += (slots - oldslots) * sizeof(DdNode *); + table->slots += slots - oldslots; + table->minDead = (unsigned) (table->gcFrac * (double) table->slots); + table->cacheSlack = (int) ddMin(table->maxCacheHard, + DD_MAX_CACHE_TO_SLOTS_RATIO*table->slots) - + 2 * (int) table->cacheSlots; } /* We don't look at the constant subtable, because it is not ** affected by reordering. @@ -1508,16 +1535,16 @@ zddShuffle( DdManager * table, int * permutation) { - int index; - int level; - int position; - int numvars; - int result; + int index; + int level; + int position; + int numvars; + int result; #ifdef DD_STATS - long localTime; - int initialSize; - int finalSize; - int previousSize; + long localTime; + int initialSize; + int finalSize; + int previousSize; #endif zddTotalNumberSwapping = 0; @@ -1525,28 +1552,28 @@ zddShuffle( localTime = util_cpu_time(); initialSize = table->keysZ; (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n", - initialSize); + initialSize); #endif numvars = table->sizeZ; for (level = 0; level < numvars; level++) { - index = permutation[level]; - position = table->permZ[index]; + index = permutation[level]; + position = table->permZ[index]; #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif - result = zddSiftUp(table,position,level); - if (!result) return(0); + result = zddSiftUp(table,position,level); + if (!result) return(0); #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); /* should never happen */ - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); /* should never happen */ + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif } @@ -1555,9 +1582,9 @@ zddShuffle( finalSize = table->keysZ; (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize); (void) fprintf(table->out,"#:T_SHUFFLE %8g: total time (sec)\n", - ((double)(util_cpu_time() - localTime)/1000.0)); + ((double)(util_cpu_time() - localTime)/1000.0)); (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n", - zddTotalNumberSwapping); + zddTotalNumberSwapping); #endif return(1); @@ -1589,12 +1616,12 @@ zddSiftUp( y = cuddZddNextLow(table,x); while (y >= xLow) { - size = cuddZddSwapInPlace(table,y,x); - if (size == 0) { - return(0); - } - x = y; - y = cuddZddNextLow(table,x); + size = cuddZddSwapInPlace(table,y,x); + if (size == 0) { + return(0); + } + x = y; + y = cuddZddNextLow(table,x); } return(1); @@ -1621,19 +1648,21 @@ zddFixTree( { if (treenode == NULL) return; treenode->low = ((int) treenode->index < table->sizeZ) ? - table->permZ[treenode->index] : treenode->index; + table->permZ[treenode->index] : treenode->index; if (treenode->child != NULL) { - zddFixTree(table, treenode->child); + zddFixTree(table, treenode->child); } if (treenode->younger != NULL) - zddFixTree(table, treenode->younger); + zddFixTree(table, treenode->younger); if (treenode->parent != NULL && treenode->low < treenode->parent->low) { - treenode->parent->low = treenode->low; - treenode->parent->index = treenode->index; + treenode->parent->low = treenode->low; + treenode->parent->index = treenode->index; } return; } /* end of zddFixTree */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddZddSetop.c b/src/bdd/cudd/cuddZddSetop.c index 566c610b..b4726b63 100644 --- a/src/bdd/cudd/cuddZddSetop.c +++ b/src/bdd/cudd/cuddZddSetop.c @@ -7,51 +7,79 @@ Synopsis [Set operations on ZDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddIte() - <li> Cudd_zddUnion() - <li> Cudd_zddIntersect() - <li> Cudd_zddDiff() - <li> Cudd_zddDiffConst() - <li> Cudd_zddSubset1() - <li> Cudd_zddSubset0() - <li> Cudd_zddChange() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddZddIte() - <li> cuddZddUnion() - <li> cuddZddIntersect() - <li> cuddZddDiff() - <li> cuddZddChangeAux() - <li> cuddZddSubset1() - <li> cuddZddSubset0() - </ul> - Static procedures included in this module: - <ul> - <li> zdd_subset1_aux() - <li> zdd_subset0_aux() - <li> zddVarToConst() - </ul> - ] + <ul> + <li> Cudd_zddIte() + <li> Cudd_zddUnion() + <li> Cudd_zddIntersect() + <li> Cudd_zddDiff() + <li> Cudd_zddDiffConst() + <li> Cudd_zddSubset1() + <li> Cudd_zddSubset0() + <li> Cudd_zddChange() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddZddIte() + <li> cuddZddUnion() + <li> cuddZddIntersect() + <li> cuddZddDiff() + <li> cuddZddChangeAux() + <li> cuddZddSubset1() + <li> cuddZddSubset0() + </ul> + Static procedures included in this module: + <ul> + <li> zdd_subset1_aux() + <li> zdd_subset0_aux() + <li> zddVarToConst() + </ul> + ] SeeAlso [] Author [Hyong-Kyoon Shin, In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -72,13 +100,16 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddSetop.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddSetop.c,v 1.25 2004/08/13 18:04:54 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /**AutomaticStart*************************************************************/ @@ -86,12 +117,15 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddSetop.c,v 1.1.1.1 2003/02/24 22:23: /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static DdNode * zdd_subset1_aux ARGS((DdManager *zdd, DdNode *P, DdNode *zvar)); -static DdNode * zdd_subset0_aux ARGS((DdManager *zdd, DdNode *P, DdNode *zvar)); -static void zddVarToConst ARGS((DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty)); +static DdNode * zdd_subset1_aux (DdManager *zdd, DdNode *P, DdNode *zvar); +static DdNode * zdd_subset0_aux (DdManager *zdd, DdNode *P, DdNode *zvar); +static void zddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty); /**AutomaticEnd***************************************************************/ +#ifdef __cplusplus +} +#endif /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ @@ -120,8 +154,8 @@ Cudd_zddIte( DdNode *res; do { - dd->reordered = 0; - res = cuddZddIte(dd, f, g, h); + dd->reordered = 0; + res = cuddZddIte(dd, f, g, h); } while (dd->reordered == 1); return(res); @@ -149,8 +183,8 @@ Cudd_zddUnion( DdNode *res; do { - dd->reordered = 0; - res = cuddZddUnion(dd, P, Q); + dd->reordered = 0; + res = cuddZddUnion(dd, P, Q); } while (dd->reordered == 1); return(res); @@ -178,8 +212,8 @@ Cudd_zddIntersect( DdNode *res; do { - dd->reordered = 0; - res = cuddZddIntersect(dd, P, Q); + dd->reordered = 0; + res = cuddZddIntersect(dd, P, Q); } while (dd->reordered == 1); return(res); @@ -207,8 +241,8 @@ Cudd_zddDiff( DdNode *res; do { - dd->reordered = 0; - res = cuddZddDiff(dd, P, Q); + dd->reordered = 0; + res = cuddZddDiff(dd, P, Q); } while (dd->reordered == 1); return(res); @@ -234,41 +268,41 @@ Cudd_zddDiffConst( DdNode * P, DdNode * Q) { - int p_top, q_top; - DdNode *empty = DD_ZERO(zdd), *t, *res; - DdManager *table = zdd; + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *res; + DdManager *table = zdd; statLine(zdd); if (P == empty) - return(empty); + return(empty); if (Q == empty) - return(P); + return(P); if (P == Q) - return(empty); + return(empty); /* Check cache. The cache is shared by cuddZddDiff(). */ res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q); if (res != NULL) - return(res); + return(res); if (cuddIsConstant(P)) - p_top = P->index; + p_top = P->index; else - p_top = zdd->permZ[P->index]; + p_top = zdd->permZ[P->index]; if (cuddIsConstant(Q)) - q_top = Q->index; + q_top = Q->index; else - q_top = zdd->permZ[Q->index]; + q_top = zdd->permZ[Q->index]; if (p_top < q_top) { - res = DD_NON_CONSTANT; + res = DD_NON_CONSTANT; } else if (p_top > q_top) { - res = Cudd_zddDiffConst(zdd, P, cuddE(Q)); + res = Cudd_zddDiffConst(zdd, P, cuddE(Q)); } else { - t = Cudd_zddDiffConst(zdd, cuddT(P), cuddT(Q)); - if (t != empty) - res = DD_NON_CONSTANT; - else - res = Cudd_zddDiffConst(zdd, cuddE(P), cuddE(Q)); + t = Cudd_zddDiffConst(zdd, cuddT(P), cuddT(Q)); + if (t != empty) + res = DD_NON_CONSTANT; + else + res = Cudd_zddDiffConst(zdd, cuddE(P), cuddE(Q)); } cuddCacheInsert2(table, cuddZddDiff, P, Q, res); @@ -298,11 +332,11 @@ Cudd_zddSubset1( DdNode * P, int var) { - DdNode *r; + DdNode *r; do { - dd->reordered = 0; - r = cuddZddSubset1(dd, P, var); + dd->reordered = 0; + r = cuddZddSubset1(dd, P, var); } while (dd->reordered == 1); return(r); @@ -330,11 +364,11 @@ Cudd_zddSubset0( DdNode * P, int var) { - DdNode *r; + DdNode *r; do { - dd->reordered = 0; - r = cuddZddSubset0(dd, P, var); + dd->reordered = 0; + r = cuddZddSubset0(dd, P, var); } while (dd->reordered == 1); return(r); @@ -360,13 +394,13 @@ Cudd_zddChange( DdNode * P, int var) { - DdNode *res; + DdNode *res; if ((unsigned int) var >= CUDD_MAXINDEX - 1) return(NULL); do { - dd->reordered = 0; - res = cuddZddChange(dd, P, var); + dd->reordered = 0; + res = cuddZddChange(dd, P, var); } while (dd->reordered == 1); return(res); @@ -404,8 +438,8 @@ cuddZddIte( statLine(dd); /* Trivial cases. */ /* One variable cases. */ - if (f == (empty = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ - return(h); + if (f == (empty = DD_ZERO(dd))) { /* ITE(0,G,H) = H */ + return(h); } topf = cuddIZ(dd,f->index); topg = cuddIZ(dd,g->index); @@ -414,7 +448,7 @@ cuddZddIte( top = ddMin(topf,v); tautology = (top == CUDD_MAXINDEX) ? DD_ONE(dd) : dd->univ[top]; - if (f == tautology) { /* ITE(1,G,H) = G */ + if (f == tautology) { /* ITE(1,G,H) = G */ return(g); } @@ -422,18 +456,18 @@ cuddZddIte( zddVarToConst(f,&g,&h,tautology,empty); /* Check remaining one variable cases. */ - if (g == h) { /* ITE(F,G,G) = G */ - return(g); + if (g == h) { /* ITE(F,G,G) = G */ + return(g); } - if (g == tautology) { /* ITE(F,1,0) = F */ - if (h == empty) return(f); + if (g == tautology) { /* ITE(F,1,0) = F */ + if (h == empty) return(f); } /* Check cache. */ r = cuddCacheLookupZdd(dd,DD_ZDD_ITE_TAG,f,g,h); if (r != NULL) { - return(r); + return(r); } /* Recompute these because they may have changed in zddVarToConst. */ @@ -442,59 +476,59 @@ cuddZddIte( v = ddMin(topg,toph); if (topf < v) { - r = cuddZddIte(dd,cuddE(f),g,h); - if (r == NULL) return(NULL); + r = cuddZddIte(dd,cuddE(f),g,h); + if (r == NULL) return(NULL); } else if (topf > v) { - if (topg > v) { - Gvn = g; - index = h->index; - } else { - Gvn = cuddE(g); - index = g->index; - } - if (toph > v) { - Hv = empty; Hvn = h; - } else { - Hv = cuddT(h); Hvn = cuddE(h); - } - e = cuddZddIte(dd,f,Gvn,Hvn); - if (e == NULL) return(NULL); - cuddRef(e); - r = cuddZddGetNode(dd,index,Hv,e); - if (r == NULL) { - Cudd_RecursiveDerefZdd(dd,e); - return(NULL); - } - cuddDeref(e); - } else { - index = f->index; - if (topg > v) { - Gv = empty; Gvn = g; + if (topg > v) { + Gvn = g; + index = h->index; + } else { + Gvn = cuddE(g); + index = g->index; + } + if (toph > v) { + Hv = empty; Hvn = h; + } else { + Hv = cuddT(h); Hvn = cuddE(h); + } + e = cuddZddIte(dd,f,Gvn,Hvn); + if (e == NULL) return(NULL); + cuddRef(e); + r = cuddZddGetNode(dd,index,Hv,e); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + return(NULL); + } + cuddDeref(e); } else { - Gv = cuddT(g); Gvn = cuddE(g); - } - if (toph > v) { - Hv = empty; Hvn = h; - } else { - Hv = cuddT(h); Hvn = cuddE(h); - } - e = cuddZddIte(dd,cuddE(f),Gvn,Hvn); - if (e == NULL) return(NULL); - cuddRef(e); - t = cuddZddIte(dd,cuddT(f),Gv,Hv); - if (t == NULL) { - Cudd_RecursiveDerefZdd(dd,e); - return(NULL); - } - cuddRef(t); - r = cuddZddGetNode(dd,index,t,e); - if (r == NULL) { - Cudd_RecursiveDerefZdd(dd,e); - Cudd_RecursiveDerefZdd(dd,t); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + index = f->index; + if (topg > v) { + Gv = empty; Gvn = g; + } else { + Gv = cuddT(g); Gvn = cuddE(g); + } + if (toph > v) { + Hv = empty; Hvn = h; + } else { + Hv = cuddT(h); Hvn = cuddE(h); + } + e = cuddZddIte(dd,cuddE(f),Gvn,Hvn); + if (e == NULL) return(NULL); + cuddRef(e); + t = cuddZddIte(dd,cuddT(f),Gv,Hv); + if (t == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + return(NULL); + } + cuddRef(t); + r = cuddZddGetNode(dd,index,t,e); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd,e); + Cudd_RecursiveDerefZdd(dd,t); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert(dd,DD_ZDD_ITE_TAG,f,g,h,r); @@ -521,69 +555,69 @@ cuddZddUnion( DdNode * P, DdNode * Q) { - int p_top, q_top; - DdNode *empty = DD_ZERO(zdd), *t, *e, *res; - DdManager *table = zdd; + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; statLine(zdd); if (P == empty) - return(Q); + return(Q); if (Q == empty) - return(P); + return(P); if (P == Q) - return(P); + return(P); /* Check cache */ res = cuddCacheLookup2Zdd(table, cuddZddUnion, P, Q); if (res != NULL) - return(res); + return(res); if (cuddIsConstant(P)) - p_top = P->index; + p_top = P->index; else - p_top = zdd->permZ[P->index]; + p_top = zdd->permZ[P->index]; if (cuddIsConstant(Q)) - q_top = Q->index; + q_top = Q->index; else - q_top = zdd->permZ[Q->index]; + q_top = zdd->permZ[Q->index]; if (p_top < q_top) { - e = cuddZddUnion(zdd, cuddE(P), Q); - if (e == NULL) return (NULL); - cuddRef(e); - res = cuddZddGetNode(zdd, P->index, cuddT(P), e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(table, e); - return(NULL); - } - cuddDeref(e); + e = cuddZddUnion(zdd, cuddE(P), Q); + if (e == NULL) return (NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, cuddT(P), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); } else if (p_top > q_top) { - e = cuddZddUnion(zdd, P, cuddE(Q)); - if (e == NULL) return(NULL); - cuddRef(e); - res = cuddZddGetNode(zdd, Q->index, cuddT(Q), e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(table, e); - return(NULL); - } - cuddDeref(e); + e = cuddZddUnion(zdd, P, cuddE(Q)); + if (e == NULL) return(NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, Q->index, cuddT(Q), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); } else { - t = cuddZddUnion(zdd, cuddT(P), cuddT(Q)); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddZddUnion(zdd, cuddE(P), cuddE(Q)); - if (e == NULL) { - Cudd_RecursiveDerefZdd(table, t); - return(NULL); - } - cuddRef(e); - res = cuddZddGetNode(zdd, P->index, t, e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(table, t); - Cudd_RecursiveDerefZdd(table, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + t = cuddZddUnion(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddUnion(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(table, cuddZddUnion, P, Q, res); @@ -610,55 +644,55 @@ cuddZddIntersect( DdNode * P, DdNode * Q) { - int p_top, q_top; - DdNode *empty = DD_ZERO(zdd), *t, *e, *res; - DdManager *table = zdd; + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; statLine(zdd); if (P == empty) - return(empty); + return(empty); if (Q == empty) - return(empty); + return(empty); if (P == Q) - return(P); + return(P); /* Check cache. */ res = cuddCacheLookup2Zdd(table, cuddZddIntersect, P, Q); if (res != NULL) - return(res); + return(res); if (cuddIsConstant(P)) - p_top = P->index; + p_top = P->index; else - p_top = zdd->permZ[P->index]; + p_top = zdd->permZ[P->index]; if (cuddIsConstant(Q)) - q_top = Q->index; + q_top = Q->index; else - q_top = zdd->permZ[Q->index]; + q_top = zdd->permZ[Q->index]; if (p_top < q_top) { - res = cuddZddIntersect(zdd, cuddE(P), Q); - if (res == NULL) return(NULL); + res = cuddZddIntersect(zdd, cuddE(P), Q); + if (res == NULL) return(NULL); } else if (p_top > q_top) { - res = cuddZddIntersect(zdd, P, cuddE(Q)); - if (res == NULL) return(NULL); + res = cuddZddIntersect(zdd, P, cuddE(Q)); + if (res == NULL) return(NULL); } else { - t = cuddZddIntersect(zdd, cuddT(P), cuddT(Q)); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddZddIntersect(zdd, cuddE(P), cuddE(Q)); - if (e == NULL) { - Cudd_RecursiveDerefZdd(table, t); - return(NULL); - } - cuddRef(e); - res = cuddZddGetNode(zdd, P->index, t, e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(table, t); - Cudd_RecursiveDerefZdd(table, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + t = cuddZddIntersect(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddIntersect(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(table, cuddZddIntersect, P, Q, res); @@ -685,62 +719,62 @@ cuddZddDiff( DdNode * P, DdNode * Q) { - int p_top, q_top; - DdNode *empty = DD_ZERO(zdd), *t, *e, *res; - DdManager *table = zdd; + int p_top, q_top; + DdNode *empty = DD_ZERO(zdd), *t, *e, *res; + DdManager *table = zdd; statLine(zdd); if (P == empty) - return(empty); + return(empty); if (Q == empty) - return(P); + return(P); if (P == Q) - return(empty); + return(empty); /* Check cache. The cache is shared by Cudd_zddDiffConst(). */ res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q); if (res != NULL && res != DD_NON_CONSTANT) - return(res); + return(res); if (cuddIsConstant(P)) - p_top = P->index; + p_top = P->index; else - p_top = zdd->permZ[P->index]; + p_top = zdd->permZ[P->index]; if (cuddIsConstant(Q)) - q_top = Q->index; + q_top = Q->index; else - q_top = zdd->permZ[Q->index]; + q_top = zdd->permZ[Q->index]; if (p_top < q_top) { - e = cuddZddDiff(zdd, cuddE(P), Q); - if (e == NULL) return(NULL); - cuddRef(e); - res = cuddZddGetNode(zdd, P->index, cuddT(P), e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(table, e); - return(NULL); - } - cuddDeref(e); + e = cuddZddDiff(zdd, cuddE(P), Q); + if (e == NULL) return(NULL); + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, cuddT(P), e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(e); } else if (p_top > q_top) { - res = cuddZddDiff(zdd, P, cuddE(Q)); - if (res == NULL) return(NULL); + res = cuddZddDiff(zdd, P, cuddE(Q)); + if (res == NULL) return(NULL); } else { - t = cuddZddDiff(zdd, cuddT(P), cuddT(Q)); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddZddDiff(zdd, cuddE(P), cuddE(Q)); - if (e == NULL) { - Cudd_RecursiveDerefZdd(table, t); - return(NULL); - } - cuddRef(e); - res = cuddZddGetNode(zdd, P->index, t, e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(table, t); - Cudd_RecursiveDerefZdd(table, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + t = cuddZddDiff(zdd, cuddT(P), cuddT(Q)); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddDiff(zdd, cuddE(P), cuddE(Q)); + if (e == NULL) { + Cudd_RecursiveDerefZdd(table, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(table, t); + Cudd_RecursiveDerefZdd(table, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(table, cuddZddDiff, P, Q, res); @@ -767,49 +801,49 @@ cuddZddChangeAux( DdNode * P, DdNode * zvar) { - int top_var, level; - DdNode *res, *t, *e; - DdNode *base = DD_ONE(zdd); - DdNode *empty = DD_ZERO(zdd); + int top_var, level; + DdNode *res, *t, *e; + DdNode *base = DD_ONE(zdd); + DdNode *empty = DD_ZERO(zdd); statLine(zdd); if (P == empty) - return(empty); + return(empty); if (P == base) - return(zvar); + return(zvar); /* Check cache. */ res = cuddCacheLookup2Zdd(zdd, cuddZddChangeAux, P, zvar); if (res != NULL) - return(res); + return(res); top_var = zdd->permZ[P->index]; level = zdd->permZ[zvar->index]; if (top_var > level) { - res = cuddZddGetNode(zdd, zvar->index, P, DD_ZERO(zdd)); - if (res == NULL) return(NULL); + res = cuddZddGetNode(zdd, zvar->index, P, DD_ZERO(zdd)); + if (res == NULL) return(NULL); } else if (top_var == level) { - res = cuddZddGetNode(zdd, zvar->index, cuddE(P), cuddT(P)); - if (res == NULL) return(NULL); + res = cuddZddGetNode(zdd, zvar->index, cuddE(P), cuddT(P)); + if (res == NULL) return(NULL); } else { - t = cuddZddChangeAux(zdd, cuddT(P), zvar); - if (t == NULL) return(NULL); - cuddRef(t); - e = cuddZddChangeAux(zdd, cuddE(P), zvar); - if (e == NULL) { - Cudd_RecursiveDerefZdd(zdd, t); - return(NULL); - } - cuddRef(e); - res = cuddZddGetNode(zdd, P->index, t, e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(zdd, t); - Cudd_RecursiveDerefZdd(zdd, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + t = cuddZddChangeAux(zdd, cuddT(P), zvar); + if (t == NULL) return(NULL); + cuddRef(t); + e = cuddZddChangeAux(zdd, cuddE(P), zvar); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); + res = cuddZddGetNode(zdd, P->index, t, e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(zdd, cuddZddChangeAux, P, zvar, res); @@ -842,24 +876,24 @@ cuddZddSubset1( DdNode * P, int var) { - DdNode *zvar, *r; - DdNode *base, *empty; + DdNode *zvar, *r; + DdNode *base, *empty; base = DD_ONE(dd); empty = DD_ZERO(dd); zvar = cuddUniqueInterZdd(dd, var, base, empty); if (zvar == NULL) { - return(NULL); + return(NULL); } else { - cuddRef(zvar); - r = zdd_subset1_aux(dd, P, zvar); - if (r == NULL) { + cuddRef(zvar); + r = zdd_subset1_aux(dd, P, zvar); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zvar); + return(NULL); + } + cuddRef(r); Cudd_RecursiveDerefZdd(dd, zvar); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDerefZdd(dd, zvar); } cuddDeref(r); @@ -891,24 +925,24 @@ cuddZddSubset0( DdNode * P, int var) { - DdNode *zvar, *r; - DdNode *base, *empty; + DdNode *zvar, *r; + DdNode *base, *empty; base = DD_ONE(dd); empty = DD_ZERO(dd); zvar = cuddUniqueInterZdd(dd, var, base, empty); if (zvar == NULL) { - return(NULL); + return(NULL); } else { - cuddRef(zvar); - r = zdd_subset0_aux(dd, P, zvar); - if (r == NULL) { + cuddRef(zvar); + r = zdd_subset0_aux(dd, P, zvar); + if (r == NULL) { + Cudd_RecursiveDerefZdd(dd, zvar); + return(NULL); + } + cuddRef(r); Cudd_RecursiveDerefZdd(dd, zvar); - return(NULL); - } - cuddRef(r); - Cudd_RecursiveDerefZdd(dd, zvar); } cuddDeref(r); @@ -939,7 +973,7 @@ cuddZddChange( DdNode * P, int var) { - DdNode *zvar, *res; + DdNode *zvar, *res; zvar = cuddUniqueInterZdd(dd, var, DD_ONE(dd), DD_ZERO(dd)); if (zvar == NULL) return(NULL); @@ -947,8 +981,8 @@ cuddZddChange( res = cuddZddChangeAux(dd, P, zvar); if (res == NULL) { - Cudd_RecursiveDerefZdd(dd,zvar); - return(NULL); + Cudd_RecursiveDerefZdd(dd,zvar); + return(NULL); } cuddRef(res); Cudd_RecursiveDerefZdd(dd,zvar); @@ -980,23 +1014,22 @@ zdd_subset1_aux( DdNode * P, DdNode * zvar) { - int top_var, level; - DdNode *res, *t, *e; - DdNode *base, *empty; + int top_var, level; + DdNode *res, *t, *e; + DdNode *empty; statLine(zdd); - base = DD_ONE(zdd); empty = DD_ZERO(zdd); /* Check cache. */ res = cuddCacheLookup2Zdd(zdd, zdd_subset1_aux, P, zvar); if (res != NULL) - return(res); + return(res); if (cuddIsConstant(P)) { - res = empty; - cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res); - return(res); + res = empty; + cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res); + return(res); } top_var = zdd->permZ[P->index]; @@ -1005,25 +1038,25 @@ zdd_subset1_aux( if (top_var > level) { res = empty; } else if (top_var == level) { - res = cuddT(P); + res = cuddT(P); } else { t = zdd_subset1_aux(zdd, cuddT(P), zvar); - if (t == NULL) return(NULL); - cuddRef(t); + if (t == NULL) return(NULL); + cuddRef(t); e = zdd_subset1_aux(zdd, cuddE(P), zvar); - if (e == NULL) { - Cudd_RecursiveDerefZdd(zdd, t); - return(NULL); - } - cuddRef(e); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); res = cuddZddGetNode(zdd, P->index, t, e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(zdd, t); - Cudd_RecursiveDerefZdd(zdd, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res); @@ -1050,23 +1083,20 @@ zdd_subset0_aux( DdNode * P, DdNode * zvar) { - int top_var, level; - DdNode *res, *t, *e; - DdNode *base, *empty; + int top_var, level; + DdNode *res, *t, *e; statLine(zdd); - base = DD_ONE(zdd); - empty = DD_ZERO(zdd); /* Check cache. */ res = cuddCacheLookup2Zdd(zdd, zdd_subset0_aux, P, zvar); if (res != NULL) - return(res); + return(res); if (cuddIsConstant(P)) { - res = P; - cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res); - return(res); + res = P; + cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res); + return(res); } top_var = zdd->permZ[P->index]; @@ -1080,22 +1110,22 @@ zdd_subset0_aux( } else { t = zdd_subset0_aux(zdd, cuddT(P), zvar); - if (t == NULL) return(NULL); - cuddRef(t); + if (t == NULL) return(NULL); + cuddRef(t); e = zdd_subset0_aux(zdd, cuddE(P), zvar); - if (e == NULL) { - Cudd_RecursiveDerefZdd(zdd, t); - return(NULL); - } - cuddRef(e); + if (e == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + return(NULL); + } + cuddRef(e); res = cuddZddGetNode(zdd, P->index, t, e); - if (res == NULL) { - Cudd_RecursiveDerefZdd(zdd, t); - Cudd_RecursiveDerefZdd(zdd, e); - return(NULL); - } - cuddDeref(t); - cuddDeref(e); + if (res == NULL) { + Cudd_RecursiveDerefZdd(zdd, t); + Cudd_RecursiveDerefZdd(zdd, e); + return(NULL); + } + cuddDeref(t); + cuddDeref(e); } cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res); @@ -1129,14 +1159,16 @@ zddVarToConst( DdNode *h = *hp; if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */ - *gp = base; + *gp = base; } if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */ - *hp = empty; + *hp = empty; } } /* end of zddVarToConst */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddZddSymm.c b/src/bdd/cudd/cuddZddSymm.c index 644673cd..52e26d88 100644 --- a/src/bdd/cudd/cuddZddSymm.c +++ b/src/bdd/cudd/cuddZddSymm.c @@ -7,45 +7,73 @@ Synopsis [Functions for symmetry-based ZDD variable reordering.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddSymmProfile() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddZddSymmCheck() - <li> cuddZddSymmSifting() - <li> cuddZddSymmSiftingConv() - </ul> - Static procedures included in this module: - <ul> - <li> cuddZddUniqueCompare() - <li> cuddZddSymmSiftingAux() - <li> cuddZddSymmSiftingConvAux() - <li> cuddZddSymmSifting_up() - <li> cuddZddSymmSifting_down() - <li> zdd_group_move() - <li> cuddZddSymmSiftingBackward() - <li> zdd_group_move_backward() - </ul> - ] + <ul> + <li> Cudd_zddSymmProfile() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddZddSymmCheck() + <li> cuddZddSymmSifting() + <li> cuddZddSymmSiftingConv() + </ul> + Static procedures included in this module: + <ul> + <li> cuddZddUniqueCompare() + <li> cuddZddSymmSiftingAux() + <li> cuddZddSymmSiftingConvAux() + <li> cuddZddSymmSifting_up() + <li> cuddZddSymmSifting_down() + <li> zdd_group_move() + <li> cuddZddSymmSiftingBackward() + <li> zdd_group_move_backward() + </ul> + ] SeeAlso [cuddSymmetry.c] Author [Hyong-Kyoon Shin, In-Ho Moon] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -65,14 +93,14 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddSymm.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddSymm.c,v 1.29 2004/08/13 18:04:54 fabio Exp $"; #endif -extern int *zdd_entry; +extern int *zdd_entry; -extern int zddTotalNumberSwapping; +extern int zddTotalNumberSwapping; -static DdNode *empty; +static DdNode *empty; /*---------------------------------------------------------------------------*/ /* Macro declarations */ @@ -85,14 +113,14 @@ static DdNode *empty; /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int cuddZddSymmSiftingAux ARGS((DdManager *table, int x, int x_low, int x_high)); -static int cuddZddSymmSiftingConvAux ARGS((DdManager *table, int x, int x_low, int x_high)); -static Move * cuddZddSymmSifting_up ARGS((DdManager *table, int x, int x_low, int initial_size)); -static Move * cuddZddSymmSifting_down ARGS((DdManager *table, int x, int x_high, int initial_size)); -static int cuddZddSymmSiftingBackward ARGS((DdManager *table, Move *moves, int size)); -static int zdd_group_move ARGS((DdManager *table, int x, int y, Move **moves)); -static int zdd_group_move_backward ARGS((DdManager *table, int x, int y)); -static void cuddZddSymmSummary ARGS((DdManager *table, int lower, int upper, int *symvars, int *symgroups)); +static int cuddZddSymmSiftingAux (DdManager *table, int x, int x_low, int x_high); +static int cuddZddSymmSiftingConvAux (DdManager *table, int x, int x_low, int x_high); +static Move * cuddZddSymmSifting_up (DdManager *table, int x, int x_low, int initial_size); +static Move * cuddZddSymmSifting_down (DdManager *table, int x, int x_high, int initial_size); +static int cuddZddSymmSiftingBackward (DdManager *table, Move *moves, int size); +static int zdd_group_move (DdManager *table, int x, int y, Move **moves); +static int zdd_group_move_backward (DdManager *table, int x, int y); +static void cuddZddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups); /**AutomaticEnd***************************************************************/ @@ -119,30 +147,27 @@ Cudd_zddSymmProfile( int lower, int upper) { - int i, x, gbot; - int TotalSymm = 0; - int TotalSymmGroups = 0; - int nvars; - - nvars = table->sizeZ; + int i, x, gbot; + int TotalSymm = 0; + int TotalSymmGroups = 0; for (i = lower; i < upper; i++) { - if (table->subtableZ[i].next != (unsigned) i) { - x = i; - (void) fprintf(table->out,"Group:"); - do { - (void) fprintf(table->out," %d", table->invpermZ[x]); - TotalSymm++; - gbot = x; - x = table->subtableZ[x].next; - } while (x != i); - TotalSymmGroups++; + if (table->subtableZ[i].next != (unsigned) i) { + x = i; + (void) fprintf(table->out,"Group:"); + do { + (void) fprintf(table->out," %d", table->invpermZ[x]); + TotalSymm++; + gbot = x; + x = table->subtableZ[x].next; + } while (x != i); + TotalSymmGroups++; #ifdef DD_DEBUG - assert(table->subtableZ[gbot].next == (unsigned) i); + assert(table->subtableZ[gbot].next == (unsigned) i); #endif - i = gbot; - (void) fprintf(table->out,"\n"); - } + i = gbot; + (void) fprintf(table->out,"\n"); + } } (void) fprintf(table->out,"Total Symmetric = %d\n", TotalSymm); (void) fprintf(table->out,"Total Groups = %d\n", TotalSymmGroups); @@ -174,75 +199,75 @@ cuddZddSymmCheck( int x, int y) { - int i; - DdNode *f, *f0, *f1, *f01, *f00, *f11, *f10; - int yindex; - int xsymmy = 1; - int xsymmyp = 1; - int arccount = 0; - int TotalRefCount = 0; - int symm_found; + int i; + DdNode *f, *f0, *f1, *f01, *f00, *f11, *f10; + int yindex; + int xsymmy = 1; + int xsymmyp = 1; + int arccount = 0; + int TotalRefCount = 0; + int symm_found; empty = table->zero; yindex = table->invpermZ[y]; for (i = table->subtableZ[x].slots - 1; i >= 0; i--) { - f = table->subtableZ[x].nodelist[i]; - while (f != NULL) { - /* Find f1, f0, f11, f10, f01, f00 */ - f1 = cuddT(f); - f0 = cuddE(f); - if ((int) f1->index == yindex) { - f11 = cuddT(f1); - f10 = cuddE(f1); - if (f10 != empty) - arccount++; - } else { - if ((int) f0->index != yindex) { - return(0); /* f bypasses layer y */ - } - f11 = empty; - f10 = f1; - } - if ((int) f0->index == yindex) { - f01 = cuddT(f0); - f00 = cuddE(f0); - if (f00 != empty) - arccount++; - } else { - f01 = empty; - f00 = f0; - } - if (f01 != f10) - xsymmy = 0; - if (f11 != f00) - xsymmyp = 0; - if ((xsymmy == 0) && (xsymmyp == 0)) - return(0); - - f = f->next; - } /* for each element of the collision list */ + f = table->subtableZ[x].nodelist[i]; + while (f != NULL) { + /* Find f1, f0, f11, f10, f01, f00 */ + f1 = cuddT(f); + f0 = cuddE(f); + if ((int) f1->index == yindex) { + f11 = cuddT(f1); + f10 = cuddE(f1); + if (f10 != empty) + arccount++; + } else { + if ((int) f0->index != yindex) { + return(0); /* f bypasses layer y */ + } + f11 = empty; + f10 = f1; + } + if ((int) f0->index == yindex) { + f01 = cuddT(f0); + f00 = cuddE(f0); + if (f00 != empty) + arccount++; + } else { + f01 = empty; + f00 = f0; + } + if (f01 != f10) + xsymmy = 0; + if (f11 != f00) + xsymmyp = 0; + if ((xsymmy == 0) && (xsymmyp == 0)) + return(0); + + f = f->next; + } /* for each element of the collision list */ } /* for each slot of the subtable */ /* Calculate the total reference counts of y ** whose else arc is not empty. */ for (i = table->subtableZ[y].slots - 1; i >= 0; i--) { - f = table->subtableZ[y].nodelist[i]; - while (f != NIL(DdNode)) { - if (cuddE(f) != empty) - TotalRefCount += f->ref; - f = f->next; - } + f = table->subtableZ[y].nodelist[i]; + while (f != NIL(DdNode)) { + if (cuddE(f) != empty) + TotalRefCount += f->ref; + f = f->next; + } } symm_found = (arccount == TotalRefCount); #if defined(DD_DEBUG) && defined(DD_VERBOSE) if (symm_found) { - int xindex = table->invpermZ[x]; - (void) fprintf(table->out, - "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", - xindex,yindex,x,y); + int xindex = table->invpermZ[x]; + (void) fprintf(table->out, + "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n", + xindex,yindex,x,y); } #endif @@ -279,16 +304,16 @@ cuddZddSymmSifting( int lower, int upper) { - int i; - int *var; - int nvars; - int x; - int result; - int symvars; - int symgroups; - int iteration; + int i; + int *var; + int nvars; + int x; + int result; + int symvars; + int symgroups; + int iteration; #ifdef DD_STATS - int previousSize; + int previousSize; #endif nvars = table->sizeZ; @@ -297,54 +322,54 @@ cuddZddSymmSifting( var = NULL; zdd_entry = ABC_ALLOC(int, nvars); if (zdd_entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSymmSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingOutOfMem; } var = ABC_ALLOC(int, nvars); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSymmSiftingOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingOutOfMem; } for (i = 0; i < nvars; i++) { - x = table->permZ[i]; - zdd_entry[i] = table->subtableZ[x].keys; - var[i] = i; + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; } - qsort((void *)var, nvars, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare); + qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); /* Initialize the symmetry of each subtable to itself. */ for (i = lower; i <= upper; i++) - table->subtableZ[i].next = i; + table->subtableZ[i].next = i; iteration = ddMin(table->siftMaxVar, nvars); for (i = 0; i < iteration; i++) { - if (zddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->permZ[var[i]]; + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->permZ[var[i]]; #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif - if (x < lower || x > upper) continue; - if (table->subtableZ[x].next == (unsigned) x) { - result = cuddZddSymmSiftingAux(table, x, lower, upper); - if (!result) - goto cuddZddSymmSiftingOutOfMem; + if (x < lower || x > upper) continue; + if (table->subtableZ[x].next == (unsigned) x) { + result = cuddZddSymmSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingOutOfMem; #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); #ifdef DD_VERBOSE - (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); #endif - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } + } } ABC_FREE(var); @@ -362,9 +387,9 @@ cuddZddSymmSifting( cuddZddSymmSiftingOutOfMem: if (zdd_entry != NULL) - ABC_FREE(zdd_entry); + ABC_FREE(zdd_entry); if (var != NULL) - ABC_FREE(var); + ABC_FREE(var); return(0); @@ -400,16 +425,16 @@ cuddZddSymmSiftingConv( int lower, int upper) { - int i; - int *var; - int nvars; - int initialSize; - int x; - int result; - int symvars; - int symgroups; - int classes; - int iteration; + int i; + int *var; + int nvars; + int initialSize; + int x; + int result; + int symvars; + int symgroups; + int classes; + int iteration; #ifdef DD_STATS int previousSize; #endif @@ -422,117 +447,117 @@ cuddZddSymmSiftingConv( var = NULL; zdd_entry = ABC_ALLOC(int, nvars); if (zdd_entry == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSymmSiftingConvOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingConvOutOfMem; } var = ABC_ALLOC(int, nvars); if (var == NULL) { - table->errorCode = CUDD_MEMORY_OUT; - goto cuddZddSymmSiftingConvOutOfMem; + table->errorCode = CUDD_MEMORY_OUT; + goto cuddZddSymmSiftingConvOutOfMem; } for (i = 0; i < nvars; i++) { - x = table->permZ[i]; - zdd_entry[i] = table->subtableZ[x].keys; - var[i] = i; + x = table->permZ[i]; + zdd_entry[i] = table->subtableZ[x].keys; + var[i] = i; } - qsort((void *)var, nvars, sizeof(int), (int (*)(const void *, const void *))cuddZddUniqueCompare); + qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare); /* Initialize the symmetry of each subtable to itself ** for first pass of converging symmetric sifting. */ for (i = lower; i <= upper; i++) - table->subtableZ[i].next = i; + table->subtableZ[i].next = i; iteration = ddMin(table->siftMaxVar, table->sizeZ); for (i = 0; i < iteration; i++) { - if (zddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->permZ[var[i]]; - if (x < lower || x > upper) continue; - /* Only sift if not in symmetry group already. */ - if (table->subtableZ[x].next == (unsigned) x) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->permZ[var[i]]; + if (x < lower || x > upper) continue; + /* Only sift if not in symmetry group already. */ + if (table->subtableZ[x].next == (unsigned) x) { #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif - result = cuddZddSymmSiftingAux(table, x, lower, upper); - if (!result) - goto cuddZddSymmSiftingConvOutOfMem; + result = cuddZddSymmSiftingAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingConvOutOfMem; #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); #ifdef DD_VERBOSE - (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); #endif - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } + } } /* Sifting now until convergence. */ while ((unsigned) initialSize > table->keysZ) { - initialSize = table->keysZ; + initialSize = table->keysZ; #ifdef DD_STATS - (void) fprintf(table->out,"\n"); + (void) fprintf(table->out,"\n"); #endif - /* Here we consider only one representative for each symmetry class. */ - for (x = lower, classes = 0; x <= upper; x++, classes++) { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - /* Here x is the largest index in a group. - ** Groups consists of adjacent variables. - ** Hence, the next increment of x will move it to a new group. - */ - i = table->invpermZ[x]; - zdd_entry[i] = table->subtableZ[x].keys; - var[classes] = i; - } + /* Here we consider only one representative for each symmetry class. */ + for (x = lower, classes = 0; x <= upper; x++, classes++) { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + /* Here x is the largest index in a group. + ** Groups consists of adjacent variables. + ** Hence, the next increment of x will move it to a new group. + */ + i = table->invpermZ[x]; + zdd_entry[i] = table->subtableZ[x].keys; + var[classes] = i; + } - qsort((void *)var,classes,sizeof(int),(int (*)(const void *, const void *))cuddZddUniqueCompare); + qsort((void *)var,classes,sizeof(int),(DD_QSFP)cuddZddUniqueCompare); - /* Now sift. */ - iteration = ddMin(table->siftMaxVar, nvars); - for (i = 0; i < iteration; i++) { - if (zddTotalNumberSwapping >= table->siftMaxSwap) - break; - x = table->permZ[var[i]]; - if ((unsigned) x >= table->subtableZ[x].next) { + /* Now sift. */ + iteration = ddMin(table->siftMaxVar, nvars); + for (i = 0; i < iteration; i++) { + if (zddTotalNumberSwapping >= table->siftMaxSwap) + break; + x = table->permZ[var[i]]; + if ((unsigned) x >= table->subtableZ[x].next) { #ifdef DD_STATS - previousSize = table->keysZ; + previousSize = table->keysZ; #endif - result = cuddZddSymmSiftingConvAux(table, x, lower, upper); - if (!result) - goto cuddZddSymmSiftingConvOutOfMem; + result = cuddZddSymmSiftingConvAux(table, x, lower, upper); + if (!result) + goto cuddZddSymmSiftingConvOutOfMem; #ifdef DD_STATS - if (table->keysZ < (unsigned) previousSize) { - (void) fprintf(table->out,"-"); - } else if (table->keysZ > (unsigned) previousSize) { - (void) fprintf(table->out,"+"); + if (table->keysZ < (unsigned) previousSize) { + (void) fprintf(table->out,"-"); + } else if (table->keysZ > (unsigned) previousSize) { + (void) fprintf(table->out,"+"); #ifdef DD_VERBOSE - (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); + (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]); #endif - } else { - (void) fprintf(table->out,"="); - } - fflush(table->out); + } else { + (void) fprintf(table->out,"="); + } + fflush(table->out); #endif - } - } /* for */ + } + } /* for */ } cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups); #ifdef DD_STATS (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n", - symvars); + symvars); (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n", - symgroups); + symgroups); #endif ABC_FREE(var); @@ -543,9 +568,9 @@ cuddZddSymmSiftingConv( cuddZddSymmSiftingConvOutOfMem: if (zdd_entry != NULL) - ABC_FREE(zdd_entry); + ABC_FREE(zdd_entry); if (var != NULL) - ABC_FREE(var); + ABC_FREE(var); return(0); @@ -580,13 +605,13 @@ cuddZddSymmSiftingAux( int x_high) { Move *move; - Move *move_up; /* list of up move */ + Move *move_up; /* list of up move */ Move *move_down; /* list of down move */ - int initial_size; - int result; - int i; - int topbot; /* index to either top or bottom of symmetry group */ - int init_group_size, final_group_size; + int initial_size; + int result; + int i; + int topbot; /* index to either top or bottom of symmetry group */ + int init_group_size, final_group_size; initial_size = table->keysZ; @@ -595,300 +620,300 @@ cuddZddSymmSiftingAux( /* Look for consecutive symmetries above x. */ for (i = x; i > x_low; i--) { - if (!cuddZddSymmCheck(table, i - 1, i)) + if (!cuddZddSymmCheck(table, i - 1, i)) break; - /* find top of i-1's symmetry */ - topbot = table->subtableZ[i - 1].next; - table->subtableZ[i - 1].next = i; - table->subtableZ[x].next = topbot; - /* x is bottom of group so its symmetry is top of i-1's - group */ - i = topbot + 1; /* add 1 for i--, new i is top of symm group */ + /* find top of i-1's symmetry */ + topbot = table->subtableZ[i - 1].next; + table->subtableZ[i - 1].next = i; + table->subtableZ[x].next = topbot; + /* x is bottom of group so its symmetry is top of i-1's + group */ + i = topbot + 1; /* add 1 for i--, new i is top of symm group */ } /* Look for consecutive symmetries below x. */ for (i = x; i < x_high; i++) { - if (!cuddZddSymmCheck(table, i, i + 1)) + if (!cuddZddSymmCheck(table, i, i + 1)) break; - /* find bottom of i+1's symm group */ - topbot = i + 1; - while ((unsigned) topbot < table->subtableZ[topbot].next) - topbot = table->subtableZ[topbot].next; - - table->subtableZ[topbot].next = table->subtableZ[i].next; - table->subtableZ[i].next = i + 1; - i = topbot - 1; /* add 1 for i++, - new i is bottom of symm group */ + /* find bottom of i+1's symm group */ + topbot = i + 1; + while ((unsigned) topbot < table->subtableZ[topbot].next) + topbot = table->subtableZ[topbot].next; + + table->subtableZ[topbot].next = table->subtableZ[i].next; + table->subtableZ[i].next = i + 1; + i = topbot - 1; /* add 1 for i++, + new i is bottom of symm group */ } /* Now x maybe in the middle of a symmetry group. */ if (x == x_low) { /* Sift down */ - /* Find bottom of x's symm group */ - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - - i = table->subtableZ[x].next; - init_group_size = x - i + 1; + /* Find bottom of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - /* after that point x --> x_high, unless early term */ - if (move_down == ZDD_MV_OOM) - goto cuddZddSymmSiftingAuxOutOfMem; + i = table->subtableZ[x].next; + init_group_size = x - i + 1; - if (move_down == NULL || - table->subtableZ[move_down->y].next != move_down->y) { - /* symmetry detected may have to make another complete - pass */ + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ if (move_down != NULL) - x = move_down->y; - else - x = table->subtableZ[x].next; - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - final_group_size = i - x + 1; + x = move_down->y; + else + x = table->subtableZ[x].next; + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; - if (init_group_size == final_group_size) { - /* No new symmetry groups detected, - return to best position */ - result = cuddZddSymmSiftingBackward(table, - move_down, initial_size); + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, + move_down, initial_size); + } + else { + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } } else { - initial_size = table->keysZ; - move_up = cuddZddSymmSifting_up(table, x, x_low, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; } else if (x == x_high) { /* Sift up */ - /* Find top of x's symm group */ - while ((unsigned) x < table->subtableZ[x].next) + /* Find top of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; x = table->subtableZ[x].next; - x = table->subtableZ[x].next; - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - init_group_size = i - x + 1; + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; - move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); - /* after that point x --> x_low, unless early term */ - if (move_up == ZDD_MV_OOM) - goto cuddZddSymmSiftingAuxOutOfMem; + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_low, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; - if (move_up == NULL || - table->subtableZ[move_up->x].next != move_up->x) { - /* symmetry detected may have to make another complete - pass */ + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ if (move_up != NULL) - x = move_up->x; - else { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - } - i = table->subtableZ[x].next; - final_group_size = x - i + 1; + x = move_up->x; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; - if (init_group_size == final_group_size) { - /* No new symmetry groups detected, - return to best position */ - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } } else { - initial_size = table->keysZ; - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; } else if ((x - x_low) > (x_high - x)) { /* must go down first: - shorter */ - /* Find bottom of x's symm group */ - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - /* after that point x --> x_high, unless early term */ - if (move_down == ZDD_MV_OOM) - goto cuddZddSymmSiftingAuxOutOfMem; - - if (move_down != NULL) { - x = move_down->y; - } - else { - x = table->subtableZ[x].next; - } - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - init_group_size = i - x + 1; + shorter */ + /* Find bottom of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; - move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); - if (move_up == ZDD_MV_OOM) - goto cuddZddSymmSiftingAuxOutOfMem; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; - if (move_up == NULL || - table->subtableZ[move_up->x].next != move_up->x) { - /* symmetry detected may have to make another complete - pass */ - if (move_up != NULL) { - x = move_up->x; + if (move_down != NULL) { + x = move_down->y; } else { - while ((unsigned) x < table->subtableZ[x].next) x = table->subtableZ[x].next; } - i = table->subtableZ[x].next; - final_group_size = x - i + 1; + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; - if (init_group_size == final_group_size) { - /* No new symmetry groups detected, - return to best position */ - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } } else { - while (move_down != NULL) { - move = move_down->next; - cuddDeallocNode(table, (DdNode *)move_down); - move_down = move; + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ } - initial_size = table->keysZ; - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); - } - } - else { - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; } else { /* moving up first:shorter */ /* Find top of x's symmetry group */ - while ((unsigned) x < table->subtableZ[x].next) + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; x = table->subtableZ[x].next; - x = table->subtableZ[x].next; - move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); - /* after that point x --> x_high, unless early term */ - if (move_up == ZDD_MV_OOM) - goto cuddZddSymmSiftingAuxOutOfMem; + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_high, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; - if (move_up != NULL) { - x = move_up->x; - } - else { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - } - i = table->subtableZ[x].next; - init_group_size = x - i + 1; - - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - if (move_down == ZDD_MV_OOM) - goto cuddZddSymmSiftingAuxOutOfMem; - - if (move_down == NULL || - table->subtableZ[move_down->y].next != move_down->y) { - /* symmetry detected may have to make another complete - pass */ - if (move_down != NULL) { - x = move_down->y; + if (move_up != NULL) { + x = move_up->x; } else { - x = table->subtableZ[x].next; + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; } - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - final_group_size = i - x + 1; + i = table->subtableZ[x].next; + init_group_size = x - i + 1; - if (init_group_size == final_group_size) { - /* No new symmetries detected, - go back to best position */ - result = cuddZddSymmSiftingBackward(table, move_down, + move_down = cuddZddSymmSifting_down(table, x, x_high, initial_size); + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) { + x = move_down->y; + } + else { + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } } else { - while (move_up != NULL) { - move = move_up->next; - cuddDeallocNode(table, (DdNode *)move_up); - move_up = move; - } - initial_size = table->keysZ; - move_up = cuddZddSymmSifting_up(table, x, x_low, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingAuxOutOfMem; } while (move_down != NULL) { - move = move_down->next; - cuddDeallocNode(table, (DdNode *)move_down); - move_down = move; + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; } while (move_up != NULL) { - move = move_up->next; - cuddDeallocNode(table, (DdNode *)move_up); - move_up = move; + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; } return(1); cuddZddSymmSiftingAuxOutOfMem: if (move_down != ZDD_MV_OOM) { - while (move_down != NULL) { - move = move_down->next; - cuddDeallocNode(table, (DdNode *)move_down); - move_down = move; - } + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } } if (move_up != ZDD_MV_OOM) { - while (move_up != NULL) { - move = move_up->next; - cuddDeallocNode(table, (DdNode *)move_up); - move_up = move; - } + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } } return(0); @@ -919,13 +944,13 @@ cuddZddSymmSiftingConvAux( int x_low, int x_high) { - Move *move; - Move *move_up; /* list of up move */ - Move *move_down; /* list of down move */ - int initial_size; - int result; - int i; - int init_group_size, final_group_size; + Move *move; + Move *move_up; /* list of up move */ + Move *move_down; /* list of down move */ + int initial_size; + int result; + int i; + int init_group_size, final_group_size; initial_size = table->keysZ; @@ -934,269 +959,269 @@ cuddZddSymmSiftingConvAux( if (x == x_low) { /* Sift down */ i = table->subtableZ[x].next; - init_group_size = x - i + 1; - - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - /* after that point x --> x_high, unless early term */ - if (move_down == ZDD_MV_OOM) - goto cuddZddSymmSiftingConvAuxOutOfMem; - - if (move_down == NULL || - table->subtableZ[move_down->y].next != move_down->y) { - /* symmetry detected may have to make another complete - pass */ - if (move_down != NULL) - x = move_down->y; - else { - while ((unsigned) x < table->subtableZ[x].next); - x = table->subtableZ[x].next; - x = table->subtableZ[x].next; - } - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - final_group_size = i - x + 1; + init_group_size = x - i + 1; - if (init_group_size == final_group_size) { - /* No new symmetries detected, - go back to best position */ - result = cuddZddSymmSiftingBackward(table, move_down, + move_down = cuddZddSymmSifting_down(table, x, x_high, initial_size); + /* after that point x --> x_high, unless early term */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ + if (move_down != NULL) + x = move_down->y; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + final_group_size = i - x + 1; + + if (init_group_size == final_group_size) { + /* No new symmetries detected, + go back to best position */ + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } + else { + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } } else { - initial_size = table->keysZ; - move_up = cuddZddSymmSifting_up(table, x, x_low, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingConvAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; } else if (x == x_high) { /* Sift up */ - /* Find top of x's symm group */ - while ((unsigned) x < table->subtableZ[x].next) + /* Find top of x's symm group */ + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; x = table->subtableZ[x].next; - x = table->subtableZ[x].next; - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - init_group_size = i - x + 1; + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; - move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); - /* after that point x --> x_low, unless early term */ - if (move_up == ZDD_MV_OOM) - goto cuddZddSymmSiftingConvAuxOutOfMem; + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_low, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; - if (move_up == NULL || - table->subtableZ[move_up->x].next != move_up->x) { - /* symmetry detected may have to make another complete - pass */ + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ if (move_up != NULL) - x = move_up->x; - else { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - } - i = table->subtableZ[x].next; - final_group_size = x - i + 1; + x = move_up->x; + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } + i = table->subtableZ[x].next; + final_group_size = x - i + 1; - if (init_group_size == final_group_size) { - /* No new symmetry groups detected, - return to best position */ - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + if (init_group_size == final_group_size) { + /* No new symmetry groups detected, + return to best position */ + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + } + else { + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + } } else { - initial_size = table->keysZ; - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingConvAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; } else if ((x - x_low) > (x_high - x)) { /* must go down first: - shorter */ - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - /* after that point x --> x_high */ - if (move_down == ZDD_MV_OOM) - goto cuddZddSymmSiftingConvAuxOutOfMem; - - if (move_down != NULL) { - x = move_down->y; - } - else { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - x = table->subtableZ[x].next; - } - i = x; - while ((unsigned) i < table->subtableZ[i].next) { - i = table->subtableZ[i].next; - } - init_group_size = i - x + 1; - - move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); - if (move_up == ZDD_MV_OOM) - goto cuddZddSymmSiftingConvAuxOutOfMem; + shorter */ + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + /* after that point x --> x_high */ + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; - if (move_up == NULL || - table->subtableZ[move_up->x].next != move_up->x) { - /* symmetry detected may have to make another complete - pass */ - if (move_up != NULL) { - x = move_up->x; + if (move_down != NULL) { + x = move_down->y; } else { - while ((unsigned) x < table->subtableZ[x].next) + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; x = table->subtableZ[x].next; } + i = x; + while ((unsigned) i < table->subtableZ[i].next) { + i = table->subtableZ[i].next; + } + init_group_size = i - x + 1; + + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; + + if (move_up == NULL || + table->subtableZ[move_up->x].next != move_up->x) { + /* symmetry detected may have to make another complete + pass */ + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } i = table->subtableZ[x].next; final_group_size = x - i + 1; if (init_group_size == final_group_size) { - /* No new symmetry groups detected, - return to best position */ + /* No new symmetry groups detected, + return to best position */ result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + initial_size); + } + else { + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } + initial_size = table->keysZ; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); } - else { - while (move_down != NULL) { - move = move_down->next; - cuddDeallocNode(table, (DdNode *)move_down); - move_down = move; } - initial_size = table->keysZ; - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); + else { + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingConvAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; } else { /* moving up first:shorter */ - /* Find top of x's symmetry group */ - x = table->subtableZ[x].next; + /* Find top of x's symmetry group */ + x = table->subtableZ[x].next; - move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); - /* after that point x --> x_high, unless early term */ - if (move_up == ZDD_MV_OOM) - goto cuddZddSymmSiftingConvAuxOutOfMem; + move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size); + /* after that point x --> x_high, unless early term */ + if (move_up == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; - if (move_up != NULL) { - x = move_up->x; - } - else { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - } + if (move_up != NULL) { + x = move_up->x; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + } i = table->subtableZ[x].next; init_group_size = x - i + 1; - move_down = cuddZddSymmSifting_down(table, x, x_high, - initial_size); - if (move_down == ZDD_MV_OOM) - goto cuddZddSymmSiftingConvAuxOutOfMem; + move_down = cuddZddSymmSifting_down(table, x, x_high, + initial_size); + if (move_down == ZDD_MV_OOM) + goto cuddZddSymmSiftingConvAuxOutOfMem; - if (move_down == NULL || - table->subtableZ[move_down->y].next != move_down->y) { - /* symmetry detected may have to make another complete - pass */ + if (move_down == NULL || + table->subtableZ[move_down->y].next != move_down->y) { + /* symmetry detected may have to make another complete + pass */ if (move_down != NULL) { - x = move_down->y; - } - else { - while ((unsigned) x < table->subtableZ[x].next) - x = table->subtableZ[x].next; - x = table->subtableZ[x].next; - } + x = move_down->y; + } + else { + while ((unsigned) x < table->subtableZ[x].next) + x = table->subtableZ[x].next; + x = table->subtableZ[x].next; + } i = x; while ((unsigned) i < table->subtableZ[i].next) { i = table->subtableZ[i].next; } - final_group_size = i - x + 1; + final_group_size = i - x + 1; if (init_group_size == final_group_size) { - /* No new symmetries detected, - go back to best position */ + /* No new symmetries detected, + go back to best position */ result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); + initial_size); + } + else { + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } + initial_size = table->keysZ; + move_up = cuddZddSymmSifting_up(table, x, x_low, + initial_size); + result = cuddZddSymmSiftingBackward(table, move_up, + initial_size); } - else { - while (move_up != NULL) { - move = move_up->next; - cuddDeallocNode(table, (DdNode *)move_up); - move_up = move; } - initial_size = table->keysZ; - move_up = cuddZddSymmSifting_up(table, x, x_low, - initial_size); - result = cuddZddSymmSiftingBackward(table, move_up, - initial_size); + else { + result = cuddZddSymmSiftingBackward(table, move_down, + initial_size); + /* move backward and stop at best position */ } - } - else { - result = cuddZddSymmSiftingBackward(table, move_down, - initial_size); - /* move backward and stop at best position */ - } - if (!result) - goto cuddZddSymmSiftingConvAuxOutOfMem; + if (!result) + goto cuddZddSymmSiftingConvAuxOutOfMem; } while (move_down != NULL) { - move = move_down->next; - cuddDeallocNode(table, (DdNode *)move_down); - move_down = move; + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; } while (move_up != NULL) { - move = move_up->next; - cuddDeallocNode(table, (DdNode *)move_up); - move_up = move; + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; } return(1); cuddZddSymmSiftingConvAuxOutOfMem: if (move_down != ZDD_MV_OOM) { - while (move_down != NULL) { - move = move_down->next; - cuddDeallocNode(table, (DdNode *)move_down); - move_down = move; - } + while (move_down != NULL) { + move = move_down->next; + cuddDeallocMove(table, move_down); + move_down = move; + } } if (move_up != ZDD_MV_OOM) { - while (move_up != NULL) { - move = move_up->next; - cuddDeallocNode(table, (DdNode *)move_up); - move_up = move; - } + while (move_up != NULL) { + move = move_up->next; + cuddDeallocMove(table, move_up); + move_up = move; + } } return(0); @@ -1228,64 +1253,64 @@ cuddZddSymmSifting_up( int x_low, int initial_size) { - Move *moves; - Move *move; - int y; - int size; - int limit_size = initial_size; - int i, gytop; + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + int i, gytop; moves = NULL; y = cuddZddNextLow(table, x); while (y >= x_low) { - gytop = table->subtableZ[y].next; - if (cuddZddSymmCheck(table, y, x)) { - /* Symmetry found, attach symm groups */ - table->subtableZ[y].next = x; - i = table->subtableZ[x].next; - while (table->subtableZ[i].next != (unsigned) x) - i = table->subtableZ[i].next; - table->subtableZ[i].next = gytop; - } - else if ((table->subtableZ[x].next == (unsigned) x) && - (table->subtableZ[y].next == (unsigned) y)) { - /* x and y have self symmetry */ - size = cuddZddSwapInPlace(table, y, x); - if (size == 0) - goto cuddZddSymmSifting_upOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto cuddZddSymmSifting_upOutOfMem; - move->x = y; - move->y = x; - move->size = size; - move->next = moves; - moves = move; - if ((double)size > - (double)limit_size * table->maxGrowth) - return(moves); - if (size < limit_size) - limit_size = size; - } - else { /* Group move */ - size = zdd_group_move(table, y, x, &moves); - if ((double)size > - (double)limit_size * table->maxGrowth) - return(moves); - if (size < limit_size) - limit_size = size; - } - x = gytop; - y = cuddZddNextLow(table, x); + gytop = table->subtableZ[y].next; + if (cuddZddSymmCheck(table, y, x)) { + /* Symmetry found, attach symm groups */ + table->subtableZ[y].next = x; + i = table->subtableZ[x].next; + while (table->subtableZ[i].next != (unsigned) x) + i = table->subtableZ[i].next; + table->subtableZ[i].next = gytop; + } + else if ((table->subtableZ[x].next == (unsigned) x) && + (table->subtableZ[y].next == (unsigned) y)) { + /* x and y have self symmetry */ + size = cuddZddSwapInPlace(table, y, x); + if (size == 0) + goto cuddZddSymmSifting_upOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSymmSifting_upOutOfMem; + move->x = y; + move->y = x; + move->size = size; + move->next = moves; + moves = move; + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + else { /* Group move */ + size = zdd_group_move(table, y, x, &moves); + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + x = gytop; + y = cuddZddNextLow(table, x); } return(moves); cuddZddSymmSifting_upOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(ZDD_MV_OOM); @@ -1316,69 +1341,69 @@ cuddZddSymmSifting_down( int x_high, int initial_size) { - Move *moves; - Move *move; - int y; - int size; - int limit_size = initial_size; - int i, gxtop, gybot; + Move *moves; + Move *move; + int y; + int size; + int limit_size = initial_size; + int i, gxtop, gybot; moves = NULL; y = cuddZddNextHigh(table, x); while (y <= x_high) { - gybot = table->subtableZ[y].next; - while (table->subtableZ[gybot].next != (unsigned) y) - gybot = table->subtableZ[gybot].next; - if (cuddZddSymmCheck(table, x, y)) { - /* Symmetry found, attach symm groups */ - gxtop = table->subtableZ[x].next; - table->subtableZ[x].next = y; - i = table->subtableZ[y].next; - while (table->subtableZ[i].next != (unsigned) y) - i = table->subtableZ[i].next; - table->subtableZ[i].next = gxtop; - } - else if ((table->subtableZ[x].next == (unsigned) x) && - (table->subtableZ[y].next == (unsigned) y)) { - /* x and y have self symmetry */ - size = cuddZddSwapInPlace(table, x, y); - if (size == 0) - goto cuddZddSymmSifting_downOutOfMem; - move = (Move *)cuddDynamicAllocNode(table); - if (move == NULL) - goto cuddZddSymmSifting_downOutOfMem; - move->x = x; - move->y = y; - move->size = size; - move->next = moves; - moves = move; - if ((double)size > - (double)limit_size * table->maxGrowth) - return(moves); - if (size < limit_size) - limit_size = size; - x = y; + gybot = table->subtableZ[y].next; + while (table->subtableZ[gybot].next != (unsigned) y) + gybot = table->subtableZ[gybot].next; + if (cuddZddSymmCheck(table, x, y)) { + /* Symmetry found, attach symm groups */ + gxtop = table->subtableZ[x].next; + table->subtableZ[x].next = y; + i = table->subtableZ[y].next; + while (table->subtableZ[i].next != (unsigned) y) + i = table->subtableZ[i].next; + table->subtableZ[i].next = gxtop; + } + else if ((table->subtableZ[x].next == (unsigned) x) && + (table->subtableZ[y].next == (unsigned) y)) { + /* x and y have self symmetry */ + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto cuddZddSymmSifting_downOutOfMem; + move = (Move *)cuddDynamicAllocNode(table); + if (move == NULL) + goto cuddZddSymmSifting_downOutOfMem; + move->x = x; + move->y = y; + move->size = size; + move->next = moves; + moves = move; + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + x = y; + y = cuddZddNextHigh(table, x); + } + else { /* Group move */ + size = zdd_group_move(table, x, y, &moves); + if ((double)size > + (double)limit_size * table->maxGrowth) + return(moves); + if (size < limit_size) + limit_size = size; + } + x = gybot; y = cuddZddNextHigh(table, x); } - else { /* Group move */ - size = zdd_group_move(table, x, y, &moves); - if ((double)size > - (double)limit_size * table->maxGrowth) - return(moves); - if (size < limit_size) - limit_size = size; - } - x = gybot; - y = cuddZddNextHigh(table, x); - } return(moves); cuddZddSymmSifting_downOutOfMem: while (moves != NULL) { - move = moves->next; - cuddDeallocNode(table, (DdNode *)moves); - moves = move; + move = moves->next; + cuddDeallocMove(table, moves); + moves = move; } return(ZDD_MV_OOM); @@ -1406,31 +1431,31 @@ cuddZddSymmSiftingBackward( Move * moves, int size) { - int i; - int i_best; - Move *move; - int res; + int i; + int i_best; + Move *move; + int res; i_best = -1; for (move = moves, i = 0; move != NULL; move = move->next, i++) { - if (move->size < size) { - i_best = i; - size = move->size; - } + if (move->size < size) { + i_best = i; + size = move->size; + } } for (move = moves, i = 0; move != NULL; move = move->next, i++) { - if (i == i_best) break; - if ((table->subtableZ[move->x].next == move->x) && - (table->subtableZ[move->y].next == move->y)) { - res = cuddZddSwapInPlace(table, move->x, move->y); - if (!res) return(0); - } - else { /* Group move necessary */ - res = zdd_group_move_backward(table, move->x, move->y); - } - if (i_best == -1 && res == size) - break; + if (i == i_best) break; + if ((table->subtableZ[move->x].next == move->x) && + (table->subtableZ[move->y].next == move->y)) { + res = cuddZddSwapInPlace(table, move->x, move->y); + if (!res) return(0); + } + else { /* Group move necessary */ + res = zdd_group_move_backward(table, move->x, move->y); + } + if (i_best == -1 && res == size) + break; } return(1); @@ -1459,75 +1484,74 @@ zdd_group_move( int y, Move ** moves) { - Move *move; - int size; - int i, temp, gxtop, gxbot, gytop, gybot, yprev; - int swapx = 0, swapy = 0; // Suppress "might be used uninitialized" + Move *move; + int size; + int i, temp, gxtop, gxbot, gybot, yprev; + int swapx, swapy; #ifdef DD_DEBUG - assert(x < y); /* we assume that x < y */ + assert(x < y); /* we assume that x < y */ #endif /* Find top and bottom for the two groups. */ gxtop = table->subtableZ[x].next; - gytop = y; gxbot = x; gybot = table->subtableZ[y].next; while (table->subtableZ[gybot].next != (unsigned) y) - gybot = table->subtableZ[gybot].next; + gybot = table->subtableZ[gybot].next; yprev = gybot; while (x <= y) { - while (y > gxtop) { - /* Set correct symmetries. */ - temp = table->subtableZ[x].next; - if (temp == x) - temp = y; - i = gxtop; - for (;;) { - if (table->subtableZ[i].next == (unsigned) x) { - table->subtableZ[i].next = y; - break; - } else { - i = table->subtableZ[i].next; - } - } - if (table->subtableZ[y].next != (unsigned) y) { - table->subtableZ[x].next = table->subtableZ[y].next; - } else { - table->subtableZ[x].next = x; - } + while (y > gxtop) { + /* Set correct symmetries. */ + temp = table->subtableZ[x].next; + if (temp == x) + temp = y; + i = gxtop; + for (;;) { + if (table->subtableZ[i].next == (unsigned) x) { + table->subtableZ[i].next = y; + break; + } else { + i = table->subtableZ[i].next; + } + } + if (table->subtableZ[y].next != (unsigned) y) { + table->subtableZ[x].next = table->subtableZ[y].next; + } else { + table->subtableZ[x].next = x; + } - if (yprev != y) { - table->subtableZ[yprev].next = x; - } else { - yprev = x; - } - table->subtableZ[y].next = temp; + if (yprev != y) { + table->subtableZ[yprev].next = x; + } else { + yprev = x; + } + table->subtableZ[y].next = temp; - size = cuddZddSwapInPlace(table, x, y); - if (size == 0) - goto zdd_group_moveOutOfMem; + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + goto zdd_group_moveOutOfMem; swapx = x; - swapy = y; - y = x; - x--; - } /* while y > gxtop */ - - /* Trying to find the next y. */ - if (table->subtableZ[y].next <= (unsigned) y) { - gybot = y; - } else { - y = table->subtableZ[y].next; - } + swapy = y; + y = x; + x--; + } /* while y > gxtop */ + + /* Trying to find the next y. */ + if (table->subtableZ[y].next <= (unsigned) y) { + gybot = y; + } else { + y = table->subtableZ[y].next; + } - yprev = gxtop; - gxtop++; - gxbot++; - x = gxbot; + yprev = gxtop; + gxtop++; + gxbot++; + x = gxbot; } /* while x <= y, end of group movement */ move = (Move *)cuddDynamicAllocNode(table); if (move == NULL) - goto zdd_group_moveOutOfMem; + goto zdd_group_moveOutOfMem; move->x = swapx; move->y = swapy; move->size = table->keysZ; @@ -1538,9 +1562,9 @@ zdd_group_move( zdd_group_moveOutOfMem: while (*moves != NULL) { - move = (*moves)->next; - cuddDeallocNode(table, (DdNode *)(*moves)); - *moves = move; + move = (*moves)->next; + cuddDeallocMove(table, *moves); + *moves = move; } return(0); @@ -1566,67 +1590,66 @@ zdd_group_move_backward( int x, int y) { - int size = -1; // Suppress "might be used uninitialized" - int i, temp, gxtop, gxbot, gytop, gybot, yprev; + int size; + int i, temp, gxtop, gxbot, gybot, yprev; #ifdef DD_DEBUG - assert(x < y); /* we assume that x < y */ + assert(x < y); /* we assume that x < y */ #endif /* Find top and bottom of the two groups. */ gxtop = table->subtableZ[x].next; - gytop = y; gxbot = x; gybot = table->subtableZ[y].next; while (table->subtableZ[gybot].next != (unsigned) y) - gybot = table->subtableZ[gybot].next; + gybot = table->subtableZ[gybot].next; yprev = gybot; while (x <= y) { - while (y > gxtop) { - /* Set correct symmetries. */ - temp = table->subtableZ[x].next; - if (temp == x) - temp = y; - i = gxtop; - for (;;) { - if (table->subtableZ[i].next == (unsigned) x) { - table->subtableZ[i].next = y; - break; - } else { - i = table->subtableZ[i].next; - } - } - if (table->subtableZ[y].next != (unsigned) y) { - table->subtableZ[x].next = table->subtableZ[y].next; - } else { - table->subtableZ[x].next = x; - } + while (y > gxtop) { + /* Set correct symmetries. */ + temp = table->subtableZ[x].next; + if (temp == x) + temp = y; + i = gxtop; + for (;;) { + if (table->subtableZ[i].next == (unsigned) x) { + table->subtableZ[i].next = y; + break; + } else { + i = table->subtableZ[i].next; + } + } + if (table->subtableZ[y].next != (unsigned) y) { + table->subtableZ[x].next = table->subtableZ[y].next; + } else { + table->subtableZ[x].next = x; + } - if (yprev != y) { - table->subtableZ[yprev].next = x; + if (yprev != y) { + table->subtableZ[yprev].next = x; + } else { + yprev = x; + } + table->subtableZ[y].next = temp; + + size = cuddZddSwapInPlace(table, x, y); + if (size == 0) + return(0); + y = x; + x--; + } /* while y > gxtop */ + + /* Trying to find the next y. */ + if (table->subtableZ[y].next <= (unsigned) y) { + gybot = y; } else { - yprev = x; + y = table->subtableZ[y].next; } - table->subtableZ[y].next = temp; - - size = cuddZddSwapInPlace(table, x, y); - if (size == 0) - return(0); - y = x; - x--; - } /* while y > gxtop */ - - /* Trying to find the next y. */ - if (table->subtableZ[y].next <= (unsigned) y) { - gybot = y; - } else { - y = table->subtableZ[y].next; - } - yprev = gxtop; - gxtop++; - gxbot++; - x = gxbot; + yprev = gxtop; + gxtop++; + gxbot++; + x = gxbot; } /* while x <= y, end of group movement backward */ return(size); @@ -1657,19 +1680,19 @@ cuddZddSymmSummary( int TotalSymmGroups = 0; for (i = lower; i <= upper; i++) { - if (table->subtableZ[i].next != (unsigned) i) { - TotalSymmGroups++; - x = i; - do { - TotalSymm++; - gbot = x; - x = table->subtableZ[x].next; - } while (x != i); + if (table->subtableZ[i].next != (unsigned) i) { + TotalSymmGroups++; + x = i; + do { + TotalSymm++; + gbot = x; + x = table->subtableZ[x].next; + } while (x != i); #ifdef DD_DEBUG - assert(table->subtableZ[gbot].next == (unsigned) i); + assert(table->subtableZ[gbot].next == (unsigned) i); #endif - i = gbot; - } + i = gbot; + } } *symvars = TotalSymm; *symgroups = TotalSymmGroups; @@ -1678,5 +1701,7 @@ cuddZddSymmSummary( } /* end of cuddZddSymmSummary */ + ABC_NAMESPACE_IMPL_END + diff --git a/src/bdd/cudd/cuddZddUtil.c b/src/bdd/cudd/cuddZddUtil.c index 72ee639a..1e89c610 100644 --- a/src/bdd/cudd/cuddZddUtil.c +++ b/src/bdd/cudd/cuddZddUtil.c @@ -7,40 +7,72 @@ Synopsis [Utility functions for ZDDs.] Description [External procedures included in this module: - <ul> - <li> Cudd_zddPrintMinterm() - <li> Cudd_zddPrintCover() - <li> Cudd_zddPrintDebug() - <li> Cudd_zddDumpDot() - </ul> - Internal procedures included in this module: - <ul> - <li> cuddZddP() - </ul> - Static procedures included in this module: - <ul> - <li> zp2() - <li> zdd_print_minterm_aux() - </ul> - ] + <ul> + <li> Cudd_zddPrintMinterm() + <li> Cudd_zddPrintCover() + <li> Cudd_zddPrintDebug() + <li> Cudd_zddFirstPath() + <li> Cudd_zddNextPath() + <li> Cudd_zddCoverPathToString() + <li> Cudd_zddDumpDot() + </ul> + Internal procedures included in this module: + <ul> + <li> cuddZddP() + </ul> + Static procedures included in this module: + <ul> + <li> zp2() + <li> zdd_print_minterm_aux() + <li> zddPrintCoverAux() + </ul> + ] SeeAlso [] - Author [Hyong-Kyoon Shin, In-Ho Moon] + Author [Hyong-Kyoon Shin, In-Ho Moon, Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" -#include "cuddInt.h" +#include "util_hack.h" +#include "cuddInt.h" ABC_NAMESPACE_IMPL_START + /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ @@ -61,7 +93,7 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.27 2009/03/08 02:49:02 fabio Exp $"; #endif /*---------------------------------------------------------------------------*/ @@ -75,9 +107,9 @@ static char rcsid[] DD_UNUSED = "$Id: cuddZddUtil.c,v 1.1.1.1 2003/02/24 22:23:5 /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static int zp2 ARGS((DdManager *zdd, DdNode *f, st_table *t)); -static void zdd_print_minterm_aux ARGS((DdManager *zdd, DdNode *node, int level, int *list)); -static void zddPrintCoverAux ARGS((DdManager *zdd, DdNode *node, int level, int *list)); +static int zp2 (DdManager *zdd, DdNode *f, st_table *t); +static void zdd_print_minterm_aux (DdManager *zdd, DdNode *node, int level, int *list); +static void zddPrintCoverAux (DdManager *zdd, DdNode *node, int level, int *list); /**AutomaticEnd***************************************************************/ @@ -104,14 +136,14 @@ Cudd_zddPrintMinterm( DdManager * zdd, DdNode * node) { - int i, size; - int *list; + int i, size; + int *list; size = (int)zdd->sizeZ; list = ABC_ALLOC(int, size); if (list == NULL) { - zdd->errorCode = CUDD_MEMORY_OUT; - return(0); + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ zdd_print_minterm_aux(zdd, node, 0, list); @@ -138,15 +170,15 @@ Cudd_zddPrintCover( DdManager * zdd, DdNode * node) { - int i, size; - int *list; + int i, size; + int *list; size = (int)zdd->sizeZ; if (size % 2 != 0) return(0); /* number of variables should be even */ list = ABC_ALLOC(int, size); if (list == NULL) { - zdd->errorCode = CUDD_MEMORY_OUT; - return(0); + zdd->errorCode = CUDD_MEMORY_OUT; + return(0); } for (i = 0; i < size; i++) list[i] = 3; /* bogus value should disappear */ zddPrintCoverAux(zdd, node, 0, list); @@ -186,31 +218,31 @@ Cudd_zddPrintDebug( int n, int pr) { - DdNode *empty = DD_ZERO(zdd); - int nodes; - double minterms; - int retval = 1; + DdNode *empty = DD_ZERO(zdd); + int nodes; + double minterms; + int retval = 1; if (f == empty && pr > 0) { - (void) fprintf(zdd->out,": is the empty ZDD\n"); - (void) fflush(zdd->out); - return(1); + (void) fprintf(zdd->out,": is the empty ZDD\n"); + (void) fflush(zdd->out); + return(1); } if (pr > 0) { - nodes = Cudd_zddDagSize(f); - if (nodes == CUDD_OUT_OF_MEM) retval = 0; - minterms = Cudd_zddCountMinterm(zdd, f, n); - if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; - (void) fprintf(zdd->out,": %d nodes %g minterms\n", - nodes, minterms); - if (pr > 2) - if (!cuddZddP(zdd, f)) retval = 0; - if (pr == 2 || pr > 3) { - if (!Cudd_zddPrintMinterm(zdd, f)) retval = 0; - (void) fprintf(zdd->out,"\n"); - } - (void) fflush(zdd->out); + nodes = Cudd_zddDagSize(f); + if (nodes == CUDD_OUT_OF_MEM) retval = 0; + minterms = Cudd_zddCountMinterm(zdd, f, n); + if (minterms == (double)CUDD_OUT_OF_MEM) retval = 0; + (void) fprintf(zdd->out,": %d nodes %g minterms\n", + nodes, minterms); + if (pr > 2) + if (!cuddZddP(zdd, f)) retval = 0; + if (pr == 2 || pr > 3) { + if (!Cudd_zddPrintMinterm(zdd, f)) retval = 0; + (void) fprintf(zdd->out,"\n"); + } + (void) fflush(zdd->out); } return(retval); @@ -256,8 +288,8 @@ Cudd_zddFirstPath( /* Allocate generator an initialize it. */ gen = ABC_ALLOC(DdGen,1); if (gen == NULL) { - zdd->errorCode = CUDD_MEMORY_OUT; - return(NULL); + zdd->errorCode = CUDD_MEMORY_OUT; + return(NULL); } gen->manager = zdd; @@ -272,9 +304,9 @@ Cudd_zddFirstPath( nvars = zdd->sizeZ; gen->gen.cubes.cube = ABC_ALLOC(int,nvars); if (gen->gen.cubes.cube == NULL) { - zdd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(gen); - return(NULL); + zdd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(gen); + return(NULL); } for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2; @@ -282,12 +314,12 @@ Cudd_zddFirstPath( ** because a path may have nodes at all levels, including the ** constant level. */ - gen->stack.stack = ABC_ALLOC(DdNode *, nvars+1); + gen->stack.stack = ABC_ALLOC(DdNodePtr, nvars+1); if (gen->stack.stack == NULL) { - zdd->errorCode = CUDD_MEMORY_OUT; - ABC_FREE(gen->gen.cubes.cube); - ABC_FREE(gen); - return(NULL); + zdd->errorCode = CUDD_MEMORY_OUT; + ABC_FREE(gen->gen.cubes.cube); + ABC_FREE(gen); + return(NULL); } for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL; @@ -295,38 +327,38 @@ Cudd_zddFirstPath( gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++; while (1) { - top = gen->stack.stack[gen->stack.sp-1]; - if (!cuddIsConstant(top)) { - /* Take the else branch first. */ - gen->gen.cubes.cube[top->index] = 0; - next = cuddE(top); - gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; - } else if (top == DD_ZERO(zdd)) { - /* Backtrack. */ - while (1) { - if (gen->stack.sp == 1) { - /* The current node has no predecessor. */ - gen->status = CUDD_GEN_EMPTY; - gen->stack.sp--; - goto done; - } - prev = gen->stack.stack[gen->stack.sp-2]; - next = cuddT(prev); - if (next != top) { /* follow the then branch next */ - gen->gen.cubes.cube[prev->index] = 1; - gen->stack.stack[gen->stack.sp-1] = next; - break; - } - /* Pop the stack and try again. */ - gen->gen.cubes.cube[prev->index] = 2; - gen->stack.sp--; top = gen->stack.stack[gen->stack.sp-1]; + if (!cuddIsConstant(Cudd_Regular(top))) { + /* Take the else branch first. */ + gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; + next = cuddE(Cudd_Regular(top)); + gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; + } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { + /* Backtrack. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(Cudd_Regular(top)); + goto done; } - } else { - gen->status = CUDD_GEN_NONEMPTY; - gen->gen.cubes.value = cuddV(top); - goto done; - } } done: @@ -361,42 +393,14 @@ Cudd_zddNextPath( /* Backtrack from previously reached terminal node. */ while (1) { - if (gen->stack.sp == 1) { - /* The current node has no predecessor. */ - gen->status = CUDD_GEN_EMPTY; - gen->stack.sp--; - goto done; - } - top = gen->stack.stack[gen->stack.sp-1]; - prev = gen->stack.stack[gen->stack.sp-2]; - next = cuddT(prev); - if (next != top) { /* follow the then branch next */ - gen->gen.cubes.cube[prev->index] = 1; - gen->stack.stack[gen->stack.sp-1] = next; - break; - } - /* Pop the stack and try again. */ - gen->gen.cubes.cube[prev->index] = 2; - gen->stack.sp--; - } - - while (1) { - top = gen->stack.stack[gen->stack.sp-1]; - if (!cuddIsConstant(top)) { - /* Take the else branch first. */ - gen->gen.cubes.cube[top->index] = 0; - next = cuddE(top); - gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++; - } else if (top == DD_ZERO(zdd)) { - /* Backtrack. */ - while (1) { if (gen->stack.sp == 1) { /* The current node has no predecessor. */ gen->status = CUDD_GEN_EMPTY; gen->stack.sp--; goto done; } - prev = gen->stack.stack[gen->stack.sp-2]; + top = gen->stack.stack[gen->stack.sp-1]; + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); next = cuddT(prev); if (next != top) { /* follow the then branch next */ gen->gen.cubes.cube[prev->index] = 1; @@ -406,13 +410,41 @@ Cudd_zddNextPath( /* Pop the stack and try again. */ gen->gen.cubes.cube[prev->index] = 2; gen->stack.sp--; + } + + while (1) { top = gen->stack.stack[gen->stack.sp-1]; + if (!cuddIsConstant(Cudd_Regular(top))) { + /* Take the else branch first. */ + gen->gen.cubes.cube[Cudd_Regular(top)->index] = 0; + next = cuddE(Cudd_Regular(top)); + gen->stack.stack[gen->stack.sp] = Cudd_Not(next); gen->stack.sp++; + } else if (Cudd_Regular(top) == DD_ZERO(zdd)) { + /* Backtrack. */ + while (1) { + if (gen->stack.sp == 1) { + /* The current node has no predecessor. */ + gen->status = CUDD_GEN_EMPTY; + gen->stack.sp--; + goto done; + } + prev = Cudd_Regular(gen->stack.stack[gen->stack.sp-2]); + next = cuddT(prev); + if (next != top) { /* follow the then branch next */ + gen->gen.cubes.cube[prev->index] = 1; + gen->stack.stack[gen->stack.sp-1] = next; + break; + } + /* Pop the stack and try again. */ + gen->gen.cubes.cube[prev->index] = 2; + gen->stack.sp--; + top = gen->stack.stack[gen->stack.sp-1]; + } + } else { + gen->status = CUDD_GEN_NONEMPTY; + gen->gen.cubes.value = cuddV(Cudd_Regular(top)); + goto done; } - } else { - gen->status = CUDD_GEN_NONEMPTY; - gen->gen.cubes.value = cuddV(top); - goto done; - } } done: @@ -441,9 +473,9 @@ done: ******************************************************************************/ char * Cudd_zddCoverPathToString( - DdManager *zdd /* DD manager */, - int *path /* path of ZDD representing a cover */, - char *str /* pointer to string to use if != NULL */ + DdManager *zdd /* DD manager */, + int *path /* path of ZDD representing a cover */, + char *str /* pointer to string to use if != NULL */ ) { int nvars = zdd->sizeZ; @@ -453,31 +485,31 @@ Cudd_zddCoverPathToString( if (nvars & 1) return(NULL); nvars >>= 1; if (str == NULL) { - res = ABC_ALLOC(char, nvars+1); - if (res == NULL) return(NULL); + res = ABC_ALLOC(char, nvars+1); + if (res == NULL) return(NULL); } else { - res = str; + res = str; } for (i = 0; i < nvars; i++) { - int v = (path[2*i] << 2) | path[2*i+1]; - switch (v) { - case 0: - case 2: - case 8: - case 10: - res[i] = '-'; - break; - case 1: - case 9: - res[i] = '0'; - break; - case 4: - case 6: - res[i] = '1'; - break; - default: - res[i] = '?'; - } + int v = (path[2*i] << 2) | path[2*i+1]; + switch (v) { + case 0: + case 2: + case 8: + case 10: + res[i] = '-'; + break; + case 1: + case 9: + res[i] = '0'; + break; + case 4: + case 6: + res[i] = '1'; + break; + default: + res[i] = '?'; + } } res[nvars] = 0; @@ -522,37 +554,37 @@ Cudd_zddDumpDot( char ** onames /* array of output names (or NULL) */, FILE * fp /* pointer to the dump file */) { - DdNode *support = NULL; - DdNode *scan; - int *sorted = NULL; - int nvars = dd->sizeZ; + DdNode *support = NULL; + DdNode *scan; + int *sorted = NULL; + int nvars = dd->sizeZ; st_table *visited = NULL; st_generator *gen; - int retval; - int i, j; - int slots; - DdNodePtr *nodelist; - long refAddr, diff, mask; + int retval; + int i, j; + int slots; + DdNodePtr *nodelist; + long refAddr, diff, mask; /* Build a bit array with the support of f. */ sorted = ABC_ALLOC(int,nvars); if (sorted == NULL) { - dd->errorCode = CUDD_MEMORY_OUT; - goto failure; + dd->errorCode = CUDD_MEMORY_OUT; + goto failure; } for (i = 0; i < nvars; i++) sorted[i] = 0; /* Take the union of the supports of each output function. */ for (i = 0; i < n; i++) { - support = Cudd_Support(dd,f[i]); - if (support == NULL) goto failure; - cuddRef(support); - scan = support; - while (!cuddIsConstant(scan)) { - sorted[scan->index] = 1; - scan = cuddT(scan); - } - Cudd_RecursiveDeref(dd,support); + support = Cudd_Support(dd,f[i]); + if (support == NULL) goto failure; + cuddRef(support); + scan = support; + while (!cuddIsConstant(scan)) { + sorted[scan->index] = 1; + scan = cuddT(scan); + } + Cudd_RecursiveDeref(dd,support); } support = NULL; /* so that we do not try to free it in case of failure */ @@ -562,8 +594,8 @@ Cudd_zddDumpDot( /* Collect all the nodes of this DD in the symbol table. */ for (i = 0; i < n; i++) { - retval = cuddCollectNodes(f[i],visited); - if (retval == 0) goto failure; + retval = cuddCollectNodes(f[i],visited); + if (retval == 0) goto failure; } /* Find how many most significant hex digits are identical @@ -581,22 +613,22 @@ Cudd_zddDumpDot( refAddr = (long) f[0]; diff = 0; gen = st_init_gen(visited); - while (st_gen(gen, (const char **) &scan, NULL)) { - diff |= refAddr ^ (long) scan; + while (st_gen(gen, (const char **)&scan, NULL)) { + diff |= refAddr ^ (long) scan; } st_free_gen(gen); /* Choose the mask. */ for (i = 0; (unsigned) i < 8 * sizeof(long); i += 4) { - mask = (1 << i) - 1; - if (diff <= mask) break; + mask = (1 << i) - 1; + if (diff <= mask) break; } /* Write the header and the global attributes. */ retval = fprintf(fp,"digraph \"ZDD\" {\n"); if (retval == EOF) return(0); retval = fprintf(fp, - "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); + "size = \"7.5,10\"\ncenter = true;\nedge [dir = none];\n"); if (retval == EOF) return(0); /* Write the input name subgraph by scanning the support array. */ @@ -611,11 +643,11 @@ Cudd_zddDumpDot( if (retval == EOF) goto failure; for (i = 0; i < nvars; i++) { if (sorted[dd->invpermZ[i]]) { - if (inames == NULL) { - retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]); - } else { - retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]); - } + if (inames == NULL) { + retval = fprintf(fp,"\" %d \" -> ", dd->invpermZ[i]); + } else { + retval = fprintf(fp,"\" %s \" -> ", inames[dd->invpermZ[i]]); + } if (retval == EOF) goto failure; } } @@ -626,63 +658,66 @@ Cudd_zddDumpDot( retval = fprintf(fp,"{ rank = same; node [shape = box]; edge [style = invis];\n"); if (retval == EOF) goto failure; for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp,"\"F%d\"", i); - } else { - retval = fprintf(fp,"\" %s \"", onames[i]); - } - if (retval == EOF) goto failure; - if (i == n - 1) { - retval = fprintf(fp,"; }\n"); - } else { - retval = fprintf(fp," -> "); - } - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + if (i == n - 1) { + retval = fprintf(fp,"; }\n"); + } else { + retval = fprintf(fp," -> "); + } + if (retval == EOF) goto failure; } /* Write rank info: All nodes with the same index have the same rank. */ for (i = 0; i < nvars; i++) { if (sorted[dd->invpermZ[i]]) { - retval = fprintf(fp,"{ rank = same; "); - if (retval == EOF) goto failure; - if (inames == NULL) { - retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]); - } else { - retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]); - } + retval = fprintf(fp,"{ rank = same; "); if (retval == EOF) goto failure; - nodelist = dd->subtableZ[i].nodelist; - slots = dd->subtableZ[i].slots; - for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode)); + if (inames == NULL) { + retval = fprintf(fp,"\" %d \";\n", dd->invpermZ[i]); + } else { + retval = fprintf(fp,"\" %s \";\n", inames[dd->invpermZ[i]]); + } if (retval == EOF) goto failure; + nodelist = dd->subtableZ[i].nodelist; + slots = dd->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", (void *) + ((mask & (ptrint) scan) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } } - scan = scan->next; - } + retval = fprintf(fp,"}\n"); + if (retval == EOF) goto failure; } - retval = fprintf(fp,"}\n"); - if (retval == EOF) goto failure; - } } /* All constants have the same rank. */ retval = fprintf(fp, - "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); + "{ rank = same; \"CONST NODES\";\n{ node [shape = box]; "); if (retval == EOF) goto failure; nodelist = dd->constants.nodelist; slots = dd->constants.slots; for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp,"\"%lx\";\n", (mask & (long) scan) / sizeof(DdNode)); - if (retval == EOF) goto failure; + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\";\n", (void *) + ((mask & (ptrint) scan) / sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; } - scan = scan->next; - } } retval = fprintf(fp,"}\n}\n"); if (retval == EOF) goto failure; @@ -690,56 +725,63 @@ Cudd_zddDumpDot( /* Write edge info. */ /* Edges from the output nodes. */ for (i = 0; i < n; i++) { - if (onames == NULL) { - retval = fprintf(fp,"\"F%d\"", i); - } else { - retval = fprintf(fp,"\" %s \"", onames[i]); - } - if (retval == EOF) goto failure; - retval = fprintf(fp," -> \"%lx\" [style = solid];\n", - (mask & (long) f[i]) / sizeof(DdNode)); - if (retval == EOF) goto failure; + if (onames == NULL) { + retval = fprintf(fp,"\"F%d\"", i); + } else { + retval = fprintf(fp,"\" %s \"", onames[i]); + } + if (retval == EOF) goto failure; + retval = fprintf(fp," -> \"%p\" [style = solid];\n", + (void *) ((mask & (ptrint) f[i]) / + sizeof(DdNode))); + if (retval == EOF) goto failure; } /* Edges from internal nodes. */ for (i = 0; i < nvars; i++) { if (sorted[dd->invpermZ[i]]) { - nodelist = dd->subtableZ[i].nodelist; - slots = dd->subtableZ[i].slots; - for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp, - "\"%lx\" -> \"%lx\";\n", - (mask & (long) scan) / sizeof(DdNode), - (mask & (long) cuddT(scan)) / sizeof(DdNode)); - if (retval == EOF) goto failure; - retval = fprintf(fp, - "\"%lx\" -> \"%lx\" [style = dashed];\n", - (mask & (long) scan) / sizeof(DdNode), - (mask & (long) cuddE(scan)) / sizeof(DdNode)); - if (retval == EOF) goto failure; + nodelist = dd->subtableZ[i].nodelist; + slots = dd->subtableZ[i].slots; + for (j = 0; j < slots; j++) { + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp, + "\"%p\" -> \"%p\";\n", + (void *) ((mask & (ptrint) scan) / sizeof(DdNode)), + (void *) ((mask & (ptrint) cuddT(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + retval = fprintf(fp, + "\"%p\" -> \"%p\" [style = dashed];\n", + (void *) ((mask & (ptrint) scan) + / sizeof(DdNode)), + (void *) ((mask & (ptrint) + cuddE(scan)) / + sizeof(DdNode))); + if (retval == EOF) goto failure; + } + scan = scan->next; + } } - scan = scan->next; } - } - } } /* Write constant labels. */ nodelist = dd->constants.nodelist; slots = dd->constants.slots; for (j = 0; j < slots; j++) { - scan = nodelist[j]; - while (scan != NULL) { - if (st_is_member(visited,(char *) scan)) { - retval = fprintf(fp,"\"%lx\" [label = \"%g\"];\n", - (mask & (long) scan) / sizeof(DdNode), cuddV(scan)); - if (retval == EOF) goto failure; + scan = nodelist[j]; + while (scan != NULL) { + if (st_is_member(visited,(char *) scan)) { + retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n", + (void *) ((mask & (ptrint) scan) / + sizeof(DdNode)), + cuddV(scan)); + if (retval == EOF) goto failure; + } + scan = scan->next; } - scan = scan->next; - } } /* Write trailer and return. */ @@ -752,7 +794,6 @@ Cudd_zddDumpDot( failure: if (sorted != NULL) ABC_FREE(sorted); - if (support != NULL) Cudd_RecursiveDeref(dd,support); if (visited != NULL) st_free_table(visited); return(0); @@ -769,7 +810,7 @@ failure: Synopsis [Prints a ZDD to the standard output. One line per node is printed.] - Description [Prints a ZDD to the standard output. One line per node is + Description [Prints a ZDD to the standard output. One line per node is printed. Returns 1 if successful; 0 otherwise.] SideEffects [None] @@ -818,63 +859,65 @@ zp2( DdNode * f, st_table * t) { - DdNode *n; - int T, E; - DdNode *base = DD_ONE(zdd); - + DdNode *n; + int T, E; + DdNode *base = DD_ONE(zdd); + if (f == NULL) - return(0); + return(0); if (Cudd_IsConstant(f)) { (void)fprintf(zdd->out, "ID = %d\n", (f == base)); - return(1); + return(1); } if (st_is_member(t, (char *)f) == 1) - return(1); + return(1); if (st_insert(t, (char *) f, NULL) == ST_OUT_OF_MEM) - return(0); + return(0); #if SIZEOF_VOID_P == 8 - (void) fprintf(zdd->out, "ID = 0x%lx\tindex = %d\tr = %d\t", - (unsigned long)f / (unsigned long) sizeof(DdNode), f->index, f->ref); + (void) fprintf(zdd->out, "ID = 0x%lx\tindex = %u\tr = %u\t", + (ptruint)f / (ptruint) sizeof(DdNode), f->index, f->ref); #else - (void) fprintf(zdd->out, "ID = 0x%x\tindex = %d\tr = %d\t", - (unsigned)f / (unsigned) sizeof(DdNode), f->index, f->ref); + (void) fprintf(zdd->out, "ID = 0x%x\tindex = %hu\tr = %hu\t", + (ptruint)f / (ptruint) sizeof(DdNode), f->index, f->ref); #endif n = cuddT(f); if (Cudd_IsConstant(n)) { (void) fprintf(zdd->out, "T = %d\t\t", (n == base)); - T = 1; + T = 1; } else { #if SIZEOF_VOID_P == 8 - (void) fprintf(zdd->out, "T = 0x%lx\t", (unsigned long) n / - (unsigned long) sizeof(DdNode)); + (void) fprintf(zdd->out, "T = 0x%lx\t", (ptruint) n / + (ptruint) sizeof(DdNode)); #else - (void) fprintf(zdd->out, "T = 0x%x\t", (unsigned) n / (unsigned) sizeof(DdNode)); + (void) fprintf(zdd->out, "T = 0x%x\t", (ptruint) n / + (ptruint) sizeof(DdNode)); #endif - T = 0; + T = 0; } n = cuddE(f); if (Cudd_IsConstant(n)) { (void) fprintf(zdd->out, "E = %d\n", (n == base)); - E = 1; + E = 1; } else { #if SIZEOF_VOID_P == 8 - (void) fprintf(zdd->out, "E = 0x%lx\n", (unsigned long) n / - (unsigned long) sizeof(DdNode)); + (void) fprintf(zdd->out, "E = 0x%lx\n", (ptruint) n / + (ptruint) sizeof(DdNode)); #else - (void) fprintf(zdd->out, "E = 0x%x\n", (unsigned) n / (unsigned) sizeof(DdNode)); + (void) fprintf(zdd->out, "E = 0x%x\n", (ptruint) n / + (ptruint) sizeof(DdNode)); #endif - E = 0; + E = 0; } if (E == 0) - if (zp2(zdd, cuddE(f), t) == 0) return(0); + if (zp2(zdd, cuddE(f), t) == 0) return(0); if (T == 0) - if (zp2(zdd, cuddT(f), t) == 0) return(0); + if (zp2(zdd, cuddT(f), t) == 0) return(0); return(1); } /* end of zp2 */ @@ -898,54 +941,54 @@ zdd_print_minterm_aux( int level /* depth in the recursion */, int * list /* current recursion path */) { - DdNode *Nv, *Nnv; - int i, v; - DdNode *base = DD_ONE(zdd); + DdNode *Nv, *Nnv; + int i, v; + DdNode *base = DD_ONE(zdd); if (Cudd_IsConstant(node)) { - if (node == base) { + if (node == base) { + /* Check for missing variable. */ + if (level != zdd->sizeZ) { + list[zdd->invpermZ[level]] = 0; + zdd_print_minterm_aux(zdd, node, level + 1, list); + return; + } + /* Terminal case: Print one cube based on the current recursion + ** path. + */ + for (i = 0; i < zdd->sizeZ; i++) { + v = list[i]; + if (v == 0) + (void) fprintf(zdd->out,"0"); + else if (v == 1) + (void) fprintf(zdd->out,"1"); + else if (v == 3) + (void) fprintf(zdd->out,"@"); /* should never happen */ + else + (void) fprintf(zdd->out,"-"); + } + (void) fprintf(zdd->out," 1\n"); + } + } else { /* Check for missing variable. */ - if (level != zdd->sizeZ) { - list[zdd->invpermZ[level]] = 0; - zdd_print_minterm_aux(zdd, node, level + 1, list); - return; + if (level != cuddIZ(zdd,node->index)) { + list[zdd->invpermZ[level]] = 0; + zdd_print_minterm_aux(zdd, node, level + 1, list); + return; } - /* Terminal case: Print one cube based on the current recursion - ** path. - */ - for (i = 0; i < zdd->sizeZ; i++) { - v = list[i]; - if (v == 0) - (void) fprintf(zdd->out,"0"); - else if (v == 1) - (void) fprintf(zdd->out,"1"); - else if (v == 3) - (void) fprintf(zdd->out,"@"); /* should never happen */ - else - (void) fprintf(zdd->out,"-"); + + Nnv = cuddE(node); + Nv = cuddT(node); + if (Nv == Nnv) { + list[node->index] = 2; + zdd_print_minterm_aux(zdd, Nnv, level + 1, list); + return; } - (void) fprintf(zdd->out," 1\n"); - } - } else { - /* Check for missing variable. */ - if (level != cuddIZ(zdd,node->index)) { - list[zdd->invpermZ[level]] = 0; - zdd_print_minterm_aux(zdd, node, level + 1, list); - return; - } - Nnv = cuddE(node); - Nv = cuddT(node); - if (Nv == Nnv) { - list[node->index] = 2; + list[node->index] = 1; + zdd_print_minterm_aux(zdd, Nv, level + 1, list); + list[node->index] = 0; zdd_print_minterm_aux(zdd, Nnv, level + 1, list); - return; - } - - list[node->index] = 1; - zdd_print_minterm_aux(zdd, Nv, level + 1, list); - list[node->index] = 0; - zdd_print_minterm_aux(zdd, Nnv, level + 1, list); } return; @@ -970,57 +1013,59 @@ zddPrintCoverAux( int level /* depth in the recursion */, int * list /* current recursion path */) { - DdNode *Nv, *Nnv; - int i, v; - DdNode *base = DD_ONE(zdd); + DdNode *Nv, *Nnv; + int i, v; + DdNode *base = DD_ONE(zdd); if (Cudd_IsConstant(node)) { - if (node == base) { + if (node == base) { + /* Check for missing variable. */ + if (level != zdd->sizeZ) { + list[zdd->invpermZ[level]] = 0; + zddPrintCoverAux(zdd, node, level + 1, list); + return; + } + /* Terminal case: Print one cube based on the current recursion + ** path. + */ + for (i = 0; i < zdd->sizeZ; i += 2) { + v = list[i] * 4 + list[i+1]; + if (v == 0) + (void) putc('-',zdd->out); + else if (v == 4) + (void) putc('1',zdd->out); + else if (v == 1) + (void) putc('0',zdd->out); + else + (void) putc('@',zdd->out); /* should never happen */ + } + (void) fprintf(zdd->out," 1\n"); + } + } else { /* Check for missing variable. */ - if (level != zdd->sizeZ) { - list[zdd->invpermZ[level]] = 0; - zddPrintCoverAux(zdd, node, level + 1, list); - return; + if (level != cuddIZ(zdd,node->index)) { + list[zdd->invpermZ[level]] = 0; + zddPrintCoverAux(zdd, node, level + 1, list); + return; } - /* Terminal case: Print one cube based on the current recursion - ** path. - */ - for (i = 0; i < zdd->sizeZ; i += 2) { - v = list[i] * 4 + list[i+1]; - if (v == 0) - (void) putc('-',zdd->out); - else if (v == 4) - (void) putc('1',zdd->out); - else if (v == 1) - (void) putc('0',zdd->out); - else - (void) putc('@',zdd->out); /* should never happen */ + + Nnv = cuddE(node); + Nv = cuddT(node); + if (Nv == Nnv) { + list[node->index] = 2; + zddPrintCoverAux(zdd, Nnv, level + 1, list); + return; } - (void) fprintf(zdd->out," 1\n"); - } - } else { - /* Check for missing variable. */ - if (level != cuddIZ(zdd,node->index)) { - list[zdd->invpermZ[level]] = 0; - zddPrintCoverAux(zdd, node, level + 1, list); - return; - } - Nnv = cuddE(node); - Nv = cuddT(node); - if (Nv == Nnv) { - list[node->index] = 2; + list[node->index] = 1; + zddPrintCoverAux(zdd, Nv, level + 1, list); + list[node->index] = 0; zddPrintCoverAux(zdd, Nnv, level + 1, list); - return; - } - - list[node->index] = 1; - zddPrintCoverAux(zdd, Nv, level + 1, list); - list[node->index] = 0; - zddPrintCoverAux(zdd, Nnv, level + 1, list); } return; } /* end of zddPrintCoverAux */ + + ABC_NAMESPACE_IMPL_END diff --git a/src/bdd/cudd/r7x8.1.out b/src/bdd/cudd/r7x8.1.out new file mode 100644 index 00000000..0e7108ee --- /dev/null +++ b/src/bdd/cudd/r7x8.1.out @@ -0,0 +1,377 @@ +# TestCudd Version #1.0, Release date 3/17/01 +# ./testcudd -p 2 r7x8.1.mat +:name: r7x8.1.mat: 7 rows 9 columns +:1: M: 63 nodes 5 leaves 52 minterms +000000-- 1 +000001-0 1 +000001-1 4 +000010-0 4 +000010-1 3 +000011-0 2 +000011-1 4 +000100-- 3 +000101-0 3 +000110-0 1 +000110-1 2 +000111-0 4 +001000-- 1 +001001-0 4 +001010-0 2 +001010-1 1 +001011-1 4 +001100-0 2 +001100-1 3 +001101-0 3 +001110-0 4 +001110-1 1 +0100-0-0 3 +011000-0 3 +011010-0 1 +100000-0 2 +100000-1 3 +100001-0 2 +100001-1 4 +100010-- 3 +100011-- 4 +100100-- 1 +100101-0 2 +100110-0 1 +100110-1 3 +100111-0 3 +101000-1 1 +101001-0 1 +101001-1 4 +101100-0 2 +101100-1 4 +101101-0 4 +110000-0 2 +110010-0 4 +111000-0 2 + +:2: time to read the matrix = 0.00 sec +:3: C: 22 nodes 1 leaves 52 minterms +0000---- 1 +0001-0-- 1 +0001-1-0 1 +001000-- 1 +001001-0 1 +001010-- 1 +001011-1 1 +001100-- 1 +001101-0 1 +001110-- 1 +01-0-0-0 1 +1000---- 1 +1001-0-- 1 +1001-1-0 1 +101000-1 1 +101001-- 1 +101100-- 1 +101101-0 1 +1100-0-0 1 +111000-0 1 + +Testing iterator on cubes: +000000-- 1 +000001-0 1 +000001-1 4 +000010-0 4 +000010-1 3 +000011-0 2 +000011-1 4 +000100-- 3 +000101-0 3 +000110-0 1 +000110-1 2 +000111-0 4 +001000-- 1 +001001-0 4 +001010-0 2 +001010-1 1 +001011-1 4 +001100-0 2 +001100-1 3 +001101-0 3 +001110-0 4 +001110-1 1 +0100-0-0 3 +011000-0 3 +011010-0 1 +100000-0 2 +100000-1 3 +100001-0 2 +100001-1 4 +100010-- 3 +100011-- 4 +100100-- 1 +100101-0 2 +100110-0 1 +100110-1 3 +100111-0 3 +101000-1 1 +101001-0 1 +101001-1 4 +101100-0 2 +101100-1 4 +101101-0 4 +110000-0 2 +110010-0 4 +111000-0 2 + +Testing prime expansion of cubes: +-000---- 1 +-00--0-- 1 +0--0-0-0 1 +--00-0-0 1 +-0-100-- 1 +10-001-- 1 +-00----0 1 +00---0-- 1 +-1-000-0 1 +-0--01-0 1 +-0--00-1 1 +00-01--1 1 + +Testing iterator on primes (CNF): +-0-0---- 1 +-0---0-- 1 +0-0-0--- 1 +-0-----0 1 +---0-0-0 1 +0101-1-1 1 +--0-00-1 1 +1-0-10-0 1 + +Cache used slots = 58.06% (expected 58.92%) +xor1: 14 nodes 1 leaves 28 minterms +000--1-1 1 +001-11-1 1 +01---0-0 1 +100--1-1 1 +101-00-0 1 +101-01-1 1 +110--0-0 1 +111-00-0 1 + +Chosen minterm for Hamming distance test: : 9 nodes 1 leaves 1 minterms +11110010 1 + +Minimum Hamming distance = 1 +ycube: 5 nodes 1 leaves 8 minterms +-0-0-0-0 1 + +CP: 11 nodes 1 leaves 7 minterms +00-0-0-0 1 +1000-0-0 1 +101000-1 1 + +:4: ineq: 10 nodes 1 leaves 42 minterms +001000-- 1 +00101--- 1 +1000---- 1 +100100-- 1 +10011--- 1 +101----- 1 +111000-- 1 +11101--- 1 + +10------ 1 +-01----- 1 +1-1----- 1 +-0-0---- 1 +1--0---- 1 +-0--10-- 1 +--1010-- 1 +1---10-- 1 + +:4: ess: 1 nodes 1 leaves 128 minterms +-------- 1 + +:5: shortP: 7 nodes 1 leaves 2 minterms +000000-- 1 + +:5b: largest: 4 nodes 1 leaves 16 minterms +01-1---- 1 + +The value of M along the chosen shortest path is 1 +:6: shortP: 5 nodes 1 leaves 8 minterms +0000---- 1 + +Average distance: 4133.34 +Number of variables = 8 Number of slots = 2304 +Number of keys = 995 Number of min dead = 9216 +walsh1: 16 nodes 2 leaves 256 minterms +-0--0--0--0- 1 +-0--0--0--10 1 +-0--0--0--11 -1 +-0--0--10-0- 1 +-0--0--10-10 1 +-0--0--10-11 -1 +-0--0--11-0- -1 +-0--0--11-10 -1 +-0--0--11-11 1 +-0--10-0--0- 1 +-0--10-0--10 1 +-0--10-0--11 -1 +-0--10-10-0- 1 +-0--10-10-10 1 +-0--10-10-11 -1 +-0--10-11-0- -1 +-0--10-11-10 -1 +-0--10-11-11 1 +-0--11-0--0- -1 +-0--11-0--10 -1 +-0--11-0--11 1 +-0--11-10-0- -1 +-0--11-10-10 -1 +-0--11-10-11 1 +-0--11-11-0- 1 +-0--11-11-10 1 +-0--11-11-11 -1 +-10-0--0--0- 1 +-10-0--0--10 1 +-10-0--0--11 -1 +-10-0--10-0- 1 +-10-0--10-10 1 +-10-0--10-11 -1 +-10-0--11-0- -1 +-10-0--11-10 -1 +-10-0--11-11 1 +-10-10-0--0- 1 +-10-10-0--10 1 +-10-10-0--11 -1 +-10-10-10-0- 1 +-10-10-10-10 1 +-10-10-10-11 -1 +-10-10-11-0- -1 +-10-10-11-10 -1 +-10-10-11-11 1 +-10-11-0--0- -1 +-10-11-0--10 -1 +-10-11-0--11 1 +-10-11-10-0- -1 +-10-11-10-10 -1 +-10-11-10-11 1 +-10-11-11-0- 1 +-10-11-11-10 1 +-10-11-11-11 -1 +-11-0--0--0- -1 +-11-0--0--10 -1 +-11-0--0--11 1 +-11-0--10-0- -1 +-11-0--10-10 -1 +-11-0--10-11 1 +-11-0--11-0- 1 +-11-0--11-10 1 +-11-0--11-11 -1 +-11-10-0--0- -1 +-11-10-0--10 -1 +-11-10-0--11 1 +-11-10-10-0- -1 +-11-10-10-10 -1 +-11-10-10-11 1 +-11-10-11-0- 1 +-11-10-11-10 1 +-11-10-11-11 -1 +-11-11-0--0- 1 +-11-11-0--10 1 +-11-11-0--11 -1 +-11-11-10-0- 1 +-11-11-10-10 1 +-11-11-10-11 -1 +-11-11-11-0- -1 +-11-11-11-10 -1 +-11-11-11-11 1 + +wtw: 14 nodes 2 leaves 16 minterms +0-00-00-00-0 16 +0-00-00-01-1 16 +0-00-01-10-0 16 +0-00-01-11-1 16 +0-01-10-00-0 16 +0-01-10-01-1 16 +0-01-11-10-0 16 +0-01-11-11-1 16 +1-10-00-00-0 16 +1-10-00-01-1 16 +1-10-01-10-0 16 +1-10-01-11-1 16 +1-11-10-00-0 16 +1-11-10-01-1 16 +1-11-11-10-0 16 +1-11-11-11-1 16 + +Average length of non-empty lists = 1 +**** CUDD modifiable parameters **** +Hard limit for cache size: 7645866 +Cache hit threshold for resizing: 30% +Garbage collection enabled: yes +Limit for fast unique table growth: 4587520 +Maximum number of variables sifted per reordering: 1000 +Maximum number of variable swaps per reordering: 2000000 +Maximum growth while sifting a variable: 1.2 +Dynamic reordering of BDDs enabled: no +Default BDD reordering method: 4 +Dynamic reordering of ZDDs enabled: no +Default ZDD reordering method: 4 +Realignment of ZDDs to BDDs enabled: no +Realignment of BDDs to ZDDs enabled: no +Dead nodes counted in triggering reordering: no +Group checking criterion: 7 +Recombination threshold: 0 +Symmetry violation threshold: 0 +Arc violation threshold: 0 +GA population size: 0 +Number of crossovers for GA: 0 +Next reordering threshold: 4004 +**** CUDD non-modifiable parameters **** +Memory in use: 4274484 +Peak number of nodes: 2044 +Peak number of live nodes: 119 +Number of BDD variables: 9 +Number of ZDD variables: 0 +Number of cache entries: 2048 +Number of cache look-ups: 2846 +Number of cache hits: 715 +Number of cache insertions: 2289 +Number of cache collisions: 937 +Number of cache deletions: 1348 +Cache used slots = 66.02% (expected 67.30%) +Soft limit for cache size: 13312 +Number of buckets in unique table: 2560 +Used buckets in unique table: 0.51% (expected 0.51%) +Number of BDD and ADD nodes: 13 +Number of ZDD nodes: 0 +Number of dead BDD and ADD nodes: 0 +Number of dead ZDD nodes: 0 +Total number of nodes allocated: 1091 +Total number of nodes reclaimed: 950 +Garbage collections so far: 1 +Time for garbage collection: 0.00 sec +Reorderings so far: 0 +Time for reordering: 0.00 sec +total time = 0.00 sec +Runtime Statistics +------------------ +Machine name: jobim.colorado.edu +User time 0.0 seconds +System time 0.0 seconds + +Average resident text size = 0K +Average resident data+stack size = 0K +Maximum resident size = 0K + +Virtual text size = 131644K +Virtual data size = 151K + data size initialized = 17K + data size uninitialized = 0K + data size sbrk = 134K +Virtual memory limit = 358400K (4194304K) + +Major page faults = 0 +Minor page faults = 1318 +Swaps = 0 +Input blocks = 0 +Output blocks = 0 +Context switch (voluntary) = 1 +Context switch (involuntary) = 1 diff --git a/src/bdd/cudd/testcudd.c b/src/bdd/cudd/testcudd.c index 1b6de5aa..f21f7816 100644 --- a/src/bdd/cudd/testcudd.c +++ b/src/bdd/cudd/testcudd.c @@ -16,19 +16,43 @@ Author [Fabio Somenzi] - Copyright [ This file was created at the University of Colorado at - Boulder. The University of Colorado at Boulder makes no warranty - about the suitability of this software for any purpose. It is - presented on an AS IS basis.] + 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.] ******************************************************************************/ -#include "util_hack.h" +#include "util.h" #include "cuddInt.h" -ABC_NAMESPACE_IMPL_START - - /*---------------------------------------------------------------------------*/ /* Constant declarations */ @@ -41,10 +65,10 @@ ABC_NAMESPACE_IMPL_START /*---------------------------------------------------------------------------*/ #ifndef lint -static char rcsid[] DD_UNUSED = "$Id: testcudd.c,v 1.1.1.1 2003/02/24 22:23:54 wjiang Exp $"; +static char rcsid[] DD_UNUSED = "$Id: testcudd.c,v 1.20 2009/03/08 02:49:02 fabio Exp $"; #endif -static char *onames[] = { "C", "M" }; /* names of functions to be dumped */ +static const char *onames[] = { "C", "M" }; /* names of functions to be dumped */ /**AutomaticStart*************************************************************/ @@ -52,12 +76,12 @@ static char *onames[] = { "C", "M" }; /* names of functions to be dumped */ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ -static void usage ARGS((char * prog)); -static FILE *open_file ARGS((char *filename, char *mode)); -static int testIterators ARGS((DdManager *dd, DdNode *M, DdNode *C, int pr)); -static int testXor ARGS((DdManager *dd, DdNode *f, int pr, int nvars)); -static int testHamming ARGS((DdManager *dd, DdNode *f, int pr, int nvars)); -static int testWalsh ARGS((DdManager *dd, int N, int cmu, int approach, int pr)); +static void usage (char * prog); +static FILE *open_file (char *filename, const char *mode); +static int testIterators (DdManager *dd, DdNode *M, DdNode *C, int pr); +static int testXor (DdManager *dd, DdNode *f, int pr, int nvars); +static int testHamming (DdManager *dd, DdNode *f, int pr); +static int testWalsh (DdManager *dd, int N, int cmu, int approach, int pr); /**AutomaticEnd***************************************************************/ @@ -77,17 +101,17 @@ int main(int argc, char **argv) { FILE *fp; /* pointer to input file */ - char *file = ""; /* input file name */ + char *file = (char *) ""; /* input file name */ FILE *dfp = NULL; /* pointer to dump file */ char *dfile; /* file for DD dump */ DdNode *dfunc[2]; /* addresses of the functions to be dumped */ DdManager *dd; /* pointer to DD manager */ - DdNode *one, *zero; /* fast access to constant functions */ + DdNode *one; /* fast access to constant function */ DdNode *M; DdNode **x; /* pointers to variables */ DdNode **y; /* pointers to variables */ - DdNode **xn; /* complements of row variables */ - DdNode **yn_; /* complements of column variables */ + DdNode **xn; /* complements of row variables */ + DdNode **yn_; /* complements of column variables */ DdNode **xvars; DdNode **yvars; DdNode *C; /* result of converting from ADD to BDD */ @@ -149,7 +173,7 @@ main(int argc, char **argv) blifOrDot = 0; /* dot format */ /* Parse command line. */ - while ((c = util_getopt(argc, argv, "CDHMPS:a:bcd:g:hkmn:p:v:x:X:")) + while ((c = util_getopt(argc, argv, (char *) "CDHMPS:a:bcd:g:hkmn:p:v:x:X:")) != EOF) { switch(c) { case 'C': @@ -216,7 +240,7 @@ main(int argc, char **argv) } if (argc - util_optind == 0) { - file = "-"; + file = (char *) "-"; } else if (argc - util_optind == 1) { file = argv[util_optind]; } else { @@ -241,7 +265,6 @@ main(int argc, char **argv) /* Initialize manager and provide easy reference to terminals. */ dd = Cudd_Init(nvars,0,nslots,cacheSize,maxMemory); one = DD_ONE(dd); - zero = DD_ZERO(dd); dd->groupcheck = (Cudd_AggregationType) groupcheck; if (autodyn) Cudd_AutodynEnable(dd,CUDD_REORDER_SAME); @@ -335,7 +358,7 @@ main(int argc, char **argv) if (retval == 0) exit(2); /* Test Hamming distance functions. */ - retval = testHamming(dd,C,pr,nx+ny); + retval = testHamming(dd,C,pr); if (retval == 0) exit(2); /* Test selection functions. */ @@ -356,6 +379,43 @@ main(int argc, char **argv) } Cudd_RecursiveDeref(dd, CPr); } + + /* Test inequality generator. */ + { + int Nmin = ddMin(nx,ny); + int q; + DdGen *gen; + int *cube; + DdNode *f = Cudd_Inequality(dd,Nmin,2,xvars,yvars); + if (f == NULL) exit(2); + Cudd_Ref(f); + if (pr>0) { + (void) printf(":4: ineq"); + Cudd_PrintDebug(dd,f,nx+ny,pr); + if (pr>1) { + Cudd_ForeachPrime(dd,Cudd_Not(f),Cudd_Not(f),gen,cube) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("1"); + break; + case 1: + (void) printf("0"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" 1\n"); + } + (void) printf("\n"); + } + } + Cudd_IterDerefBdd(dd, f); + } FREE(xvars); FREE(yvars); Cudd_RecursiveDeref(dd, CP); @@ -419,7 +479,7 @@ main(int argc, char **argv) } /* Reorder if so requested. */ - if (approach != CUDD_REORDER_NONE) { + if (approach != CUDD_REORDER_NONE) { #ifndef DD_STATS retval = Cudd_EnableReorderingReporting(dd); if (retval == 0) { @@ -502,9 +562,10 @@ main(int argc, char **argv) dfunc[1] = M; if (blifOrDot == 1) { /* Only dump C because blif cannot handle ADDs */ - retval = Cudd_DumpBlif(dd,1,dfunc,NULL,onames,NULL,dfp); + retval = Cudd_DumpBlif(dd,1,dfunc,NULL,(char **)onames, + NULL,dfp,0); } else { - retval = Cudd_DumpDot(dd,2,dfunc,NULL,onames,dfp); + retval = Cudd_DumpDot(dd,2,dfunc,NULL,(char **)onames,dfp); } if (retval != 1) { (void) fprintf(stderr,"abnormal termination\n"); @@ -524,9 +585,9 @@ main(int argc, char **argv) } if (pr>0) { (void) printf("Number of variables = %6d\t",dd->size); - (void) printf("Number of slots = %6d\n",dd->slots); - (void) printf("Number of keys = %6d\t",dd->keys); - (void) printf("Number of min dead = %6d\n",dd->minDead); + (void) printf("Number of slots = %6u\n",dd->slots); + (void) printf("Number of keys = %6u\t",dd->keys); + (void) printf("Number of min dead = %6u\n",dd->minDead); } } while (multiple && !feof(fp)); @@ -643,15 +704,15 @@ usage(char *prog) ******************************************************************************/ static FILE * -open_file(char *filename, char *mode) +open_file(char *filename, const char *mode) { FILE *fp; if (strcmp(filename, "-") == 0) { - return mode[0] == 'r' ? stdin : stdout; + return mode[0] == 'r' ? stdin : stdout; } else if ((fp = fopen(filename, mode)) == NULL) { - perror(filename); - exit(1); + perror(filename); + exit(1); } return fp; @@ -798,34 +859,56 @@ testIterators( if (!Cudd_bddPrintCover(dd,C,C)) return(0); } + if (pr>1) { + (void) printf("Testing iterator on primes (CNF):\n"); + Cudd_ForeachPrime(dd,Cudd_Not(C),Cudd_Not(C),gen,cube) { + for (q = 0; q < dd->size; q++) { + switch (cube[q]) { + case 0: + (void) printf("1"); + break; + case 1: + (void) printf("0"); + break; + case 2: + (void) printf("-"); + break; + default: + (void) printf("?"); + } + } + (void) printf(" 1\n"); + } + (void) printf("\n"); + } + /* Test iterator on nodes. */ if (pr>2) { - DdGen *gen; DdNode *node; (void) printf("Testing iterator on nodes:\n"); Cudd_ForeachNode(dd,M,gen,node) { if (Cudd_IsConstant(node)) { #if SIZEOF_VOID_P == 8 (void) printf("ID = 0x%lx\tvalue = %-9g\n", - (unsigned long) node / - (unsigned long) sizeof(DdNode), + (ptruint) node / + (ptruint) sizeof(DdNode), Cudd_V(node)); #else (void) printf("ID = 0x%x\tvalue = %-9g\n", - (unsigned int) node / - (unsigned int) sizeof(DdNode), + (ptruint) node / + (ptruint) sizeof(DdNode), Cudd_V(node)); #endif } else { #if SIZEOF_VOID_P == 8 - (void) printf("ID = 0x%lx\tindex = %d\tr = %d\n", - (unsigned long) node / - (unsigned long) sizeof(DdNode), + (void) printf("ID = 0x%lx\tindex = %u\tr = %u\n", + (ptruint) node / + (ptruint) sizeof(DdNode), node->index, node->ref); #else - (void) printf("ID = 0x%x\tindex = %d\tr = %d\n", - (unsigned int) node / - (unsigned int) sizeof(DdNode), + (void) printf("ID = 0x%x\tindex = %u\tr = %u\n", + (ptruint) node / + (ptruint) sizeof(DdNode), node->index, node->ref); #endif } @@ -932,8 +1015,7 @@ static int testHamming( DdManager *dd, DdNode *f, - int pr, - int nvars) + int pr) { DdNode **vars, *minBdd, *zero, *scan; int i; @@ -989,5 +1071,3 @@ testHamming( return(1); } /* end of testHamming */ -ABC_NAMESPACE_IMPL_END - |